pcap_t* pcap_open_offline ( const char * fname, char * errbuf );
参数含义:
fname:要打开的文件名;
errbuf:保存错误信息;
这里我们通过pcap_createsrcstr()函数根据新WinPcap语法创建一个源字符串。函数具体格式如下:
int pcap_createsrcstr ( char * source, int type, const char * host, const char * port, const char * name, char * errbuf );
参数含义:
source:要存入的源字符串;
type:要创建的源字符串类型;
host:远程主机;
port:远程端口;
name:我们要打开的文件名;
errbuf:存储错误信息;
返回值:
0:没有错误;
-1:创建出错,错误写入errbuf中;
下面的程序读取保存的文件,然后将数据包中的数据打印出来:
#include <stdio.h> #include <pcap.h> #define LINE_LEN 16 void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *); main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; char source[PCAP_BUF_SIZE]; if (argc != 2) { printf("usage: %s filename", argv[0]); return -1; } /* 根据新WinPcap语法创建一个源字符串 */ if (pcap_createsrcstr(source, // 源字符串 PCAP_SRC_FILE, // 我们要打开的文件 NULL, // 远程主机 NULL, // 远程主机端口 argv[1], // 我们要打开的文件名 errbuf // 错误缓冲区 ) != 0) { fprintf(stderr, "\nError creating a source string\n"); return -1; } /* 打开捕获文件 */ if ((fp = pcap_open(source, // 设备名 65536, // 要捕捉的数据包的部分 // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 1000, // 读取超时时间 NULL, // 远程机器验证 errbuf // 错误缓冲池 )) == NULL) { fprintf(stderr, "\nUnable to open the file %s.\n", source); return -1; } // 读取并解析数据包,直到EOF为真 pcap_loop(fp, 0, dispatcher_handler, NULL); return 0; } void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data) { u_int i = 0; /* 打印pkt时间戳和pkt长度 */ printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); /* 打印数据包 */ for (i = 1; (i < header->caplen + 1); i++) { printf("%.2x ", pkt_data[i - 1]); if ((i % LINE_LEN) == 0) printf("\n"); } printf("\n\n"); }
下面的程序同样实现了如上功能,只是,我们使用了 pcap_next_ex() 函数来代替需要进行回调的 pcap_loop() :
#include <stdio.h> #include <pcap.h> #define LINE_LEN 16 main(int argc, char **argv) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; char source[PCAP_BUF_SIZE]; struct pcap_pkthdr *header; const u_char *pkt_data; u_int i=0; int res; if(argc != 2) { printf("usage: %s filename", argv[0]); return -1; } /* 根据新WinPcap语法创建一个源字符串 */ if ( pcap_createsrcstr( source, // 源字符串 PCAP_SRC_FILE, // 我们要打开的文件 NULL, // 远程主机 NULL, // 远程主机端口 argv[1], // 我们要打开的文件名 errbuf // 错误缓冲区 ) != 0) { fprintf(stderr,"\nError creating a source string\n"); return -1; } /* 打开捕获文件 */ if ( (fp= pcap_open(source, // 设备名 65536, // 要捕捉的数据包的部分 // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容 PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式 1000, // 读取超时时间 NULL, // 远程机器验证 errbuf // 错误缓冲池 ) ) == NULL) { fprintf(stderr,"\nUnable to open the file %s.\n", source); return -1; } /* 从文件获取数据包 */ while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0) { /* 打印pkt时间戳和pkt长度 */ printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len); /* 打印数据包 */ for (i=1; (i < header->caplen + 1 ) ; i++) { printf("%.2x ", pkt_data[i-1]); if ( (i % LINE_LEN) == 0) printf("\n"); } printf("\n\n"); } if (res == -1) { printf("Error reading the packets: %s\n", pcap_geterr(fp)); } return 0; }