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

全部博文(120)

文章存档

2013年(16)

2012年(104)

分类: WINDOWS

2013-02-27 01:53:25

需注意的有一下几点:

1.pcap_next_ex返回的是从数据链路层开始的包,因此分析ip包应先去掉帧头

2.包由外而内数据链路层->ip层->tcp

3.结构体中位域的变量也有大小端的问题,因为我的机器是x86的,是小端,因此结构体定义没有考虑大端的情况

3.winpcap需要先complie然后才能filter,filter的规则为,我使用的是tcp and src host *.*.*.*,过滤源地址为*.*.*.*的tcp包

4.winpcap开发需要下载winpcap的开发包http://www.winpcap.org/devel.htm。然后在vs2010中的加入include和lib的目录,然后在链接器中加入lib目录下的.lib文件名,然后就能#include

源代码有两个文件

贴一下:

tcp.h


点击(此处)折叠或打开

  1. #include <WinSock2.h>
  2. /* 4字节的IP地址 */
  3. typedef struct ip_address
  4. {
  5.     u_char byte1;
  6.     u_char byte2;
  7.     u_char byte3;
  8.     u_char byte4;
  9. } ip_address;

  10. /* IPv4 首部 */

  11. typedef struct header_tcp
  12. {
  13.     u_short src_port;
  14.     u_short dst_port;
  15.     u_int seq;
  16.     u_int ack_seq;
  17.     u_short doff:4,hlen:4,fin:1,syn:1,rst:1,psh:1,ack:1,urg:1,ece:1,cwr:1;
  18.     u_short window;
  19.     u_short check;
  20.     u_short urg_ptr;
  21. }tcp_header;
  22. typedef struct ip_header
  23. {
  24.     u_char ver_ihl; // 版本 (4 bits) + 首部长度 (4 bits)
  25.     u_char tos; // 服务类型(Type of service)
  26.     u_short tlen; // 总长(Total length)
  27.     u_short identification; // 标识(Identification)
  28.     u_short flags_fo; // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
  29.     u_char ttl; // 存活时间(Time to live)
  30.     u_char proto; // 协议(Protocol)
  31.     u_short crc; // 首部校验和(Header checksum)
  32.     ip_address saddr; // 源地址(Source address)
  33.     ip_address daddr; // 目的地址(Destination address)
  34.     u_int op_pad; // 选项与填充(Option + Padding)
  35. } ip_header;


