When compiling a program which listens to a network device via the pcap-library with -pthread, it stops working in the pcap_loop() bits. Fix: none known. How-To-Repeat: #include <pcap.h> #include <net/bpf.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <sys/ioctl.h> pcap_t *pd = NULL; char *dev = "fxp0"; int link_offset; int link_type; int snaplen = 65535, promisc = 1, to = 1000; char pc_err[PCAP_ERRBUF_SIZE]; void networkinit(void) { if ((pd = pcap_open_live(dev, snaplen, promisc, to, pc_err)) == NULL) { perror(pc_err); exit(-1); } } void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) { fprintf(stderr,"."); } void networkrun(void) { while (pcap_loop(pd, 0, (pcap_handler)process, 0)); exit(-2); } int main(void) { networkinit(); networkrun(); } (You might have to tweak the fxp0 in the dev-variable) Compile as "gcc -Wall -o nw nw.c -lpcap". It will print a dot for every IP packet. Compile as "gcc -Wall -o nw nw.c -lpcap -pthread". It will print nothing.
Some minor further investigations in libpcap showed that the read() function in /usr/src/contrib/libpcap/pcap-bpf.c:81 looks like it's blocking until the buffer is fully filled: if (p->cc == 0) { + fprintf(stderr,"pcap_read before read (bufsize: %d bytes)\n",p->bufsize); cc = read(p->fd, (char *)p->buffer, p->bufsize); + fprintf(stderr,"pcap_read after read (read: %d bytes)\n",cc); if (cc < 0) { This is the effect on a version without -pthread: [~/bpf] edwin@friet44>./nw_u pcap_read entered pcap_read before read (bufsize: 32768 bytes) pcap_read after read (read: 244 bytes) ..pcap_read entered pcap_read before read (bufsize: 32768 bytes) pcap_read after read (read: 276 bytes) ..pcap_read entered This is the effect on a version with -pthread: [~/bpf] edwin@friet44>./nw pcap_read entered pcap_read before read bufsize: (32768 bytes) pcap_read after read (read: 32232 bytes) ...........................................................pcap_read entered pcap_read before read (bufsize: 32768 bytes) pcap_read after read (read: 32160 bytes) .........................................................pcap_read entered pcap_read before read (bufsize: 32768 bytes) pcap_read after read (read: 31648 bytes) I have no idea how to solve this... Edwin -- Edwin Groothuis | Personal website: http://www.MavEtJu.org edwin@mavetju.org | Interested in MUDs? Visit Fatal Dimensions: ------------------+ http://www.FatalDimensions.org/
I've tried the solution as suggested on: http://archives.neohapsis.com/archives/openbsd/2001-03/0857.html At least the threading works with it, but the data is still coming in a burst instead of on a per-packet base like in a normal unthreaded environment. Edwin -- Edwin Groothuis | Personal website: http://www.MavEtJu.org edwin@mavetju.org | Interested in MUDs? Visit Fatal Dimensions: ------------------+ http://www.FatalDimensions.org/
In essence, this is the same problem as identified in PR 22063. If no one objects, I'll close this in a couple of days. I have submitted a patch to PR 22063 that solves this problem in the kernel code. Guy
State Changed From-To: open->closed Fixed in sys/net/bpf.c revision 1.59.2.8 and sys/net/bpfdesc.h revision 1.14.2.2.