采用pcab包可以进一步学习TCP/IP协议.在windows下是winpcap函数包(注意需要同时安装驱动库。http://www.winpcap.org 可下载);linux下面是libpcap,一般安装linux时候直接就安装了(不要忘记,tcpdump就是用他实现的哦!)。而且利用改库我们就很方便的对socket数据包进行截取。下面是一个从文档里找到简单的例子。在vc下面编译通过。注意,为了顺利编译通过,还需到http://www.winpcap.org/devel.htm下下载WinPcap 3.1编译库。例子说明:1、本例子是截获tcp数据包,并打印出地址和数据长度,同时取得http协议种使用的cookie。2、本例子在linux没有去测试,但是两个库得函数形式一致,而且例子基本上都是c形式代码,相信移植也很    简单。#include "stdafx.h"#include #include /* 4 bytes IP address */typedef struct ip_address{ u_char byte1; u_char byte2; u_char byte3; u_char byte4;}ip_address;/* IPv4 header */typedef struct ip_header{ u_char ver_ihl;  /* Version (4 bits) + Internet header length (4 bits)*/ u_char tos;      /* Type of service */ u_short tlen;    /* Total length */ u_short identification; /* Identification */  u_short flags_fo;       /* Flags (3 bits) + Fragment offset (13 bits)*/ u_char ttl;      /* Time to live */ u_char proto;    /* Protocol */ u_short crc;     /* Header checksum */ ip_address saddr;/* Source address */ ip_address daddr;/* Destination address */ u_int op_pad;    /* Option + Padding */}ip_header;/* UDP header */typedef struct udp_header{ u_short sport;   /* Source port */ u_short dport;   /* Destination port */ u_short len;     /* Datagram length */ u_short crc;     /* Checksum */}udp_header;/* TCP header */typedef struct tcp_header{ u_short nSrcPort; u_short nDesPort; u_int   SeqNum; u_int   AckSeqNum; u_char   headLen;  }tcp_header;/*声明回调函数 Prototype of the pachet handler */void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data);int FindCookie(const char * pBuf,char * pCookie);int main() {    pcap_if_t* alldevs;    pcap_if_t* d;    int inum;    int i = 0;    pcap_t* adhandle;    char errbuf[PCAP_ERRBUF_SIZE];    u_int netmask;    //注意该处设置过滤条件,形式和tcpdump一致    char packet_filter[] = "tcp and host 192.168.99.199 and port 80";    struct bpf_program fcode;    /* Retrieve the device list */    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)    {        fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);        exit(1);    }    /* Print all net adapter in the list*/    for (d = alldevs; d; d = d->next)    {        printf("%d. %s", ++ i, d->name);        if (d->description)        {            printf(" (%s)\n", d->description);        }        else        {            printf(" (No description available)\n");        }    }    if (i == 0)    {        printf("\nNo interfaces found! Make sure Winpcap is installed.\n");        return -1;    }    //select one of adapter for snatch     printf("Enter the interface number (1 - %d):", i);    scanf("%d", &inum);    if (inum i)    {        printf("\nInterface number out of range.\n");        /* Free the device list */        pcap_freealldevs(alldevs);        return -1;    }    /* Jump to the selected adapter */    // for (d = alldevs; d; d = d->next);    d = alldevs;    /* Open the adapter */    if ((adhandle = pcap_open(d->name,  /*name of the device */        65536,      /* portion of the packet to capture */        /* 65536 grants that the whole packet will be captured on all the MACs */        PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */        1000,       /* read timeout */        NULL,       /* remote authentication */        errbuf      /* error buffer */        )) == NULL)    {        fprintf(stderr, "\nUnable to open the adapter. %s is not supported by Winpcap\n");        /* Free the devices list */        pcap_freealldevs(alldevs);        return -1;    }    /* Check the link layer. We support only Ethernet for simplicity */    if (pcap_datalink(adhandle) != DLT_EN10MB)    {        fprintf(stderr, "\nThis program works only on Ethernet networks.\n");        /* Free the devices list */        pcap_freealldevs(alldevs);        return -1;    }    if (d->addresses != NULL)    {        /* Retrieve the mask of the first address of the interface */        netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;    }    else    {        /* If the interface is without addresses we suppose to be in a C class network */        netmask = 0xffffffff;    }    /* complie the filter */    if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask)     {        fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");        /* Free the devices list */        pcap_freealldevs(alldevs);        return -1;    }    /* set the filter */    if (pcap_setfilter(adhandle, &fcode)     {        fprintf(stderr, "\nError setting the filter.\n");        /* Free the devices list */        pcap_freealldevs(alldevs);        return -1;    }    printf("\nlistening on %s ...\n", d->description);    /* At this point,we don’t need any more the device list. Free it */    pcap_freealldevs(alldevs);    /* Start the capture */    pcap_loop(adhandle, 0, packet_handler, NULL);    return 1;}/* Callback function invoked by libpcap for every incoming packet */void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data){    struct tm* ltime;    char timestr[16];    ip_header* ih;    udp_header* uh;    u_int ip_len;    u_short sport, dport;    tcp_header *tcpHead=NULL;    /* convert the timestamp to readable format */    ltime = localtime(&header->ts.tv_sec);    strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);    /* print timestamp and length of the packet */    printf("%s.%.6d len: %d\n ", timestr, header->ts.tv_usec, header->len);    /* retrieve the position of the ip header */    ih = (ip_header*)(pkt_data + 14);  /* length of ethernet header */    /* retrieve the position of the udp header */    ip_len = (ih->ver_ihl & 0xf) * 4;    tcpHead = (tcp_header*)((u_char*)ih + ip_len);    int tcpHeadLen = (4*(tcpHead->headLen)>>4);    //取得应用数据(http数据),目的分析cookie    char *pData =  (char*)((u_char*)ih + ip_len+tcpHeadLen);    char szCookie[1024];    memset(szCookie,0,sizeof(szCookie));    int nRet = FindCookie(pData,szCookie);    if(nRet ==0 )    {        printf("Cookie=%s",szCookie);        FILE *fp = fopen("d:\\out.txt","aw");        fprintf(fp,"%s",szCookie);        fclose(fp);        //exit(1);    }    /* print ip addresse*/    printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",    ih->saddr.byte1,    ih->saddr.byte2,    ih->saddr.byte3,    ih->saddr.byte4,    /*sport,*/    ih->daddr.byte1,    ih->daddr.byte2,    ih->daddr.byte3,    ih->daddr.byte4    );    } int FindCookie(const char * pBuf,char * pCookie){    char *p =  strstr(pBuf,"Cookie");    if(p==NULL)        return -1;    char *pEnd =  strstr(p,"\r\n");    if(p==NULL)        return -1;    int Len =pEnd-p;    if(Len>1024)        Len =1024;    memmove(pCookie,p,Len);        return 0;}
11-04 13:59