发送arp请求报文

本文详细探讨了ARP请求报文的结构,并提供了相关的代码示例,帮助读者理解如何构造并发送ARP请求,以实现网络层到数据链路层的地址解析过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 (1)报文格式

(2)代码如下:

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#include <string.h>
#include <net/if.h>

#define SRC_MAC  { 0x00,0x0C,0x29,0x6F,0x57,0xE7 }//源MAC地址
#define DEST_MAC { 0x00,0x0C,0x29,0xD3,0xD6,0xF7 }//目的MAC地址

struct arppacket
{
        unsigned char dest_mac[ETH_ALEN];//接收方MAC
        unsigned char src_mac[ETH_ALEN];//发送方MAC
        unsigned short type;         //0x0806是ARP帧的类型值
        unsigned short ar_hrd;//硬件类型 - 以太网类型值0x1
        unsigned short ar_pro;//上层协议类型 - IP协议(0x0800)
        unsigned char  ar_hln;//MAC地址长度
        unsigned char  ar_pln;//IP地址长度
        unsigned short ar_op;//操作码 - 0x1表示ARP请求包,0x2表示应答包
        unsigned char  ar_sha[ETH_ALEN];//发送方mac
        unsigned char ar_sip[4];//发送方ip
        unsigned char ar_tha[ETH_ALEN];//接收方mac
        unsigned char ar_tip[4];//接收方ip
} __attribute__ ((__packed__));
int main(int argc,char *argv[])
{
    int fd = 0;
    struct in_addr s,r;
    struct sockaddr_ll sl;

    struct arppacket arp={
                DEST_MAC,
                SRC_MAC,
                htons(0x0806),
                htons(0x01),
                htons(0x0800),
                ETH_ALEN,
                4,
                htons(0x01),
                SRC_MAC,
                {0},
                DEST_MAC,
                {0}
    };

    fd = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
    if(fd < 0)
    {
        printf("socket error\n");
        return -1;
    }
    memset(&sl, 0, sizeof(sl));

    inet_aton("192.168.11.220", &s);
    memcpy(&arp.ar_sip, &s, sizeof(s));

    inet_aton("192.168.11.192", &r);
    memcpy(&arp.ar_tip, &r, sizeof(r));


    sl.sll_family = AF_PACKET;
    sl.sll_ifindex = IFF_BROADCAST;
	
	while(1)
    {
        if(sendto(fd,&arp, sizeof(arp), 0, (struct sockaddr*)&sl, sizeof(sl)) <= 0)
        {
            printf("send error\n");
        }
        else
           printf("send success\n");

        sleep(1);
    }

    close(fd);

    return 0;
}
	

 

