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 짱가쟁이