뭐... 요넘도 마찮가지로 byte array에서 ip4 header만 추출하는 넘임..

Ip4Header.java
- source ip, destination ip, protocol 을 추출

import org.jnetpcap.packet.format.FormatUtils;


public class Ip4Header {


public final static int TCP = 6;

public final static int UDP = 17;

String version;

int     headerLength;

String srcIP;

String dstIP;

int protocol;


public String getVersion() {

return version;

}

public int getHeaderLength() {

return headerLength;

}

public String getSrcIP() {

return srcIP;

}

public String getDstIP() {

return dstIP;

}

public int getProtocol() {

return protocol;

}


public boolean makeHeader(byte[] buf) {

try {

byte[] bTmp = new byte[1];

System.arraycopy(buf, 14, bTmp, 0, bTmp.length);

if(!"4".equals(StringUtil.ascii2hexstr(bTmp).substring(0, 1))) return false;

this.version = StringUtil.ascii2hexstr(bTmp).substring(0, 1);

this.headerLength = Integer.parseInt(StringUtil.ascii2hexstr(bTmp).substring(1, 2)) * 4;

byte[] protocol = new byte[1];

byte[] dstIP = new byte[4];

byte[] srcIP = new byte[4];

System.arraycopy(buf, 23, protocol, 0, protocol.length);

System.arraycopy(buf, 26, srcIP, 0, srcIP.length);

System.arraycopy(buf, 30, dstIP, 0, dstIP.length);

this.protocol = protocol[0];

this.srcIP = FormatUtils.ip(srcIP);

this.dstIP = FormatUtils.ip(dstIP);

return true;

} catch(Exception e) {

e.printStackTrace();

return false;

}

}

}



캡쳐된 패킷 버퍼를 byte[] 로 전환해서 위 클래스에 할당하면 알아서 추출해준다.
byte[] dst = new byte[buffer.capacity()];
buffer.get(dst); 

 
Posted by 짱가쟁이

pcap lib 로 수집된 패킷을 mac address로 필터링을 하려고 하는데.. 이넘의 거지 같은 pcap lib가 thread에 안전하지 않더란 말이쥐.. 더럽게도 다중 쓰레드에서는 각 클래스에 스캔을 뜨는 이 편한 방법을 못쓰고 직접 바이트를 파싱해야 한다능..

그래서 필요한 넘만 직접 파싱해서 하나 만들었다.

EthernetHeader.java
- 패킷을 byte[]로 받아서 source mac, destination mac, type을 추출한다.

public class EthernetHeader {

public final static String IP = "0800";

byte[] srcMac = new byte[6];

byte[] dstMac = new byte[6];

byte[] type = new byte[2];

public byte[] getDstMac() {

return dstMac;

}


public byte[] getSrcMac() {

return srcMac;

}


public byte[] getType() {

return type;

}


public boolean makeHeader(byte[] buf) {

try {

System.arraycopy(buf, 0, dstMac, 0, dstMac.length);

System.arraycopy(buf, 6, srcMac, 0, srcMac.length);

System.arraycopy(buf, 12, type, 0, type.length);

return true;

} catch(Exception e) {

return false;

}

}

public boolean isIp() {

return IP.equals(StringUtil.ascii2hexstr(type));

}

}


 위 코드의 type이라는 넘은 하위 프로토콜의 타입을 의미하며 내는 IP 프로토콜만 사용했기 때문에 위처럼 고정해서 사용했음.

 

ByteBufferHandler 사용해서 패킷 캡쳐하는 부분
 

@Override

public void nextPacket(PcapHeader header, ByteBuffer buffer, Object arg2) {

try {

PcapDumper dumper = (PcapDumper) arg2;

    byte[] dst = new byte[buffer.capacity()];

    buffer.get(dst);

    EthernetHeader ethernetHeader = new EthernetHeader();

    if(!ethernetHeader.makeHeader(dst)) return;

    if(ethernetHeader.isIp()) { // IP 프로토콜

// packet 내의 시간 값 읽어 온다.

String timestampString = JNetPcapUtil.makeTimestampString("yyyyMMddHHmmssSSS", new Date(header.timestampInMillis()));
................
.......... 

 
뭐.. jNetpcap을 사용하면 편하게 패킷을 캡쳐할 수 있고, 필터링 할 수 있지만.. 다중 쓰레드에 안전하지 않다는 것임.
뭐 추후 버전은 concurrency에 안전하게 나올지 모르지만 현재 버전에서는 어쩔 수 없이 편한 방법을 사용하지 못하고 이렇듯 무식하게 직접 파싱을 해줘야 한다. 쩌ㅃ~





 

'framework > jNetPcap' 카테고리의 다른 글

[jnetpcap] - byte[] 에서 ip4 header 추출하기  (2) 2012.02.13
Posted by 짱가쟁이
이전버튼 1 이전버튼