采用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