使用Jcap捕获数据包

xiaoxiao2021-02-28  8

 使用JPcap可以发包,使用JnetPcap可以接收和过滤包。现在项目中遇到的问题总结如下。

1.  环境搭建

如果是在Window下则必须在path路径下存在JnetPcap.dll和Jpcap.dll文件,如果是在linux环境下,可以将JnetPcap.so和JnetPcap.so存放到/usr/lib目录下即可,但是最好的解决方案是讲将两个so文件存放到项目目录下,然后使用

System.load(System.getProperty(“user.dir”)+/so文件相对路径)。

2.  无法打开网卡,或者是存在主备网卡的问题(bond网卡)

解决方案:直接使用网卡名称打开网卡   

Pcap pcap=Pcap.openLive("eth0",64*1024,Pcap.MODE_NON_PROMISCUOUS,new StringBuilder()); //Pcap pcap=Pcap.openLive(网卡名称,包大小,网卡模式,错误信息);                     

说明:网卡名称一般为eth0等

           包大小一般为64*1024

           网卡模式一般为Pcap.MODE_NON_PROMISCUOUS混合模式

           错误信息其中存放的是当网卡打开失败后返回的系统信息,一般为StringBuilder

3.  如何循环捕包

通过上面得到的Pcap网卡对象就可以循环捕包了,大致程序逻辑如下:

      由于会一台机器上可能会有多个网卡,所以抓包前应先进行网卡的绑定

Pcap pcap=Pcap.openLive("eth0",64*1024,Pcap.MODE_NON_PROMISCUOUS,new StringBuilder()); PcapBpfProgram filter = new PcapBpfProgram(); String expression=” ”; int r=pcap.compile(filter , expression , 0, 0); if(r==Pcap.OK){ Pcap.setFilter(filter); } PcapPacketHandler<Object> handler=newPcapPacketHandler<Object>(){ @Override public void nextPcaket( PcapPacket oriPcaket,Object arg1){ //oriPcaket为在网卡上根据filter捕获的包                 //具体的业务逻辑在这里添加     } } pcap.loo(-1,handler,”可以随便起个名字”);//第一个参数指示接收的包数,如果为-1则表示一直接收,10则表示收取10个包后就不再收包了。

特别说明:

1.     表达式expression的重要性,因为同一时刻网卡有可能会收到大量的包,如果不加上过滤器那么程序的处理能力肯定是达不到的。

2.     过滤表达式示例:

String expression="ip and udp src port 12345 and dst port 54321 and eth src not 11:22:33:44:55:66";

该表达式过滤使用了IP和UDP协议,并且源端口为12345,目的端口为54321,并且源mac地址不为11:22:33:44:55:66,只有满足上述所有条件,才会被到。

4.  包结构

 

内容

长度

eth头

源mac,目的mac

14字节

ip头

源IP,目的IP

20字节

udp头

源端口,目的端口

8字节

负载

数据

不定

1. 得到mac

EtherNet ethe=newEtherNet(); PcapPcaket pcaket; if(pcaket.hasHeader(ethe)){ String srcMac= FormatUtils.mac(ethe.source());     String dstMac= FormatUtils.mac(ethe.destination()); }

 

2. 得到ip

 

Ip4 ip =new Ip4(); byte srcIp=new byte[4]; byte dstIp=new byte[4]; PcapPcaket pcaket; If(pcaket.hasHeader(ip)){ srcIp =ip.source(); dstIp=ip. Destination(); }

 

3. 得到端口

 

Udp udp=new Udp(); PcapPcaket pcaket; If(pcaket.hasHeader(usp)){ int srcPort=udp.source(); int dstPort=udp.destination(); }
转载请注明原文地址: https://www.6miu.com/read-2799970.html

最新回复(0)