关于wpcap的数据包问题(很简单)
只问一个问题:
pcap_loop(fp, 0, ProcessPacket, NULL)将数据包转给ProcessPacket
void ProcessPacket(u_char * ufp, const struct pcap_pkthdr * pkthdr, const u_char *pkt)
我想请问每次转过来的包指针是不是指的同一个地址?也就是说并不是每次生成一个新包,而是将老包重新写过?
我其实知道这个问题的答案,就是每次传过来的是一个新包地址,因为我用一个进程队列读出来上百个包,每个包的内容是不一样的,也就是说指针指的包是不同的。但我读winpcap的源代码,只在pcap_open_live里有新建一个空间的过程,如下:
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
register pcap_t *p;
NetType type;
DWORD error;
char errbuf[PCAP_ERRBUF_SIZE+1];
int errlen;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
p->adapter=NULL;
p->adapter=PacketOpenAdapter(device);
if (p->adapter==NULL) {
error = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,0,errbuf,PCAP_ERRBUF_SIZE,NULL);
/*
* "FormatMessage()" "helpfully" sticks CR/LF at the end of
* the message. Get rid of it.
*/
errlen = strlen(errbuf);
if (errlen >= 2) {
errbuf[errlen - 1] = '\0';
errbuf[errlen - 2] = '\0';
}
sprintf(ebuf, "Error opening adapter: %s", errbuf);
return NULL;
}
/*get network type*/
if(PacketGetNetType (p->adapter,&type)==FALSE)
{
sprintf(ebuf, "Cannot determine the network type");
goto bad;
}
/*Set the linktype*/
switch (type.LinkType) {
。。。
default: p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
}
/* Set promisquous mode */
if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS);
else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL);
/* Leave room for link header */
p->bufsize = PcapBufSize;
p->buffer = (u_char *)malloc(PcapBufSize);
if (p->buffer == NULL) {
sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* allocate packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL){
sprintf(ebuf, "failed to allocate the PACKET structure");
goto bad;
}
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
/* allocate the standard buffer in the driver */
if(PacketSetBuff(p->adapter,SIZE_BUF)==FALSE)
{
sprintf(ebuf,"driver error: not enough memory to allocate the buffer\n");
goto bad;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{
sprintf(ebuf,"driver error: not enough memory to allocate the buffer\n");
goto bad;
}
PacketSetReadTimeout(p->adapter,to_ms);
return (p);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
free(p->buffer);
free(p);
return (NULL);
}
但在pcap_read里没有新建包的过程。
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
int n = 0;
register u_char *bp, *ep;
cc = p->cc;
if (p->cc == 0) {
/* capture the packets */
if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
sprintf(p->errbuf, "read error: PacketReceivePacket failed");
return (-1);
}
cc = p->Packet->ulBytesReceived;
bp = p->Packet->Buffer;
}
else
bp = p->bp;
/*
* Loop through each packet.
*/
#define bhp ((struct bpf_hdr *)bp)
ep = bp + cc;
while (bp < ep) {
register int caplen, hdrlen;
caplen = bhp->bh_caplen;
hdrlen = bhp->bh_hdrlen;
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
bp += BPF_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
#undef bhp
p->cc = 0;
return (n);
}
从某种考虑上讲,也就是没有新建包,那我每次为什么能读到不同的包呢?