C语言无法读取ARP数据包,捕获代码无有效输出如何解决
问题根因分析
- 错误1:套接字类型不匹配
你使用SOCK_DGRAM类型的PF_PACKET套接字时,内核会自动剥离以太网帧头,返回的缓冲区直接是ARP协议载荷,此时你将接收缓冲区强转为struct ether_header类型,解析到的完全是错误数据。如果需要获取以太网帧头,需要将套接字类型改为SOCK_RAW。 - 错误2:MAC地址打印格式错误
struct ether_header中的ether_shost是存储二进制MAC地址的6字节uint8数组,不是以\0结尾的C字符串,直接用%s格式化打印无法输出正确内容,需要逐个字节转成十六进制格式输出。 - 额外注意:此类原始套接字程序需要root权限运行,否则会创建套接字失败。
修正后代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <net/ethernet.h> #include <net/if_arp.h> int main(){ int sock; unsigned char recvbuf[2048]; // 改为SOCK_RAW获取完整以太网帧 if((sock=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP)))==-1){ perror("socket error"); return -1; } for(;;){ if(recvfrom(sock,recvbuf,sizeof(recvbuf),0,NULL,NULL)==-1){ perror("recvfrom error"); } struct ether_header *e = (struct ether_header *)recvbuf; // 格式化打印MAC地址 printf("arp from :%02x:%02x:%02x:%02x:%02x:%02x\n", e->ether_shost[0], e->ether_shost[1], e->ether_shost[2], e->ether_shost[3], e->ether_shost[4], e->ether_shost[5]); } }
运行验证
使用sudo执行编译后的二进制文件,同一局域网内触发ARP请求(比如ping一个同网段未使用的IP),即可看到正确的源MAC地址输出。
内容的提问来源于stack exchange,提问作者mojo
相关产品推荐
相关产品推荐

