WinPcap下的主要结构体和主要函数.docx
《WinPcap下的主要结构体和主要函数.docx》由会员分享,可在线阅读,更多相关《WinPcap下的主要结构体和主要函数.docx(9页珍藏版)》请在冰豆网上搜索。
WinPcap下的主要结构体和主要函数
WinPCap中的主要结构体:
1.structpcap_if_t(称为网络设备结构,表示一个网络接口设备(如网卡)) 结构体包含以下5个域(其结构体与pcap_if相同,可以用pcap_if_t代替pcap_if):
structpcap_if{
structpcap_if*next;
char*name;/*nametohandto"pcap_open_live()"*/
char*description;/*textualdescriptionofinterface,orNULL*/
structpcap_addr*addresses;
bpf_u_int32flags;/*PCAP_IF_interfaceflags*/
};
Structpcap_addr:
Representationofaninterfaceaddress (表示接口地址)
Structpcap_addr
{
structpcap_addr* next:
ifnotNULL,apointertothenextelementinthelist; NULLforthelastelementofthelist(指向下一个元素的指针)c:
\iknow\docshare\data\WpdPack\docs\html\structpcap__addr.html-b151e8e96bdb23ae8dd8d644de561999
structsockaddr* addr apointertoastructsockaddrcontaininganaddressc:
\iknow\docshare\data\WpdPack\docs\html\structpcap__addr.html-4863f5b8767cd19fe6ea4db75456e5df
structsockaddr* netmask ifnotNULL,apointertoastructsockaddrthatcontainsthenetmaskcorrespondingtotheaddresspointedtobyaddr.c:
\iknow\docshare\data\WpdPack\docs\html\structpcap__addr.html-c43963e42e4d901e55e433ab9c3ea686
structsockaddr* broadaddr ifnotNULL,apointertoastructsockaddrthatcontainsthebroadcastaddresscorre�spondingtotheaddresspointedtobyaddr;maybenulliftheinterfacedoesn'tsupportbroadcastsc:
\iknow\docshare\data\WpdPack\docs\html\structpcap__addr.html-0077647e1560caa72d457120b36c248c
structsockaddr* dstaddr ifnotNULL,apointertoastructsockaddrthatcontainsthedestinationaddresscorre�spondingtotheaddresspointedtobyaddr;maybenulliftheinterfaceisn'tapoint-to-pointinterface
}
2.pcap_if
Iteminalistofinterfaces,usedbypcap_findalldevs().
(接口设备列表的一项(一个设备,比如一个网卡))
Definitionatline148offileincs/pcap.h.
Structpcap_if
{
structpcap_if*next
ifnotNULL,apointertothenextelementinthelist;NULLforthelastelementofthelist
char*name
apointertoastringgivinganameforthedevicetopasstopcap_open_live()
char*description
ifnotNULL,apointertoastringgivingahuman-readabledescriptionofthedevice
structpcap_addr*addresses
apointertothefirstelementofalistofaddressesfortheinterface
u_intflags
PCAP_IF_interfaceflags.CurrentlytheonlypossibleflagisPCAP_IF_LOOPBACK,thatissetiftheinterfaceisaloopbackinterface.
}
2.结构体pcap_t
Descriptorofanopencaptureinstance.Thisstructureisopaquetotheuser,thathandlesitscontentthroughthefunctionsprovidedbywpcap.dll.(该结构体描述一个捕获的实例(例如指向一个发现的网卡,称为网卡描述符),其结构体在.h文件中看不到)
3.结构体pcap_pkthdr //Headerofapacketinthedumpfile.
Eachpacketinthedumpfileisprependedwiththisgenericheader.
(每一个分组都有不同的头部,分组的头部用该结构体表示)
structpcap_pkthdr{
structtimevalts;
bpf_u_int32caplen;
bpf_u_int32len;
}
ts:
时间戳
cpalen:
当前分组的长度
len:
数据包的长度
5.结构体 sockaddr_in
一般编程中使用,它与sockaddr等价的数据结构
sockaddr_in(在Winsock2.h中定义):
struct sockaddr_in{
};
typedefstructin_addr{
union{
struct{
unsignedchars_b1,
s_b2,
s_b3,
s_b4;
}S_un_b;
struct{
unsignedshorts_w1,
s_w2;
}S_un_w;
unsignedlongS_addr;
}S_un;
}IN_ADDR;
sin_family指代协议族,在socket编程中只能是AF_INET
sin_port存储端口号(使用网络字节顺序)
sin_addr存储IP地址,使用in_addr这个数据结构
sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
s_addr按照网络字节顺序存储IP地址
sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向sockadd的结构体,并代替它。
也就是说,你可以使用sockaddr_in建立你所需要的信息,
在最后用进行类型转换就可以了bzero((char*)&mysock,sizeof(mysock));//初始化
mysock结构体名
mysock.sa_family=AF_INET;
mysock.sin_addr.S_un.S_addr=inet_addr("192.168.0.1");
……
等到要做转换的时候用:
(structsockaddr*)mysock
例子:
获得子网掩码
pcap_if_t*d;
netmask=((sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;
例子2:
Socketaddr_in InternetAddr;
intnPortId=5150;
InternetAddr.sin_family=AF_INET;
InternetAddr.sin_addr.s_addr=inet_addr("198.198.10.216");
InternetAddr.sin_port=htonl(nPortId);
WinPcap下的主要函数:
1.intpcap_findalldevs(pcap_if_t**alldevsp,
char*errbuf
)//获取设备列表,以供函数pcap_open_live()打开这些设备
Constructalistofnetworkdevicesthatcanbeopenedwithpcap_open_live().
Note:
thattheremaybenetworkdevicesthatcannotbeopenedwithpcap_open_live()bytheprocesscallingpcap_findalldevs(),because,forexample,thatprocessmightnothavesufficientprivilegestoopenthemforcapturing;ifso,thosedeviceswillnotappearonthelist.
alldevspissettopointtothefirstelementofthelist;eachelementofthelistisoftypepcap_if_t,
-1isreturnedonfailure,inwhichcaseerrbufisfilledinwithanappropriateerrormessage;0isreturnedonsuccess.
2.voidpcap_freealldevs(pcap_if_t*alldevsp)
释放由函数pcap_findalldevs()获取的设备列表
Freeaninterfacelistreturnedbypcap_findalldevs().
pcap_freealldevs()isusedtofreealistallocatedbypcap_findalldevs().
Seealso:
pcap_findalldevs()
3.pcap_t*pcap_open_live(
constchar*device,//要打开的网络设施,
intsnaplen,//捕捉的分组最大长度,单位Byte
intpromisc,//是否为混杂模式,1为混杂模式
intto_ms,//readtime_out给予阅读分组的最大时间,单位ms
char*ebuf
)
Device(Source):
为打开的网络设施,是包含要打开的源名称的以’\0’结尾的字符串。
源名称得包含新的源规范语法(SourceSpecificationSyntax),并且它不能为NULL。
为了方便的使用源语法,
snaplen:
需要保留的数据包的长度。
对每一个过滤器接收到的数据包,第一个‘snaplen’字节的内容将被保存到缓冲区,并且传递给用户程序。
例如,snaplen等于100,那么仅仅每一个数据包的第一个100字节的内容被保存。
简言之就是从每一个包的开头到snaplen的那段内容将被保存。
flags:
保存一些由于抓包需要的标志。
Winpcap定义了三种标志:
● PCAP_OPENFLAG_PROMISCUOUS:
1,它定义了适配器(网卡)是否进入混杂模式(promiscuousmode)。
● PCAP_OPENFLAG_DATATX_UDP:
2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。
● PCAP_OPENFLAG_NOCAPTURE_RPCAP:
4,它定义了远程探测器是否捕获它自己产生的数据包。
read_timeout:
以毫秒为单位。
readtimeout被用来设置在遇到一个数据包的时候读操作不必立即返回,而是等待一段时间,让更多的数据包到来后从OS内核一次读多个数据包。
auth:
一个指向’structpcap_rmtauth’的指针,保存当一个用户登录到某个远程机器上时的必要信息。
假如不是远程抓包,该指针被设置为NULL。
(本地抓包不需要该参数)
errbuf:
一个指向用户申请的缓冲区的指针,存放当该函数出错时的错误信息。
函数的返回值:
该函数正常情况下,返回值是一个’pcap_t’(网卡描述符),它可以作为下一步其他函数调用该网卡的参数(例如,ppcap_compile()等)的参数。
在遇到问题的情况下,该函数返回NULL并且’errbuf’变量保存了错误信息。
Openalivecapturefromthenetwork.
pcap_open_live()isusedtoobtainapacketcapturedescriptortolookatpacketsonthenetwork.
deviceisastringthatspecifiesthenetworkdevicetoopen;onLinuxsystemswith2.2orlaterkernels,adeviceargumentof"any"orNULLcanbeusedtocapturepacketsfromallinterfaces.
snaplenspecifiesthemaximumnumberofbytestocapture.Ifthisvalueislessthanthesizeofapacketthatiscaptured,onlythefirstsnaplenbytesofthatpacketwillbecapturedandprovidedaspacketdata.Avalueof65535shouldbesufficient,onmostifnotallnetworks,tocaptureallthedataavailablefromthepacket.
promiscspecifiesiftheinterfaceistobeputintopromiscuousmode.(Notethatevenifthisparameterisfalse,theinterfacecouldwellbeinpromiscuousmodeforsomeotherreason.)Fornow,thisdoesn'tworkonthe"any"device;ifanargumentof"any"orNULLissupplied,thepromiscflagisignored.
to_msspecifiesthereadtimeoutinmilliseconds.Thereadtimeoutisusedtoarrangethatthereadnotnecessarilyreturnimmediatelywhenapacketisseen,butthatitwaitforsomeamountoftimetoallowmorepacketstoarriveandtoreadmultiplepacketsfromtheOSkernelinoneoperation.Notallplatformssupportareadtimeout;onplatformsthatdon't,thereadtimeoutisignored.Azerovalueforto_ms,onplatformsthatsupportareadtimeout,willcauseareadtowaitforevertoallowenoughpacketstoarrive,withnotimeout.
errbufisusedtoreturnerrororwarningtext.Itwillbesettoerrortextwhenpcap_open_live()failsandreturnsNULL.errbufmayalsobesettowarningtextwhenpcap_open_live()succeds;todetectthiscasethecallershouldstoreazero-lengthstringinerrbufbeforecallingpcap_open_live()anddisplaythewarningtotheuseriferrbufisnolongerazero-lengthstring.
Seealso:
pcap_open_offline(),pcap_open_dead(),pcap_findalldevs(),pcap_close()
4.intpcap_datalink(pcap_t*p)
返回链路层的类型,链路层的类型包括:
● DLT_NULL:
BSD回路封装;链路层协议头是一个4字节的域,以主机字节顺序(hostbyteorder),包含一个从socket.h来的PF_value。
主机字节顺序(hostbyteorder)是捕获数据包的机器的字节顺序,而PF_value是捕获数据包的机器的OS。
如果一个读取一个文件,字节顺序和PF_value不一定是抓取文件的那些机器。
● DLT_EN10MB:
以太网(10Mb,100Mb,1000Mb,或者更高)。
● DLT_IEEE802:
IEEE802.5令牌环网。
● DLT_ARCNET:
ARCNET。
● DLT_SLIP:
SLIP。
● DLT_PPP:
PPP;如果第一个字节是0xff或0x03,它是类HDLC帧上的PPP。
● DLT_FDDI:
FDDI
● DLT_ATM_RFC1483:
RFC1483LLC/SNAPATM;数据包以IEEE802.2LLC头开始。
● DLT_RAW:
原始IP(rawIP);数据包以IP头开始。
● DLT_PPP_SERIAL:
按照RFC1662,基于类HDLC帧的PPP,或者按照RFC1547的4.3.1,基于HDLC帧的CiscoPPP;前者的第一个字节是0xFF,后者的第一个字节是0x0F或0x8F。
● DLT_PPP_ETHER:
按照RFC2516,PPPoE;数据包以PPPoE头开始。
● DLT_C_HDLC:
按照RFC1547的4.3.1,基于HDLC帧的CiscoPPP。
● DLT_IEEE802_11:
IEEE802.11无线局域网。
● DLT_FRELAY:
帧中继(FrameRelay)。
● DLT_LOOP:
OpenBSD回路封装。
● DLT_LINUX_SLL:
Linux抓包封装。
● DLT_LTALK:
苹果的LocalTalk,数据包以AppleTalkLLAP头开始。
● DLT_PFLOG:
OpenBSDpflog。
● DLT_PRISM_HEADER:
后接802.11头的棱镜监视器模式(Prismmonitormode)信息。
● DLT_IP_OVER_FC:
RFC2625IP-over-Fiber频道,以RFC2625中定义的Network_Header开始。
● DLT_SUNATM:
SunATM设备。
● DLT_IEEE802_11_RADIO:
后接802.11头的链路层信息。
● DLT_ARCNET_LINUX:
没有异常帧的ARCNET。
● DLT_LINUX_IRDA:
Linux-IrDA数据包,DLT_LINUX_SLL头后接IrLAP头
5.intpcap_compile(pcap_t*p,
structbpf_program*fp,
char*str,
intoptimize,
bpf_u_int32netmask
)//翻译分组过滤器
简单的说:
pcap_complie()将程序中的字符串str集成到(翻译到)数据包驱动中的低级字节码fp。
Str->fp(内核认识的格式)
编译一个数据包过滤器,将一个能被核心态(kernel-level)过滤器引擎解释的程序中的高层过滤表达式(filteringexpression)进行转化。
pcap_compile(