关于wpcap的数据包问题(很简单)

tuiger2003 2003-07-06 04:07:09
只问一个问题:

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);
}
从某种考虑上讲,也就是没有新建包,那我每次为什么能读到不同的包呢?
...全文
205 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
DeadWolf 2003-07-08
  • 打赏
  • 举报
回复
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
bp += BPF_WORDALIGN(caplen + hdrlen);

每次循环后bp指向不同的地址,因此得到的就是处理不同的数据包
1> 捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据winpcap结构包;   2> 在数据包发往应用程序之前,按照自定义的规则将某些特殊的数据包过滤掉;   3> 在网络上发送原始的数据包;   4> 收集网络通信过程中的统计信息。   winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据包。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据包的发收,它仅仅只是监听共享网络上传送的数据包。因此,它不能用于QoS调度程序或个人防火墙。目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且M$也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫sniffer pro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码。它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件。还有一个简单的监听软件叫Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在HUB网络上。著名软件tcpdump及ids snort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。   winpcap提供给用户两个不同级别的编程接口:一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用wpcap.dll是当然的选择。
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。它提供了以下的各项功能:   1> 捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报;   2> 在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉;   3> 在网络上发送原始的数据报;   4> 收集网络通信过程中的统计信息。   winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报。也就是说,winpcap不能阻塞,过滤或控制其他应用程序数据报的发收,它仅仅只是监听共享网络上传送的数据报。因此,它不能用于QoS调度程序或个人防火墙。目前,winpcap开发的主要对象是windows NT/2000/XP,这主要是因为在使用winpcap的用户中只有一小部分是仅使用windows 95/98/Me,并且M$也已经放弃了对win9x的开发。因此本文相关的程序T-ARP也是面向NT/2000/XP用户的。其实winpcap中的面向9x系统的概念和NT系统的非常相似,只是在某些实现上有点差异,比如说9x只支持ANSI编码,而NT系统则提倡使用Unicode编码。有个软件叫sniffer pro.可以作网管软件用,有很多功能,可监视网络运行情况,每台网内机器的数据流量,实时反映每台机器所访问IP以及它们之间的数据流通情况,可以抓包,可对过滤器进行设置,以便只抓取想要的包,比如POP3包,smtp包,ftp包等,并可从中找到邮箱用户名和密码,还有ftp用户名和密码.它还可以在使用交换机的网络上监听,不过要在交换机上装它的一个软件.还有一个简单的监听软件叫 Passwordsniffer,可截获邮箱用户名和密码,还有ftp用户名和密码,它只能用在用HUB网络上著名软件tcpdump及ids snort都是基于libpcap编写的,此外Nmap扫描器也是基于libpcap来捕获目标主机返回的数据包的。   winpcap提供给用户两个不同级别的编程接口:一个基于libpcap的wpcap.dll,另一个是较底层的packet.dll。对于一般的要与unix平台上libpcap兼容的开发来说,使用pacap.dll是当然的选择。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