From owner-freebsd-hackers Mon Oct 16 13:26:21 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from rm-rstar.sfu.ca (rm-rstar.sfu.ca [142.58.120.21]) by hub.freebsd.org (Postfix) with ESMTP id ADEF037B66C for ; Mon, 16 Oct 2000 13:26:17 -0700 (PDT) Received: from fraser.sfu.ca (vanepp@fraser.sfu.ca [142.58.101.25]) by rm-rstar.sfu.ca (8.10.1/8.10.1/SFU-5.0H) with ESMTP id e9GKQBF05802 for ; Mon, 16 Oct 2000 13:26:11 -0700 (PDT) From: Peter Van Epp Received: (from vanepp@localhost) by fraser.sfu.ca (8.9.2/8.9.2/SFU-5.0C) id NAA01828 for freebsd-hackers@freebsd.org; Mon, 16 Oct 2000 13:26:10 -0700 (PDT) Message-Id: <200010162026.NAA01828@fraser.sfu.ca> Subject: bpf.c select fix for review To: freebsd-hackers@freebsd.org Date: Mon, 16 Oct 2000 13:26:10 -0700 (PDT) X-Mailer: ELM [version 2.5 PL3] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG While working on the new argus version I discovered that there is a bug in the /sys/net/bpf.c code if you are doing select with a timeout (which tcpdump isn't). Basically if you set up tcpreplay on another machine and send a less than full buffer (9 packets 2300 bytes in my case) to a FreeBSD 4.1 RELEASE machine, argus won't see the packets. It turns out that because it is using select (and not immediate mode) the partially full buffer won't get passed up to libpcap. The OpenBSD folks have a partial fix (which only gets the first packet up and leaves the other 8 dangling). I ported that to FreeBSD and then made a fix which appears to work based on what their code looked to be trying to do (as opposed to what it does which is incorrect). Basically at receive packet time the tick counter is stored in a variable in the capture structure. When the select/poll timeout occurs it checks if the current tick time is > then the last received packet count + the timeout value. If so it rotates the (partially full) packet buffer and signals to wake up the process. While this appears to work (and match the Solaris behavior on the same file) I figured I'd see if anyone sees a glaring hole in the fix before submitting a bug report on it. Peter Van Epp / Operations and Technical Support Simon Fraser University, Burnaby, B.C. Canada *** /sys/net/bpf.c.orig Sat Oct 14 19:00:59 2000 --- /sys/net/bpf.c Mon Oct 16 09:30:24 2000 *************** *** 1054,1061 **** if (events & (POLLIN | POLLRDNORM)) { if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) revents |= events & (POLLIN | POLLRDNORM); ! else ! selrecord(p, &d->bd_sel); } splx(s); return (revents); --- 1054,1076 ---- if (events & (POLLIN | POLLRDNORM)) { if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0)) revents |= events & (POLLIN | POLLRDNORM); ! else { ! /* ! * If there is a timeout and no data in the hold buffer ! * see if there has been data in the capture buffer ! * for more than a timeout interval. If so rotate the ! * buffer to push the packets to the user. ! */ ! if ((d->bd_slen != 0) && (d->bd_hlen == 0)) { ! if ((d->bd_rtout != -1) && ! (d->bd_rdStart + d->bd_rtout) > ticks) { ! ROTATE_BUFFERS(d); ! revents |= events & (POLLIN | POLLRDNORM); ! } ! } else ! selrecord(p, &d->bd_sel); ! ! } } splx(s); return (revents); *************** *** 1219,1224 **** --- 1234,1245 ---- */ (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen)); d->bd_slen = curlen + totlen; + + /* + * Mark the time the last packet was seen for poll timeout processing. + */ + + d->bd_rdStart = ticks; } /* *** /sys/net/bpfdesc.h.orig Sat Oct 14 19:16:07 2000 --- /sys/net/bpfdesc.h Sat Oct 14 19:21:54 2000 *************** *** 69,74 **** --- 69,75 ---- struct bpf_if * bd_bif; /* interface descriptor */ u_long bd_rtout; /* Read timeout in 'ticks' */ + u_long bd_rdStart; /* when the read started */ struct bpf_insn *bd_filter; /* filter code */ u_long bd_rcount; /* number of packets received */ u_long bd_dcount; /* number of packets dropped */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message