printf(\ }
if(res == -1){
printf(\ } return 0; }
用pcap_live_dump将数据写到文件:
WinPcap的最新版本提供了一个进一步的方法来将数据包存储到磁盘,就是使用pcap_live_dump()函数。他需要三个参数:一个文件名,和一个该文件允许的最大长度还有一个参数是该文件所允许的最大包的数量。对这些参数来说 0 意味着没有最大限制。注:我们可以在调用pcap_live_dump()前设置一个过滤器来定义哪些数据报需要存储。
pcap_live_dump() 是非阻塞的,所以他会立刻返回:数据的存储过程将会异步的进行,直到文件到达了指定的最大长度或最大数据报的数目为止。
应用程序能够用pcap_live_dump_ended()来等检查是否数据存储完毕,如果你指定的最大长度参数和数据报数量为0,那么该操作将永远阻塞。
pcap_live_dump() 和 pcap_dump()的不同从设置的最大极限来说就是性能的问题。pcap_live_dump()采用WinPcap NPF驱动来从内核级的层次上向文件中写数据,从而使内存拷贝最小化。
显然,这些特点当前在其他的操作系统下是不能够实现的,pcap_live_dump()是WinPcap所特有的,而且只能够应用于Win32环境.
循序渐进学习使用WINPCAP(八) ---------发送数据包
尽管WinPcap从名字上来看表明他的主要目的是捕获数据包,但是他还为原始网络提供了一些其他的功能,其中
之一就是用户可以发送数据包,这也就是本节的主要内容。需要指出的是原来的libpcap并不提供数据包 的发
送功能,这里所说的功能都是WinPcap的扩展功能,所以并不能够工作在UNIX下。
用pcap_sendpacket来发送一个数据包:
下面的代码是一个最简单的发送数据的方法。打开一个适配器后就可以用 pcap_sendpacket()来手工发送
一
个数据包了。这个函数需要的参数:一个装有要发送数据的缓冲区,要发送的长度,和一个适配器。注意缓冲
区中的数据将不被内核协议处理,只是作为最原始的数据流被发送,所以我门必须填充好正确的协议头以便正
确的将数据发送。
#include
#include
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(\ return; }
/* 打开指定网卡 */
if((fp = pcap_open_live(argv[1], 100, 1, 1000, error) ) == NULL) {
fprintf(stderr,\ return; }
/* 假设网络环境为ethernet,我门把目的MAC设为1:1:1:1:1:1*/ packet[0]=1; packet[1]=1; packet[2]=1;
packet[3]=1; packet[4]=1; packet[5]=1;
/* 假设源MAC为 2:2:2:2:2:2 */ packet[6]=2; packet[7]=2; packet[8]=2; packet[9]=2; packet[10]=2; packet[11]=2;
/* 填充发送包的剩余部分 */ for(i=12;i<100;i++){ packet[i]=i%6; }
/* 发送包 */ pcap_sendpacket(fp, packet, 100); return; }
发送队列:
pcap_sendpacket()只是提供一个简单的直接的发送数据的方法,而发送队列提供一个高级的强大的和最优的机
制来发送一组数据包,队列实际上是一个装有要发送数据的一个容器,他有一个最大值来表明他所能够 容纳的
最大比特数。
pcap_sendqueue_alloc()用来创建一个队列,并指定该队列的大小。
一旦队列被创建就可以调用pcap_sendqueue_queue()来将数据存储到队列中,这个函数接受一个带有时间戳和
长度的pcap_pkthdr结构和一个装有数据报的缓冲区。这些参数同样也应用于pcap_next_ex() 和
pcap_handler()中,所以给要捕获的数据包或要从文件读取的数据包排队就是pcap_sendqueue_queue()的事情 了。
WinPcap调用pcap_sendqueue_transmit()来发送数据包,注意,第三个参数如果非零,那么发送将是同步的,
这将站用很大的CPU资源,因为发生在内核驱动的同步发送是通过\的,但是一般情况下能够
精确到微秒。
需要指出的是用pcap_sendqueue_transmit()来发送比用pcap_sendpacket()来发送一系列的数据要高效的多,
因为他的数据是在内核级上被缓冲。
当不再需要队列时可以用pcap_sendqueue_destroy()来释放掉所有的队列资源。
下面的代码演示了如何用发送队列来发送数据,该示例用pcap_open_offline()打开了一个文件,然后将数据
从文件移动到已分配的队列,这时就同步地传送队列(如果用户指定为同步的话)。 /*
* Copyright (c) 1999 - 2002
* Politecnico di Torino. All rights reserved. *
* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the Politecnico * di Torino, and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
#include
#include
void usage();
void main(int argc, char **argv) { pcap_t *indesc,*outdesc;
char error[PCAP_ERRBUF_SIZE]; FILE *capfile; int caplen, sync; u_int res;
pcap_send_queue *squeue; struct pcap_pkthdr *pktheader; u_char *pktdata;
/* Check the validity of the command line */ if (argc <= 2 || argc >= 5) { usage(); return; }
/* 得到文件长度 */ capfile=fopen(argv[1],\ if(!capfile){
printf(\ return; }
fseek(capfile , 0, SEEK_END);
caplen= ftell(capfile)- sizeof(struct pcap_file_header); fclose(capfile);
/* 检查确保时间戳被忽略 */ if(argc == 4 && argv[3][0] == 's') sync = TRUE; else
sync = FALSE;
/* Open the capture */
if((indesc = pcap_open_offline(argv[1], error)) == NULL){ fprintf(stderr,\ return; }
/* Open the output adapter */
if((outdesc = pcap_open_live(argv[2], 100, 1, 1000, error) ) == NULL) {
fprintf(stderr,\ return;