main.cpp

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <tchar.h>
  3. #include <WinSock2.h>
  4. #include <Windows.h>

  5. #include <stdlib.h>
  6. #include <iostream>
  7. #include <string>
  8. #define HAVE_REMOTE
  9. #include <pcap.h>
  10. #include "tcp_ip.h"
  11. int main()
  12. {
  13.     pcap_if_t *alldevs;
  14.     pcap_if_t *d;
  15.     int inum;
  16.     int i=0;
  17.     pcap_t *adhandle;
  18.     char errbuf[PCAP_ERRBUF_SIZE];
  19.     u_int netmask;
  20.     char packet_filter[] = "tcp and (src host *.*.*.*)";//自己定义ip地址即可
  21.     struct bpf_program fcode;


  22.     /* 获取本机设备列表 */
  23.     if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
  24.     {
  25.         fprintf(stderr,"Error in pcap_findalldevs: %sn", errbuf);
  26.         exit(1);
  27.     }

  28.     /* 打印列表 */
  29.     for(d=alldevs; d; d=d->next)
  30.     {
  31.         printf("%d. %s", ++i, d->name);
  32.         if (d->description)
  33.             printf(" (%s)n", d->description);
  34.         else
  35.             printf(" (No description available)n");
  36.     }

  37.     if(i==0)
  38.     {
  39.         printf("nNo interfaces found! Make sure WinPcap is installed.n");
  40.         return -1;
  41.     }

  42.     printf("Enter the interface number (1-%d):",i);
  43.     scanf("%d", &inum);

  44.     if(inum < 1 || inum > i)
  45.     {
  46.         printf("nInterface number out of range.n");
  47.         /* 释放设备列表 */
  48.         pcap_freealldevs(alldevs);
  49.         return -1;
  50.     }

  51.     /* 跳转到选中的适配器 */
  52.     for(d=alldevs, i=0; i< inum-1 ; d=d->next, i++);

  53.     /* 打开设备 */
  54.     if ( (adhandle= pcap_open(d->name, // 设备名
  55.         65535, // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
  56.         PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
  57.         1000, // 读取超时时间
  58.         NULL, // 远程机器验证
  59.         errbuf // 错误缓冲池
  60.         ) ) == NULL)
  61.     {
  62.         fprintf(stderr,"nUnable to open the adapter. %s is not supported by WinPcapn", d->name);
  63.         /* 释放设备列表 */
  64.         pcap_freealldevs(alldevs);
  65.         return -1;
  66.     }

  67.     printf("nlistening on %s...n", d->description);


  68.     /* 检查数据链路层,为了简单,我们只考虑以太网 */
  69.     if(pcap_datalink(adhandle) != DLT_EN10MB)
  70.     {
  71.         fprintf(stderr,"nThis program works only on Ethernet networks.n");
  72.         /* 释放设备列表 */
  73.         pcap_freealldevs(alldevs);
  74.         return -1;
  75.     }
  76.     printf("datalink:[%d]n", pcap_datalink(adhandle));
  77.     if(d->addresses != NULL)
  78.         /* 获得接口第一个地址的掩码 */
  79.         netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
  80.     else
  81.         /* 如果接口没有地址,那么我们假设一个C类的掩码 */
  82.         netmask=0xffffff;


  83.     //编译过滤器
  84.     if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
  85.     {
  86.         fprintf(stderr,"nUnable to compile the packet filter. Check the syntax.n");
  87.         /* 释放设备列表 */
  88.         pcap_freealldevs(alldevs);
  89.         int x;
  90.         scanf("%d",&x);
  91.         return -1;
  92.     }

  93.     //设置过滤器
  94.     if (pcap_setfilter(adhandle, &fcode)<0)
  95.     {
  96.         fprintf(stderr,"nError setting the filter.n");
  97.         /* 释放设备列表 */
  98.         pcap_freealldevs(alldevs);
  99.         return -1;
  100.     }

  101.     printf("nlistening on %s...n", d->description);

  102.     /* 释放设备列表 */
  103.     pcap_freealldevs(alldevs);
  104.     


  105.     /* 开始捕获 */
  106.     int ret;
  107.     struct pcap_pkthdr *header;
  108.     const u_char *pkt_data;


  109.     while ((ret = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0)
  110.     {
  111.         if(ret == 0)
  112.         {
  113.             /* 超时时间到 */
  114.             printf("time over!n");
  115.             continue;
  116.         }
  117.         char buffer[20000];
  118.         if (header->len > 0)
  119.         {
  120.             printf("len:[%d]n",header->len);
  121.             ip_header *ip =(ip_header *) (pkt_data +14);
  122.             printf("daddr:[%u.%u.%u.%u]n", ip->daddr.byte1,ip->daddr.byte2,ip->daddr.byte3,ip->daddr.byte4);
  123.             printf("saddr:[%u.%u.%u.%u]n", ip->saddr.byte1,ip->saddr.byte2,ip->saddr.byte3,ip->saddr.byte4);
  124.             tcp_header *tcp = (tcp_header *)((u_char*)ip + (ip->ver_ihl&0xf)*4);
  125.             char *data = (char *)tcp + (tcp->hlen)*4;
  126.             u_int datalen = ntohs(ip->tlen)-(ip->ver_ihl&0xf)*4-(tcp->hlen)*4;
  127.             
  128.             
  129.             memcpy(buffer, data, datalen);
  130.             buffer[datalen] = '';
  131.             printf("buffer:[%s]n", buffer+20);
  132.         }
  133.     }
  134.     return 0;
  135. }


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