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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 儿童7岁还坐不住怎么办 孩子缺锌手蜕皮裂开怎么办 宝宝读幼儿园哭怎么办 幼儿上课爱讲话怎么办 孩子上课总是乱跑怎么办 孩子听不懂老师讲课怎么办 高一上课听不懂怎么办 上课学生纪律差怎么办 一年级学生认字少怎么办 孩子上课做不住怎么办 幼儿园小孩上课乱跑怎么办 孩子挑食不爱吃饭怎么办 幼儿园孩子不听指令怎么办 1岁宝宝多动症怎么办 3岁宝宝胆小怎么办 爱挑食的孩子怎么办 小孩上课经常发呆怎么办 小孩不爱吃饭挑食怎么办 一年级小孩学习不好怎么办 宝宝上课坐不住怎么办 八个月婴儿拉稀怎么办 八个月孕妇拉稀怎么办 孩子好动爱喊怎么办 八个月小孩发烧怎么办 孩子好动怎么办学龄前教育 小孩好动症该怎么办 小孩子好动症该怎么办 怀孕5个月胎死亡怎么办 小孩多动调皮怎么办 手心老是出汗是怎么办 孩子吃饭特别慢怎么办 小孩子老想睡觉怎么办 孩子下午上课犯困怎么办 小孩子有多动症该怎么办 初中写作业犯困怎么办 孩子晚上学习困怎么办 小孩子容易兴奋激动怎么办 中考时过度兴奋怎么办 小孩兴奋不睡觉怎么办 孩子突然反常不听话怎么办? 婴儿亢奋不睡觉怎么办