Winpcap程序实例
获得网卡接口。在普通的SOCKET编程中,对双网卡编程是不行的。当主机为双网卡时,本程序可分别获得两张网卡各自的描述结构及地址,然后可以对它们分别进行操作。返回的alldevs队列首部为逻辑网卡,一般不对它进行什么操作。 (一)获得网卡接口 #i nclude \"pcap.h\" void main() {
pcap_if_t *alldevs; /*struct pcap_if_t{ pcap_if_t *next; char *name; char *description; pcap_addr *addresses; U_int falgs; } */
pcap_if_t *d; int i=0;
char errbuf[PCAP_ERRBUF_SIZE]; /* Retrieve the device list */
if (pcap_findalldevs(&alldevs, errbuf) == -1)//返回网卡列表,alldevs指向表头 {
fprintf(stderr,\"Error in pcap_findalldevs: %s\\n\ exit(1); }
/* Print the list */ for(d=alldevs;d;d=d->next) {
printf(\"%d. %s\ if (d->description)
printf(\" (%s)\\n\
else printf(\" (No description available)\\n\"); } if(i==0)
{
printf(\"\\nNo interfaces found! Make sure WinPcap is installed.\\n\"); return; }
/* We don't need any more the device list. Free it */ pcap_freealldevs(alldevs); }
-------------------------------------------------------------------------------- (二)抓包
本程序俘获局域网内UDP报文。 #i nclude \"pcap.h\" /* 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;
/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); 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;
char packet_filter[] = \"ip and udp\"; struct bpf_program fcode; /* Retrieve the device list */
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr,\"Error in pcap_findalldevs: %s\\n\ exit(1); }
/* Print the list */
for(d=alldevs; d; d=d->next) {
printf(\"%d. %s\ if (d->description)
printf(\" (%s)\\n\ else
printf(\" (No description available)\\n\"); } if(i==0) {
printf(\"\\nNo interfaces found! Make sure WinPcap is installed.\\n\"); return -1; }
printf(\"Enter the interface number (1-%d):\ scanf(\"%d\ if(inum < 1 || 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, i=0; i< inum-1 ;d=d->next, i++); /* Open the adapter */
if ( (adhandle= pcap_open_live(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. 1, // promiscuous mode 1000, // read timeout errbuf // error buffer ) ) == NULL) {
fprintf(stderr,\"\\nUnable to open the adapter. %s is not supported by WinPcap\\n\");
/* Free the device 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 device 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=0xffffff; //compile the filter
if(pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ){ fprintf(stderr,\"\\nUnable to compile the packet filter. Check the syntax.\\n\");
/* Free the device list */ pcap_freealldevs(alldevs); return -1; }
//set the filter
if(pcap_setfilter(adhandle, &fcode)<0){
fprintf(stderr,\"\\nError setting the filter.\\n\"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
printf(\"\\nlistening on %s...\\n\
/* 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 0; }
/* 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;
/* convert the timestamp to readable format */ ltime=localtime(&header->ts.tv_sec);
strftime( timestr, sizeof timestr, \"%H:%M:%S\ /* print timestamp and length of the packet */ /* retireve the position of the ip header */ ih = (ip_header *) (pkt_data + 14); //length of ethernet header
/* retireve the position of the udp header */ ip_len = (ih->ver_ihl & 0xf) * 4;
uh = (udp_header *) ((u_char*)ih + ip_len);
/* convert from network byte order to host byte order */ printf(\"%s.%.6d len:%d \header->len);
/* print ip addresses */
printf(\"%d.%d.%d.%d -> %d.%d.%d.%d\\n\ ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4, ih->daddr.byte1, ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4 ); }
-------------------------------------------------------------------------------- (三)发包
要在命令行下运行,给与参数:网卡描述符。或者添加代码findalldevs(),那样应很方便。
#i nclude #i nclude void main(int argc, char **argv) { pcap_t *fp; char error[PCAP_ERRBUF_SIZE]; u_char packet[100]; int i; /* Check the validity of the command line */ if (argc != 2) { printf(\"usage: %s inerface\ return; } /* Open the output adapter */ if((fp = pcap_open_live(argv[1], 100, 1, 1000, error) ) == NULL) { fprintf(stderr,\"\\nError opening adapter: %s\\n\ return; } /* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */ packet[0]=1; packet[1]=1; packet[2]=1; packet[3]=1; packet[4]=1; packet[5]=1; /* set mac source to 2:2:2:2:2:2 */ packet[6]=2; packet[7]=2; packet[8]=2; packet[9]=2; packet[10]=2; packet[11]=2; /* Fill the rest of the packet */ for(i=12;i<100;i++){ packet=i%256; } /* Send down the packet */ pcap_sendpacket(fp, packet, 100); return; } 系统管理 linux及windows系统管理 主页博客相册|个人档案 |好友 查看文章 使用Winpcap示例程序的时候,会出现很多错误(转) 2009-12-02 11:55 因篇幅问题不能全部显示,请点此查看更多更全内容