Chinaunix首页 | 论坛 | 博客
  • 博客访问: 482611
  • 博文数量: 120
  • 博客积分: 1853
  • 博客等级: 上尉
  • 技术积分: 1177
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-22 22:40
文章分类

全部博文(120)

文章存档

2013年(16)

2012年(104)

分类: 网络与安全

2012-10-16 22:56:39

1.设置数据链路层的原始套接字
2.设置为混杂模式
3.针对个层协议都有不同的数据结构,可以去/usr/include/netinet/目录下去查找相应的文件,察看struct的定义
4.如果自己定义结构体,必须注意大小端的问题。详情请看 /usr/include/netinet/ip.h中steuct iphdr 中ihl和version的定义。
5.本程序是从数据链路层开始抓区数据,如果想从IP层抓取TCP或者UDP数据的话,只需要修改socket函数中的第三个参数改为IPPROTO_TCP或者IPPROTO_UDP即可。
6.我只是把网卡名称设置为了 “eth0“, 在别的机器上,可能要改成别的名称。
7.通过这次编程知道了,127.0.0.1是自循环的,如果从数据链路层开始抓包的话,mac地址显示的是0(实际上可能都不经过数据链路层).
8.本程序,不支持无线网卡。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <net/ethernet.h>
  3. #include <netinet/ip.h>
  4. #include <netinet/tcp.h>
  5. #include <netinet/udp.h>
  6. #include <arpa/inet.h>
  7. #include <sys/ioctl.h>
  8. #include <string.h>
  9. #include <net/if.h>
  10. #include <errno.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/socket.h>

  15. int analyData(char *data);
  16. int rawSocket();
  17. int setPromisc(char *,int *);
  18. int native(char *data);
  19. int count=0;
  20. int main(int argc,char **argv)
  21. {
  22.    /* if(argc!=2)
  23.     {
  24.         perror("please enter the ecterface");
  25.         exit(1);
  26.     }
  27.         */
  28.     int sock;
  29.     int msgsock;
  30.     struct sockaddr_in rcvaddr;
  31.     char buf[9216];
  32.     struct ifreq ifr;
  33.     int len;
  34.     int rval;
  35.     sock=rawSocket();
  36.     setPromisc("eth0",&sock);
  37.     len=sizeof(struct sockaddr);
  38.     memset(buf,0,sizeof(buf));
  39.     while(1)
  40.     {
  41.         rval=recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&rcvaddr,&len);
  42.         if(rval>0)
  43.         {
  44.             printf("本次获取 %d bytes,以下是分析数据\n",rval);
  45.             analyData(buf);

  46.         }

  47.     }
  48.     return 0;


  49. }
  50. int analyData(char *data)
  51. {
  52.     struct iphdr *ip;
  53.     struct tcphdr *tcp;
  54.     struct udphdr *udp;
  55.         struct ether_header *ether;
  56.     ether=(struct ether_header*)data;//若数据是从数据链路曾抓取的,那么就有这个以太网帧头

  57.     count++;
  58.     printf("Frame %d \n",count);
  59.     printf("帧中协议: %04x\n",htons(ether->ether_type));
  60.     
  61.         /*mac部分*/
  62.         int Ndata;
  63.         u_int8_t *tmp = (u_int8_t *)data;
  64.         printf("dst mac:\n");
  65.         for(Ndata=0; Ndata<ETHER_ADDR_LEN; Ndata++){
  66.                 printf("%02x ", tmp[Ndata]);
  67.         }
  68.         
  69.         tmp = (u_int8_t *)data + ETHER_ADDR_LEN;
  70.         printf("\nsrc mac:\n");
  71.         for(Ndata=6; Ndata<ETHER_ADDR_LEN + 6; Ndata++){
  72.                 printf("%02x ", tmp[Ndata]);
  73.         }
  74.         printf("\n");
  75.         

  76.         /*ip 部分*/
  77.         ip=(struct iphdr*)(data+sizeof(struct ether_header));
  78.         data = data + sizeof(struct ether_header);
  79.         char ip_buf[100];
  80.     printf("version: %d ", ip->version);
  81.         printf("ttl: %d\n", ip->ttl);
  82.         printf("Source IP::%s",inet_ntop(AF_INET, &ip->saddr, ip_buf, 100));
  83.     printf("Dest IP::%s",inet_ntop(AF_INET, &ip->daddr, ip_buf, 100));
  84.         printf("\n");

  85.         /*tc部分*/
  86.          data = data + (ip->ihl<<2);
  87.         if(ip->protocol == 6){
  88.             printf("tcp header:\n");
  89.              tcp=(struct tcphdr *)data;
  90.          printf("Source Port::%d\n",ntohs(tcp->source));
  91.             printf("Dest Port::%d\n",ntohs(tcp->dest));
  92.             printf("\n");
  93.         }

  94.         /*udp 部分*/
  95.         if(ip->protocol == 17){
  96.             udp = (struct udphdr *)data;
  97.             printf("udp header:\n");
  98.             printf("udp source port: %d\n", ntohs(udp->source));            
  99.             printf("udp dst port: %d\n", ntohs(udp->dest));            
  100.             printf("udp len \n: %d\n", ntohs(udp->len));            
  101.         }



  102.     return 1;
  103. }

  104. int rawSocket()//创建原始套接字
  105. {
  106.     int sock;
  107. //     sock=socket(PF_INET,SOCK_RAW,IPPROTO_TCP);//IP层抓取

  108.         sock=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));//数据链路层抓取
  109.     if(sock<0)
  110.     {
  111.         printf("create raw socket failed::%s\n",strerror(errno));
  112.         exit(1);
  113.     }
  114.     
  115.     printf("raw socket ::%d created successful\n",sock);
  116.     return sock;
  117. }
  118. int setPromisc(char *enterface,int *sock)//设置eth0的混乱模式
  119. {
  120.     struct ifreq ifr;
  121.     strcpy(ifr.ifr_name, "eth0");
  122.     ifr.ifr_flags=IFF_UP|IFF_PROMISC|IFF_BROADCAST|IFF_RUNNING;
  123.     if(ioctl(*sock,SIOCSIFFLAGS,&ifr)==-1)//设置混乱模式
  124.     {
  125.         perror("set 'eth0' to promisc model failed\n");
  126.         exit(1);
  127.     }
  128.     printf("set '%s' to promisc successed\n",enterface);
  129.     return 1;

  130. }

阅读(1922) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~