12.3 数据包文件存储的幕后

数据包文件存储的主要函数调用关系如图12-8所示。

12.3 数据包文件存储的幕后 - 图1

图 12-8 数据包文件存储的主要函数调用关系

12.3.1 pcap_dump_open函数

pcap_dump_open函数用于打开一个文件并写入数据包,其原型如下:


pcap_dumper_tpcap_dump_open(pcap_tp,const char*fname)


上述函数中,参数fname为需要打开的用来存储数据包的savefile文件名,-等同于stdout文件;参数p是调用pcap_open_offline或pcap_open_live函数返回的一个pcap结构体。

如果函数pcap_dump_open执行失败则返回NULL。

该函数的具体代码实现如下:


pcap_dumper_tpcap_dump_open(pcap_tp,const char*fname)

{

FILE*f;

int linktype;

/检测数据链路层的类型/

linktype=dlt_to_linktype(p->linktype);

if(linktype==-1){

//数据链路层类型不支持文件转储

return(NULL);

}

linktype|=p->linktype_ext;

/打开转储文件/

if(fname[0]=='-'&&fname[1]=='\0'){

f=stdout;

fname="standard output";

}else{

f=fopen(fname,"wb");

if(f==NULL){

//打开转储文件失败

return(NULL);

}

}

/存储转储文件的头信息/

return(pcap_setup_dump(p,linktype,f,fname));

}


上述代码中,pcap_setup_dump函数主要通过调用sf_write_header函数来设置转储文件的头信息,具体实现代码如下:


static pcap_dumper_tpcap_setup_dump(pcap_tp,int linktype,

FILEf,const charfname)

{

if defned(WIN32)||defned(MSDOS)

if(f==stdout)

SET_BINMODE(f);

else

setbuf(f,NULL);//把文件设置为非缓冲的

endif

/写文件头信息/

if(sf_write_header(f,linktype,p->tzoff,p->snapshot)==-1)

{//写文件失败

……

return(NULL);

}

return((pcap_dumper_t*)f);

}


上述代码中,sf_write_header函数主要是调用fwrite把文件头信息写入转储文件中的。该函数的具体实现代码如下:


static int sf_write_header(FILE*fp,int linktype,int thiszone,int snaplen)

{

struct pcap_fle_header hdr;

hdr.magic=TCPDUMP_MAGIC;

hdr.version_major=PCAP_VERSION_MAJOR;

hdr.version_minor=PCAP_VERSION_MINOR;

hdr.thiszone=thiszone;

hdr.snaplen=snaplen;

hdr.sigfgs=0;

hdr.linktype=linktype;

if(fwrite((char*)&hdr,sizeof(hdr),1,fp)!=1)

return(-1);

return(0);

}