Subject: bin/2106: netbsd1.1 rarpd opens too many bpfs
To: None <gnats-bugs@NetBSD.ORG>
From: Andrew Brown <codewarrior@daemon.org>
List: netbsd-bugs
Date: 02/21/1996 13:03:21
>Number:         2106
>Category:       bin
>Synopsis:       netbsd1.1 rarpd opens too many bpfs
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Feb 21 13:50:02 1996
>Last-Modified:
>Originator:     Andrew Brown
>Organization:
Coding Dynamics
>Release:        rarpd.c,v 1.8 1995/09/01 21:55:47
>Environment:
i386 netbsd 1.1
	
System: NetBSD hypo.webbed.com 1.1 NetBSD 1.1 (WEBBED-MULTI) #7: Sat Jan 27 16:38:35 EST 1996 battlej@hypo.webbed.com:/usr/src/sys/arch/i386/compile/WEBBED-MULTI i386


>Description:
   rarpd, when started in "all interfaces" mode, opens up each bpf device in
turn and attaches them to the network interfaces.  but it opens too many
since the SIOCGIFCONF ioctl returns each interface once for each address that
it has whether these are hardware addresses or ip addresses.  for interface
that is "up" this will be at least two (one more for each inet alias you put
on the interface).  on my netbsd box that has two interfaces this was four
opens which was all the bpfs  had built into my kernel.  when i added an ip
alias to one interface, rarpd could no longer restarted after boot time.

>How-To-Repeat:
   run rarpd -ad on any machine with an interface that is up and notice how
many times it mentions each hardware address.

>Fix:
   minor code hackage :).  add the interface name to the struct that records
each interface when opened, have init_one check this list each time it is
called from init_all, and after deciding to open a bpf, have it store the name
in the struct.  here's my patch:

***************
*** 67,72 ****
--- 67,73 ----
   */
  struct if_info {
        int     ii_fd;          /* BPF file descriptor */
+       char    ii_name[IFNAMSIZ];      /* if name, e.g. "en0" */
        u_char  ii_eaddr[6];    /* Ethernet address of this interface */
        u_long  ii_ipaddr;      /* IP address of this interface */
        u_long  ii_netmask;     /* subnet or net mask */
***************
*** 193,198 ****
--- 194,204 ----
  {
        struct if_info *p;
  
+       /* first check to see if this "if" was already opened? */
+       for(p = iflist; p; p = p->ii_next)
+               if (!strncmp(p->ii_name, ifname, IFNAMSIZ))
+                       return;
+ 
        p = (struct if_info *)malloc(sizeof(*p));
        if (p == 0) {
                err(FATAL, "malloc: %s", strerror(errno));
***************
*** 202,207 ****
--- 208,214 ----
        iflist = p;
  
        p->ii_fd = rarp_open(ifname);
+       strncpy(p->ii_name, ifname, IFNAMSIZ);
        lookup_eaddr(ifname, p->ii_eaddr);
        lookup_ipaddr(ifname, &p->ii_ipaddr, &p->ii_netmask);
  }
>Audit-Trail:
>Unformatted: