ARP数据包格式

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


ARP包类型
replay

01


REPLY
0x0002


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

}

猜你喜欢

转载自xiaozhou09.iteye.com/blog/1839733