一、ARP数据包的基本格式
Ethernet头部 |
ARP数据部分 | |||||||||
6 |
6 |
2 |
2 |
2 |
2 |
2 |
4 |
6 |
4 |
6 |
目标MAC地址 |
源地MAC地址 |
类型号0x0800:ip 0x0806:ARP |
局域网类型 以太网0x0001 |
网络协议类型 IP网络0x0800 |
MAC/IP地址长度,恒为0x06/04 |
01
|
ARP目标IP地址 |
ARP目标MAC 地址 |
ARP源IP地址 |
ARP源MAC地址 |
二、ARP数据包的信息
请求格式,回应格式。
包含物理地址和IP地址。
三、发送一个ARP请求
1.下载winpcap安装
2.下载jpcap 把jpcap.dll放到java的bin文件夹下
3.新建一个项目导入jpcap.jar
然后构建一个ARP数据请求包。
package com.stx.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.NetworkInterfaceAddress;
import jpcap.packet.ARPPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
import jpcap.packet.TCPPacket;
import jpcap.packet.UDPPacket;
/*
* 1.发送一个arp请求包
* 2.得到arp回应包解析出目的主机的mac地址
* */
public class Mac {
private NetworkInterface devices[]; // 网络设备
private NetworkInterface device; // 网络设备对象
private JpcapCaptor jpcapCaptor; // 设备的链接
private JpcapSender jpcapSender; // 包的发送实例
private ARPPacket arpPacket; // arp包的构建
private byte[] hostMAC, goalMAC; // 源主机、目标主机的MAC
private byte hostIP[], goalIP[]; // 源主机、目标主机的IP
private List<String> IP; // 存放请求的IP用于后面的检查
private int request; // 发送请求的个数
private int get; // 得到请求的个数
// 实例化
public Mac() {
devices = JpcapCaptor.getDeviceList();
IP = new ArrayList<String>();
}
// 的到一个网卡的实例
public NetworkInterface getDervice(int index) {
return devices[index];
}
// 整个系统的实例化
public void init() {
// 看具体的情况由于本地使用的是无线连接时第三个
int choice = choiceDevice();
device = getDervice(choice);
//
try {
// 构建一个设别的连接(具体的实例,获取的字符串长度,是否开启混杂模式,超时连接)
jpcapCaptor = JpcapCaptor.openDevice(device, 65535, false, 1000);
// jpcapCaptor.setFilter("ip", true);
// 构建一个发送的实例
jpcapSender = jpcapCaptor.getJpcapSenderInstance();
} catch (IOException e) {
System.out.println("=====初始化失败了,设别连接实例失败=======");
e.printStackTrace();
}
}
// 摧毁设别连接的实例
public void destory() {
if (jpcapCaptor != null)
jpcapCaptor.close();
else
System.out.println("=======设备连接已经关闭了========");
}
// 创建一个请求包并发送
public void creatRequestArp(String hostIP, String goalIP) {
/*
* 本地连接有源ip,目标ip 源MAC,目标MAC=0xff ff ff ff ff ff
*/
this.hostIP = getByte(hostIP); // 源ip
hostMAC = device.mac_address; // 源头MAC
this.goalIP = getByte(goalIP); // 目标IP
goalMAC = new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255,
(byte) 255, (byte) 255 };
// 构建一个数据包
arpPacket = new ARPPacket();
arpPacket.hardtype = ARPPacket.HARDTYPE_ETHER; // 网络类型
arpPacket.prototype = ARPPacket.PROTOTYPE_IP; // 网络协议IP
arpPacket.operation = ARPPacket.ARP_REQUEST; // ARP请求
arpPacket.hlen = 6; // 硬件长度
arpPacket.plen = 4; // IP长度
arpPacket.target_hardaddr = goalMAC; // 目标MAC
arpPacket.target_protoaddr = this.goalIP; // 目标IP
arpPacket.sender_hardaddr = hostMAC; // 源MAC
arpPacket.sender_protoaddr = this.hostIP; // 源IP
// 声明一个以太网的包头
EthernetPacket ethToTarget = new EthernetPacket();
ethToTarget.frametype = EthernetPacket.ETHERTYPE_ARP;// 类型号
ethToTarget.src_mac = hostMAC;
ethToTarget.dst_mac = goalMAC;
// 数据包添加以太网的包头
arpPacket.datalink = ethToTarget;
// 发送这个arp请求数据包
jpcapSender.sendPacket(arpPacket);
System.out.println(arpPacket);
// 添加一些统计信息
IP.add(goalIP);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 把字符串的IP地址转换为了 byte数组行的
public byte[] getByte(String IP) {
byte[] byteIP = new byte[4];
int i = 0;
for (String s : IP.split("\\.")) {
byteIP[i++] = (byte) (Integer.parseInt(s));
}
// System.out.println(IP);
// for(int j=0;j<4;j++){
//
// System.out.print((int)(byteIP[j]& 0xff)+" ");
// }
return byteIP;
}
public int choiceDevice() {
for (int i = 0; i < devices.length; i++) {
System.out.println("--------------" + i
+ "------------------------------");
System.out.println("网卡名称:" + devices[i].name);
for (NetworkInterfaceAddress a : devices[i].addresses) {
System.out.println("IP地址:" + a.address);
}
System.out
.println("------------------------------------------------");
}
System.out.print("请输入你的选择【从0开始】:");
try {
return System.in.read() - 48;
} catch (IOException e) {
e.printStackTrace();
return 0;
}
}
// 接收数据包
public void getArp() {
Packet ipPacket = null;
do {
ipPacket = jpcapCaptor.getPacket();
if (ipPacket instanceof ARPPacket) {
// System.out.println(ipPacket.src_ip.getHostAddress());
ARPPacket a = (ARPPacket) ipPacket;
if (a.operation == 2) {
System.out.println(a.operation == 1 ? "请求" : "回答");
System.out.println(a.getSenderProtocolAddress() + " "
+ a.getSenderHardwareAddress());
System.out.println(a.getTargetProtocolAddress() + " "
+ a.getTargetHardwareAddress());
System.out.println("ARP " + ipPacket);
}
}
// else if(ipPacket instanceof UDPPacket){
// System.out.println("UDP "+ipPacket);
// }
} while (true);
}
// 打印出测试IP地址
public void showGoalIP() {
for (int i = 0; i < IP.size(); i++) {
System.out.println(IP.get(i));
}
}
}