您的当前位置:首页正文

Winpcap程序实例

2021-11-25 来源:步旅网


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 #i nclude void usage();

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

因篇幅问题不能全部显示,请点此查看更多更全内容