ArpSender是C#写的ARP发包器,写的初衷是想试下什么样的ARP包才会引起ARP攻击,构造一些包可能会导致别人上不了网。至于包怎么填,发挥大家的想象吧,嘿嘿。 ArpSender用了SharpPcap这个开源API,有兴趣的到网上查下,用起来挺简单的。编程过程中最大的问题就是线程的问题。发包的代码中用了BackgroundWorker控件,因为参数只能传一个,并且线程是不允许直接调用主窗口控件,后来用了一个结构体struct ArpPac来传,感觉还是很麻烦啊!不过还好在BackgroundWorker的RunWorkerCompleted可以直接操作主窗口控件了,能把结果显示到主窗口上。 在编写获取IP的MAC地址部分,一开始还是用BackgroundWorker,在获取存在的IP地址MAC时可以正常工作,可是当IP不存在是,DOWORK方法一直没结束。因为里面一个Resolve方法一直没返回,也没超时设定,线程就一直卡在那不动了。也不知道该怎么结束这个线程。于是改用了Thread,传参数用了个object数组,嘿嘿,所有参数都封起来。到了那边再解封,很好用。后来才发现,线程是没有返回值的。。又不能直接操作窗体控件。。没办法,只好设个全局变量来保存结果了。获取MAC部分还用了个Timer控件,1秒钟如果还没得到返回的MAC,直接结束该线程。。。 BackgroundWorker 用起来简单也很好用,如果有个abort方法的话。。。
### ARP请求报文的结构与工作原理 ARP(Address Resolution Protocol)是一种用于将IP地址解析为MAC地址的协议。以下是关于ARP请求报文的具体格式、字段解释及其工作方式的内容。 --- ### 1. ARP请求报文的结构 ARP请求报文遵循固定的格式,其主要组成部分包括以下几个字段[^2]: | 字段名称 | 长度(字节) | 描述 | |-----------------------|-------------|----------------------------------------------------------------------| | 硬件类型 (Hardware Type) | 2 | 表示底层网络硬件的类型,对于以太网来说,该值固定为 `1`。 | | 协议类型 (Protocol Type) | 2 | 表示上层协议的类型,IPv4 的值为 `0x0800`。 | | 硬件地址长度 (HLEN) | 1 | 硬件地址(MAC地址)的长度,单位为字节,对于以太网而言通常是 `6`。 | | 协议地址长度 (PLEN) | 1 | 协议地址(IP地址)的长度,单位为字节,对于 IPv4 来说是 `4`。 | | 操作码 (Operation Code) | 2 | 定义了此报文的操作类型,ARP 请求时为 `1`,ARP 应答时为 `2`。 | | 发送方硬件地址 (SHA) | HLEN | 发起 ARP 请求的设备的 MAC 地址。 | | 发送方协议地址 (SPA) | PLEN | 发起 ARP 请求的设备的 IP 地址。 | | 目标硬件地址 (THA) | HLEN | 目前未知的目标设备的 MAC 地址,默认填充为全零 (`00:00:00:00:00:00`)。 | | 目标协议地址 (TPA) | PLEN | 待查找的目标设备的 IP 地址。 | --- ### 2. ARP请求报文的工作原理 当一台设备需要向同一局域网中的另一台设备发送数据包时,如果它的ARP缓存中没有目标IP地址对应的MAC地址,则会发起ARP请求。以下是具体的流程[^1][^4]: #### (1)构建并广播ARP请求 - 设备 A 构建一个 ARP 请求报文,其中包含以下信息: - **操作码**:设置为 `1`,表示这是一个 ARP 请求。 - **发送方硬件地址 (SHA)** 和 **发送方协议地址 (SPA)**:分别是设备 A 自己的 MAC 地址和 IP 地址。 - **目标协议地址 (TPA)**:待查询的目标设备的 IP 地址。 - **目标硬件地址 (THA)**:初始为空(全零),因为尚未知道目标设备的 MAC 地址。 - 此 ARP 请求将以广播形式发送到整个局域网,所有连接在同一子网中的设备都能接收到这条消息。 #### (2)接收并响应ARP请求 - 当某个设备 B 收到这个广播消息后,它会检查 TPA 是否与其自身的 IP 地址相匹配。 - 如果匹配成功,设备 B 将生成一个 ARP 应答报文,并将其单播回设备 A。应答报文中包含了设备 B 的 MAC 地址作为 THA。 #### (3)更新ARP缓存 - 设备 A 接收到 ARP 应答后,会提取出目标设备的 MAC 地址,并将其与相应的 IP 地址一起存储在本地的 ARP 缓存表中。 - 这样,在未来的通信过程中,设备 A 不再需要重新发起 ARP 查询即可直接使用已知的 MAC 地址进行数据传输。 --- ### 示例代码:模拟ARP请求报文 下面是一个简单的 Python 脚本,演示如何构造一个基本的 ARP 请求报文: ```python from scapy.all import Ether, ARP, sendp def create_arp_request(src_mac, src_ip, dst_ip): ether = Ether(dst="ff:ff:ff:ff:ff:ff") # 广播地址 arp = ARP(op=1, hwsrc=src_mac, psrc=src_ip, pdst=dst_ip) packet = ether / arp return packet # 参数定义 source_mac = "aa:bb:cc:dd:ee:ff" source_ip = "192.168.1.100" target_ip = "192.168.1.2" packet = create_arp_request(source_mac, source_ip, target_ip) # 发送ARP请求 sendp(packet, iface="eth0") ``` --- ### 动态ARP表项的老化机制 为了避免ARP缓存占用过多资源或保留过期的信息,设备会对动态创建的ARP表项实施老化策略[^3]。主要包括以下几点: - **老化超时时间**:一旦某条动态ARP表项达到预设的时间阈值,系统就会尝试通过发送探测报文确认该映射关系是否仍然有效。 - **老化探测次数**:允许的最大重试次数,若连续多次未获得回应则认为目标不可达并将该项移除。 - **老化探测模式**:可以配置为主动或被动两种模式之一,前者定期主动检测,后者仅在必要时候触发。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值