一、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)); } } }