TCP/IP协议分析--ARP包
来源:互联网 发布:亚马逊第三方软件 编辑:程序博客网 时间:2024/04/28 12:36
当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,必须要知道对方的物理地址。如果只知道目的主机的IP地址,就必须通过ARP协议来获取其物理地址。
当链路层数据类型被标记为ARP包时,那么链路层数据段的内容就是ARP包的内容。
首先定义ARP包结构体:
//eth.h #ifndef __ETH__ #define __ETH__ typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8;/*链路层结构*/typedef struct { u8 destMAC[6]; //目的MAC u8 sourMAC[6]; //源MAC u16 type; //类型 u8 data[1500]; //数据 }ETH_HEADER; /*链路层数据包类型*/typedef enum { ARP_PACKET=0x0806, //ARP包 RARP_PACKET=0x8035, //RARP包 IP_PACKET=0x0800 //IP包}PACKET_TYPE;/*ARP包结构*/typedef struct{ u16 hardware; //硬件地址类型,1表示MAC地址 u16 protocol; //协议地址类型,0x0800表示IP地址 u8 mac_len; //硬件地址的长度,对于MAC地址为6 u8 ip_len; //协议地址长度,对于IP地址来说有4和6,对应IPV4和IPV6 u16 op; //操作类型,1表示ARP请求,2表示ARP应答 u8 sourMAC[6]; //发送者MAC地址 u8 sourIP[4]; //发送者IP地址 u8 destMAC[6]; //目的MAC地址,对于请求来说,这里是全0 u8 destIP[4]; //目的IP地址}ARP_STRUCT;/*ARP操作类型*/typedef enum { ARP_REQUEST=1, ARP_REPLY=2, RARP_REQUEST=3, RARP_REPLY=4}ARP_OP; #endif硬件地址类型(hardware)和协议地址类型(protocol):需要转换的两种协议,一般硬件地址类型是1,协议类型是0x0800,表示MAC和IP地址进行转换。
硬件地址长度(mac_len):对于 MAC地址,长度为6
协议地址长度(ip_len):对于 IP地址,长度为4和6,分别对应IPV4和IPV6.
操作类型(op):1表示ARP请求,2表示ARP应答。还有RARP请求3,RARP应答4.
源MAC地址(sourMAC):发送者硬件地址
源IP地址(sourIP):发送者IP地址
目的MAC地址(destMAC):目的MAC地址,对于ARP请求,该字段全0(因为不知到MAC地址,所以填0),对于ARP应答,应答者会把自己MAC地址填入此处,并回应。
目的IP地址(destIP):目的IP地址,即获取这个IP地址主机的MAC地址
ARP解析,注意网络字节顺序是大端格式,对于大部分系统,需要将其转换为小端格式:
//eth.c#include<stdio.h> #include<netinet/if_ether.h> #include"eth.h" /*将二进制网卡地址转换为可读的字符地址,与ifconfig命令中的格式相同*/ void StrMac(u8* str,u8* bin) { sprintf(str,"%02X:%02X:%02X:%02X:%02X:%02X",bin[0],bin[1],bin[2],bin[3],bin[4],bin[5]); }/*将二进制IP地址转换为可读的字符地址,与ifconfig命令中的格式相同*/ void StrIP(u8* str,u8* bin){ sprintf(str,"%d.%d.%d.%d",bin[0],bin[1],bin[2],bin[3]);}/*解析链路层数据,返回值为包类型(大端格式)*/u16 analyseETH(ETH_HEADER* eth) { u8 mac[20]; StrMac(mac,eth->destMAC); printf("destMAC:%s\n",mac); StrMac(mac,eth->sourMAC); printf("sourMAC:%s\n",mac); printf("ETH_type:%04x\n",htons(eth->type)); //htons返回小端格式的数据 return eth->type; }void analyseARP(ARP_STRUCT* arp){ static int num = 0; u8 mac_ip[20]; printf("---------ARP STRUCT[%d]---------\n",num++); printf("hardware:%04x\n",htons(arp->hardware)); printf("protocol:%04x\n",htons(arp->protocol)); printf("mac_len:%d\n",arp->mac_len); printf("ip_len:%d\n",arp->ip_len); printf("op:%04x\n",htons(arp->op)); StrMac(mac_ip,arp->sourMAC); printf("sour_mac:%s\n",mac_ip); StrIP(mac_ip,arp->sourIP); printf("sour_IP:%s\n",mac_ip); StrMac(mac_ip,arp->destMAC); printf("dest_mac:%s\n",mac_ip); StrIP(mac_ip,arp->destIP); printf("dest_IP:%s\n",mac_ip);}int main(){ int socket_fd; ETH_HEADER* eth; u32 num = 0; u16 type; u8 buf[10240]; ssize_t len; socket_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); //申请链路层的套接字 if(socket_fd == -1) { printf("socket error!\n"); return -1; } while(1) { len = recv(socket_fd,buf,sizeof(buf),0); if(len == -1) { printf("recv error!\n"); break; } else if(len == 0) { continue; } printf("*********ETH HEADER[%d]*********\n",num++); printf("recv_len:%d\n",len); eth = (ETH_HEADER*)buf; type = analyseETH(eth); switch(htons(type)) { case ARP_PACKET: printf("ARP_PACKET!\n"); analyseARP((ARP_STRUCT*)eth->data); break; case RARP_PACKET: printf("RARP_PACKET!\n"); break; case IP_PACKET: printf("IP_PACKET!\n"); break; default: printf("what?\n"); break; } } close(socket_fd); return 0; }
执行gcc eth.c -o eth编译
./eth 运行,就可以看到ARP包的信息。
因为ARP应答时,链路层的目的MAC地址已经被替换为ARP请求者的MAC地址,所以只能接受本机发出的和ARP应答和回应给本机的ARP应答包。(除非将网卡配置为混杂模式)
0 0
- TCP/IP协议分析--ARP包
- TCP/IP协议分析--ARP欺骗
- tcp/ip ---------- ARP协议
- 2.tcp/ip协议分析-IP协议、ARP协议和RARP协议
- TCP/IP基础:ARP 协议
- 分析TCP/IP协议栈代码之ARP->IP & ICMP->UDP->TCP(STM32-PDF+代码)
- TCP/IP(3)IP协议ARP协议和RARP协议
- TCP/IP(三)IP协议,ARP协议,RARP协议
- TCP/IP(三)IP协议,ARP协议,RARP协议
- TCP/IP协议学习(2)-IP协议、ARP协议
- linux tcp/ip协议栈源码分析---arp协议的实现
- TCP/IP researching之ARP协议浅析
- TCP/IP researching之ARP协议浅析
- TCP/IP-04-ARP地址解析协议
- TCP/IP 笔记之 ARP协议
- TCP/IP卷一 ARP协议
- TCP/IP协议之ARP与RARP
- TCP/IP 协议 —— ARP
- 学习vi和vim编辑器(1):vi文本编辑器
- 求解集合的交集问题
- Java解析文件内容
- [概率dp] zoj 3822 Domination
- Android 判断程序是不是第一次运行
- TCP/IP协议分析--ARP包
- Codeforces 113A-Grammar Lessons(实现)
- 2014年10月12日 苹果终端 Unix常用指令及clang指令的总结
- STM32外部中断和IWDG
- make 函数(3)--〉其他常用函数
- 第十九章 19.4.2节练习
- [Java Web]Hibernate基础总结(三)
- 【软件工程3】第一篇日志&自我介绍&角色理解&团队寄语
- 的萨达