NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/41367: pcap_lookupnet() returns wrong netmask



>Number:         41367
>Category:       lib
>Synopsis:       pcap_lookupnet() returns wrong netmask
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May 06 16:15:00 +0000 2009
>Originator:     Manuel Bouyer
>Release:        NetBSD 5.0
>Organization:
>Environment:
NetBSD netadmin.lip6.fr 5.0_RC2 NetBSD 5.0_RC2 (XEN3_DOMU) #0: Sat Mar 14 
16:24:22 UTC 2009  
builds%b1.netbsd.org@localhost:/home/builds/ab/netbsd-5/i386/200903140000Z-obj/home/builds/ab/netbsd-5/src/sys/arch/i386/compile/XEN3_DOMU
 i386
Architecture: i386
Machine: i386
(I confirmed the issue on amd64 5.0_RELEASE system)
>Description:
        I noticed that pkgsrc/net/arpwatch didn't work properly on a
        netbsd-5 machine. I tracked it down to pcap_lookupnet() returning
        the wrong netmask (255.255.255.<last byte of IP address> instead
        of 255.255.255.0). This seems to be because libpcap does't
        initialize the memory before calling SIOCGIFNETMASK and the
        kernel doesn't fill all 4 bytes of the sin_addr (only the
        significant bytes are copied it seems).

        Now I don't know if the bug is really in libpcap no zeroing
        out the memory before ioctl, or the kernel not copying the
        whole sin_addr (maybe both ?)
>How-To-Repeat:
        see above
>Fix:
        this patch fixes arpwatch for me:

Index: inet.c
===================================================================
RCS file: /cvsroot/src/dist/libpcap/inet.c,v
retrieving revision 1.2
diff -u -r1.2 inet.c
--- inet.c      27 Feb 2006 15:53:24 -0000      1.2
+++ inet.c      6 May 2009 15:36:47 -0000
@@ -573,6 +573,12 @@
        }
        sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
        *netp = sin4->sin_addr.s_addr;
+       memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+       /* XXX Work around Linux kernel bug */
+       ifr.ifr_addr.sa_family = AF_INET;
+#endif
+       (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
        if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
                (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
                    "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));



Home | Main Index | Thread Index | Old Index