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 |
---|