加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

用C达成截获网络数据包

发布时间:2021-11-20 18:49:20 所属栏目:教程 来源:互联网
导读:1. 把网卡置于混杂模式。 2. 捕获数据包。 3. 分析数据包。 注:下面的源代码取至Chad Renfro的 Basic Packet-Sniffer Construction from the Ground Up 一文中 /************************Tcp_sniff_2.c********************/ 1.#include 2.#include 3.#incl

1.  把网卡置于混杂模式。
 
2.  捕获数据包。
 
3.  分析数据包。
 
注:下面的源代码取至Chad  Renfro的 < <  Basic  Packet-Sniffer  Construction  from  the  Ground  Up> > 一文中
/************************Tcp_sniff_2.c********************/
1.#include   
2.#include   
3.#include
4.#include
5.#include
6.#include
7.#include   
8.#include
9.#include  "headers.h "
     
#define  INTERFACE  "eth0 "
     
 /*Prototype  area*/
     
10.int  Open_Raw_Socket(void); 
11.int  Set_Promisc(char  *interface,  int  sock); 
12.int  main()  {   
13.int  sock,  bytes_recieved,  fromlen;  
14.char  buffer[65535];
15.struct  sockaddr_in  from; 
16.struct  ip  *ip;
17.struct  tcp  *tcp;   
18.sock  =  Open_Raw_Socket();
19.  Set_Promisc(INTERFACE,  sock);
     
20.  while(1)
22.  {
23.  fromlen  =  sizeof  from;
24.  bytes_recieved  =  recvfrom(sock,  buffer,  sizeof  buffer,  0,  (struct  sockaddr  *)&from,  &fromlen);
25.  printf( "nBytes  received  :::  %5dn ",bytes_recieved);
26.  printf( "Source  address  :::  %sn ",inet_ntoa(from.sin_addr));
27.  ip  =  (struct  ip  *)buffer;
/*See  if  this  is  a  TCP  packet*/
28.  if(ip-> ip_protocol  ==  6)  {
29.  printf( "IP  header  length  :::  %dn ",ip-> ip_length);
30.  printf( "Protocol  :::  %dn ",ip-> ip_protocol);
31.  tcp  =  (struct  tcp  *)(buffer  +  (4*ip-> ip_length));
32.  printf( "Source  port  :::  %dn ",ntohs(tcp-> tcp_source_port));
33.  printf( "Dest  port  :::  %dn ",ntohs(tcp-> tcp_dest_port));
34.  }
     
35.  }
36.}
37.int  Open_Raw_Socket()  {    
38.  int  sock;
39.  if((sock  =  socket(AF_INET,  SOCK_RAW,  IPPROTO_TCP))  <  0)  {
/*Then  the  socket  was  not  created  properly  and  must  die*/
40.  perror( "The  raw  socket  was  not  created ");
41.  exit(0);
42.  };  
43.  return(sock);  
44.  }
     
45.int  Set_Promisc(char  *interface,  int  sock  )  {   
46.  struct  ifreq  ifr;        
47.  strncpy(ifr.ifr_name,  interface,strnlen(interface)+1);
48.  if((ioctl(sock,  SIOCGIFFLAGS,  &ifr)  ==  -1))  {  
/*Could  not  retrieve  flags  for  the  interface*/
49.  perror( "Could  not  retrive  flags  for  the  interface ");
50.  exit(0);
51.  } 
52.  printf( "The  interface  is  :::  %sn ",  interface);  
53.  perror( "Retrieved  flags  from  interface  successfully ");
54.  ifr.ifr_flags  |=  IFF_PROMISC;   
55.  if  (ioctl  (sock,  SIOCSIFFLAGS,  &ifr)  ==  -1  )  {   
/*Could  not  set  the  flags  on  the  interface  */   
56.  perror( "Could  not  set  the  PROMISC  flag: ");
57.  exit(0);     
58.  }
59.  printf( "Setting  interface  :::  %s  :::  to  promisc ",  interface);
60.  return(0);
61.  }
     
/***********************EOF**********************************/
 
上面这段程序中有很详细的注解,不过我想还是有必要说一说,首先第10行--int  Open_Raw_Socket(void); 是我们的自定义函数,具体内容如下:
 
37.int  Open_Raw_Socket()  {    
38.  int  sock;
39.  if((sock  =  socket(AF_INET,  SOCK_RAW,  IPPROTO_TCP))  <  0)  {
/*Then  the  socket  was  not  created  properly  and  must  die*/
40.  perror( "The  raw  socket  was  not  created ");
41.  exit(0);
42.  };  
43.  return(sock);  
44.  }
     
 
                   
 
第39行  if((sock  =  socket(AF_INET,  SOCK_RAW,  IPPROTO_TCP))  <  0)  {
 
这里我们调用了socket函数,使创建了了一个原始套接口,使之收到TCP/IP信息包。
 
  接下来第11行-int  Set_Promisc(char  *interface,  int  sock),这也是我们的自定义函数,目的是把网卡置于混杂模式,具体内容如下:
45.int  Set_Promisc(char  *interface,  int  sock  )  {   
46.  struct  ifreq  ifr;        
47.  strncpy(ifr.ifr_name,  interface,strnlen(interface)+1);
48.  if((ioctl(sock,  SIOCGIFFLAGS,  &ifr)  ==  -1))  {  
/*Could  not  retrieve  flags  for  the  interface*/
49.  perror( "Could  not  retrive  flags  for  the  interface ");
50.  exit(0);
51.  } 
52.  printf( "The  interface  is  :::  %sn ",  interface);  
53.  perror( "Retrieved  flags  from  interface  successfully ");
54.  ifr.ifr_flags  |=  IFF_PROMISC;   
55.  if  (ioctl  (sock,  SIOCSIFFLAGS,  &ifr)  ==  -1  )  {   
/*Could  not  set  the  flags  on  the  interface  */   
56.  perror( "Could  not  set  the  PROMISC  flag: ");
57.  exit(0);     
58.  }
59.  printf( "Setting  interface  :::  %s  :::  to  promisc ",  interface);
60.  return(0);
61.  }
 
  首先  struct  ifreq  ifr;  定一了一个ifrreg的结构ifr,接下来  strncpy(ifr.ifr_name,  interface,strnlen(interface)+1);,就是把我们网络设备的名字填充到ifr结构中,在这里  #define  INTERFACE  "eth0 "  ,让我们再往下看,ioctl(sock,  SIOCGIFFLAGS,  &ifr),SIOCGIFFLAGS请求表示需要获取接口标志,现在到了第54行,在我们成功的获取接口标志后把他设置成混杂模式,ifr.ifr_flags  |=  IFF_PROMISC;ioctl  (sock,  SIOCSIFFLAGS,  &ifr)。OK,现在我们所说的第一步已经完成--------把网卡置于混杂模式。 

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读