MAC帧数据包的接收示例(原始套接字)

测试MAC帧数据包使用的传输协议

  1 #include <stdio.h>
  2 #include <sys/socket.h>
  3 #include <stdlib.h>
  4 #include <arpa/inet.h>
  5 #include <unistd.h>
  6 #include <netinet/if_ether.h>
  7 
  8 int main(int argc, const char *argv[])
  9 {
 10     //创建原始套接字
 11     int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
 12     if(sockfd < 0)
 13     {
 14         perror("fail to socket");
 15         exit(1);
 16     }
 17     printf("sockfd = %d\n", sockfd);
 18 
 19     //接收链路层数据
 20     int ret;
 21     unsigned short mac_type;
 22     while(1)
 23     {
 24         unsigned char buf[1600] = {};                                                                                
 25         char src_mac[18] = {};
 26         char dest_mac[18] = {};
 27         //buf将存放完整的帧数据 (例如:MAC头部+IP头+tcp/udp头+应用数据)
 28         ret = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
 29
 30         //从接收到的数据中获取源mac地址、目的mac地址以及类型
 31         sprintf(src_mac, "%x:%x:%x:%x:%x:%x",\
 32                 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
 33         sprintf(dest_mac, "%x:%x:%x:%x:%x:%x",\
 34            buf[0+6], buf[1+6], buf[2+6], buf[3+6], buf[4+6], buf[5+6]);
 35         //从封包中获取网络层的数据类型,注意字节序的转换
 36         mac_type = ntohs(*(unsigned short *)(buf + 12));
 37 
 38         printf("源mac:%s --> 目的mac:%s\n", src_mac, dest_mac);
 39         printf("type = %#x\n", mac_type);
 40         
 41         if(mac_type == 0x800)                                                                                        
 42         {
 43        	  printf("\n****************IP数据包*******************\n");
 44 
 45             //定义指针变量保存IP数据包首地址
 46             unsigned char *ip_buf = buf + 14;
 47             
 48             //获取ip数据包首部长度
 49             //首部长度占4位,是数据包的前八位中的后四位,且单位是4字节
 50             int ip_headlen = ((*ip_buf) & 0x0f) * 4;
 51             printf("ip数据包首部长度: %d字节\n", ip_headlen);
 52             //获取IP封包的总长度,表示总长度的位置从IP数据包的第16位开始
 53             printf("ip数据包总长度:%d字节\n",\
 54                     ntohs(*(unsigned short *)(ip_buf + 2)));
 55 
 56             //分析ip协议包中传输层协议(IP报文的上层协议)
 57             unsigned char ip_type = *(unsigned short *)(ip_buf + 9);
 58             if(ip_type == 1)
 59             {
 60                 printf("ICMP协议\n");
 61             }
 62             else if(ip_type == 2)
 63             {
 64                 printf("IGMP协议\n");
 65             }
 66             else if(ip_type == 6)
 67             {                                                                                                        
 68                 printf("TCP协议\n");
 69             }
 70             else if(ip_type == 17)
 71             {
 72                 printf("UDP协议\n");
 73             }
 74 
 75             printf("******************************************\n\n");
 76         }
 77         else if(mac_type == 0x0806)
 78         {
 79             printf("\nARP数据包\n\n");
 80         }
 81         else if(mac_type == 0x8035)
 82         {
 83             printf("\nRARP数据包\n\n");
 84         }
 85     }
 86 
 87     close(sockfd);
 88 
 89     return 0;
 90 }

猜你喜欢

转载自blog.csdn.net/anton_99/article/details/97614172
今日推荐