在平凡中也会有很多的快乐;有梦想,人才不会孤单
学会放弃~
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一个简单的Sniffer程序

Posted on 2005-04-18 19:00  情走边锋  阅读(550)  评论(0)    收藏  举报
一个简单的Sniffer程序
   下面是一个非常简单的C程序,它可以完成一般的监听功能,/* */中的内容是本文的注解。
  /*下面是包含进行调用系统和网络函数的头文件*/
  #include〈stdio.h〉
  #include〈sys/socket.h〉
  #include〈netinet/in.h〉
  #include〈arpa/inet.h〉
  /*下面是IP和TCP包头结构*/
  struct IP{
   unsigned int ip_length:4;
   /*定义IP头的长度*/
   unsigned int ip_version:4;
   /*IP版本,Ipv4 */
   unsigned char ip_tos;
   /*服务类型*/
   unsigned short
  ip_total_length; /*IP数据包的总长度*/
   unsigned short ip_id;
   /*鉴定城*/
   unsigned short ip_flags;
   /*IP 标志 */
   unsigned char ip_ttl;
   /*IP 包的存活期*/
   unsigned char ip_protocol;
   /*IP 上层的协议*/
   unsigned short ip_cksum;
   /*IP头校验和*/
  unsigned int ip_source ;
  /*源IP地址*/
  unsigned int ip_source;
  /*目的IP地址*/
   };
  struct tcp{
  unsigned short tcp_source_port;
  /*定义TCP源端口*/
   unsigned short tcp_dest_port;
   /*TCP目的端口*/
   unsigned short tcp_seqno;
   /*TC P序列号*/
  unsigned int tcp_ackno;
  /*发送者期望的下一个序列号*/
  unsigned int tcp_res1:4;
  /*下面几个是TCP标志*/
  tcp_hlen:4
  tcp_fin:1,
  tcp_syn:1,
  tcp_rst:1,
  tcp_psh:1,
  tcp_ack:1,
  tcp_urg:1,
  tcp_res2:2;
  unsignd short tcp_winsize; /*能接收的最大字节数*/
   unsigned short tcp_cksum;
   /* TCP校验和*/
   unsigned short tcp_urgent;
   /* 紧急事件标志*/
  };
  /*主函数*/
  int main()
  {
  int sock,bytes_recieved,fromlen;
  char buffer[65535];
  struct sockaddr_in from;
   /*定义socket结构*/
  struct ip ip;
   /*定义IP和TCP*/
  struct tcp *tcp;
   sock=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
  /* 上面是建立socket连接,第一个参数是地址族类型,用INTERNET类型*/
  /* 第二个参数是socket类型,这里用了SOCK_RAW,它可以绕过传输层*/
  /* 直接访问IP层的包,为了调用SOCK_RAW,需要有root权限*/
  /* 第三个参数是协议,选IPPROTO_TCP指定了接收TCP层的内容*/
  while(1)
  /*建立一个死循环,不停的接收网络信息*/
  {
  fromlen=sizeof from;
  bytes_recieved=recvfrom(sock,buffer,sizeofbuffer,0,(struct sockaddr *)&from,&fromlen);
  /*上面这个函数是从建立的socket连接中接收数据*/
  /*因为recvfrom()需要一个sockaddr数据类型,所以我们用了一个强制类型转换*/
  print("\nBytes received ::: %5d\n",bytes_recieved);
  /*显示出接收的数据字节数*/
  printf("source address ::: %s\n",inet_ntoa(from.sin_addr));
  /*显示出源地址*/
  ip=(struct ip *)buffer;
  /*把接收的数据转化为我们预先定义的结构,便于查看*/
  printf("IP header length ::: %d\n",ip->ip_length);
  /*显示IP头的长度*/
  print("Protocol ::: %d\n",ip->ip_protocol);
  /*显示协议类型,6是TCP,17是UDP*/
  tcp=(struct tcp *)(buffer + (4*ip->ip_iplength));
  /*上面这名需要详细解释一下,因为接收的包头数据中,IP头的大小是固定的4字节*/
  /*所以我用IP长度乘以4,指向TCP头部分*/
  printf("Source port ::: %d\n",ntohs(tcp->tcp_source_port); /*显示出端口*/
  printf("Dest prot ::: %d\n",ntohs(tcp->tcp_dest_port));/*显示出目标端口*/
   以上这个C程序是为了说明Sniffer的接收原理而列举的一个最简单的例子,它只是完成了Sniffer的接收功能,在运行它之前,我们还需要手工把同卡设为混杂模式,在root权限下用如下命令设置:
  ifconfig eth0 promisc
科为网络安全