WinPcap发送接收裸包(二)

来源:互联网 发布:java成绩代码 编辑:程序博客网 时间:2024/05/16 14:20

上一篇说了如何发送裸包,下面看如何接收数据包。

代码很简单,就不多介绍了。

#ifdef _MSC_VER/* * we do not want the warnings about the old deprecated and unsecure CRT functions * since these examples can be compiled under *nix as well */#define _CRT_SECURE_NO_WARNINGS#endif#include "pcap.h"typedef struct eth_header{unsigned char DestMac[6];unsigned char SrcMac[6];unsigned short Etype;}eth_header;/* prototype of the packet handler */void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);void formatMACToStr(LPSTR lpHWAddrStr,const unsigned char *HWAddr);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;char packet_filter[] ="ether src 28:d2:44:28:74:f9" /*"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", errbuf);exit(1);}/* Print the list */for(d=alldevs; d; d=d->next){printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s)\n", d->description);elseprintf(" (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):",i);scanf("%d", &inum);/* Check if the user specified a valid adapter */if(inum < 1 || inum > i){printf("\nAdapter 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 (nonzero means promiscuous) 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 filterif (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 filterif (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", 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 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];time_t local_tv_sec;eth_header *pEthHeader;char strMac[50];char *pRecBuffer;/* * unused parameter */(VOID)(param);/* convert the timestamp to readable format */local_tv_sec = header->ts.tv_sec;ltime=localtime(&local_tv_sec);strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);/* print timestamp and length of the packet */pEthHeader=(eth_header *)pkt_data;formatMACToStr(strMac,pEthHeader->SrcMac);printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);printf("\nSrcMac is:%s-->",strMac);formatMACToStr(strMac,pEthHeader->DestMac);printf("destMac is:%s\n",strMac);printf("eth type is:\t%d\n",ntohs(pEthHeader->Etype));    pRecBuffer=(char *)(pkt_data+14);printf("data is:\t%s\n",pRecBuffer);}/*****************************************************************************Name & Params::*formatMACToStr*(*LPSTR lpHWAddrStr : 要显示到list上的字符串*unsigned char *HWAddr :  传入的MAC字符串*)*Purpose:*将用户输入的MAC地址字符转成相应格式****************************************************************************/void formatMACToStr(LPSTR lpHWAddrStr,const unsigned char *HWAddr){int i;short temp;char szStr[3];strcpy(lpHWAddrStr, "");for (i=0; i<6; ++i){temp = (short)(*(HWAddr + i));_itoa(temp, szStr, 16);if (strlen(szStr) == 1)strcat(lpHWAddrStr, "0");strcat(lpHWAddrStr, szStr);if (i<5)strcat(lpHWAddrStr, ":");         // 加上 - }}

0 0