Date: Fri, 10 Sep 1999 12:23:14 +0200 (SAT) From: Reinier Bezuidenhout <rbezuide@oskar.nanoteq.co.za> To: freebsd-hackers@freebsd.org Cc: freebsd-current@freebsd.org Subject: Endless loop in libpcap 2.2.x/3.x/-current Message-ID: <199909101023.MAA09680@oskar.nanoteq.co.za>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi ...
We are running a system where we use the libpcap to capture
packets from an ethernet device. We've been observing a problem where
the monitor program goes into an endless loop and spins for ever.
I've compiled the program with debugging on and observed that the
call-back function is called repeatedly from the libpcap library.
I examined the library and ended up in the pcap_read function in
pcap-bpf.c
The code follows
snip - snip - snip
round line 110 in 2.2.x and in -current
------------------
#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);
----------
In our case (from the debug info obtained from our program, I can see that
bhp->bh_caplen and bhp->bh_hdrlen are both zero (0).
(gdb) p *(struct bpf_hdr *)pkt
$11 = {bh_tstamp = {tv_sec = 16652, tv_usec = 0}, bh_caplen = 0,
bh_datalen = 33555200, bh_hdrlen = 0}
pkt is bp received back from libpcap.
cnt is -1 when we installed the callback function.
As can be seen ... caplen and hdrlen is then set to 0. bp is smaller
than ep because cc >0 (data was read)
It enters the while loop, set caplen, hdrlen to 0, calls the callback
function. libpcap then tries to increment bp with the BPF_WORDALIGN
macro.
From bpf.h
#define BPF_ALIGNMENT sizeof(long)
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
This concludes to
(gdb) p (((0)+(sizeof(long)-1))&~(sizeof(long)-1))
$12 = 0
so bp is NOT incremented and the whole process is repeated and here it
gets stuck in the loop.
I attached a possible fix for this, please review, edit as necessar and
commit :)
The patch is to -current file, put should apply to most other versions
too.
Thankyou
Reinier
[-- Attachment #2 --]
Index: pcap-bpf.c
===================================================================
RCS file: /home/freebsd-cvs/src/contrib/libpcap/pcap-bpf.c,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 pcap-bpf.c
*** pcap-bpf.c 1998/09/15 19:28:05 1.1.1.3
--- pcap-bpf.c 1999/09/10 10:11:49
***************
*** 117,122 ****
--- 117,130 ----
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
+ /*
+ * If we can't increment bp, get out of the while
+ * We've atleast called the callback with the data
+ * we have at out disposal - NB : it might be garbage
+ */
+ if (!BPF_WORDALIGN(caplen + hdrlen)) {
+ break;
+ }
bp += BPF_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909101023.MAA09680>
