Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Nov 1997 11:54:07 -0800 (PST)
From:      Joel.Faedi@esial.u-nancy.fr
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   bin/5139: portmap does not find interfaces correctly
Message-ID:  <199711241954.LAA28861@hub.freebsd.org>
Resent-Message-ID: <199711242000.MAA29369@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         5139
>Category:       bin
>Synopsis:       portmap does not find interfaces correctly
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 24 12:00:00 PST 1997
>Last-Modified:
>Originator:     Joel Faedi
>Organization:
ESIAL - Nancy (France)
>Release:        2.2.5 and 3.0-971123-SNAP
>Environment:
FreeBSD meduse.scinfo.u-nancy.fr 2.2.5-RELEASE FreeBSD 2.2.5-RELEASE #15: Tue Nov 18 09:40:12 CET 1997     faedi@meduse.scinfo.u-nancy.fr:/usr/src/sys/compile/MEDUSE  i386
>Description:
when some (the first in the list obtained from SIOCGIFCONF ioctl call) ethernet interfaces are down or have no inet address, future register to portmapper (mountd, nfsd,...) will fail.
>How-To-Repeat:
Put more than one ethernet card in your PC and affect (with ifconfig)
an inet address only to the 2nd detected ethernet card , start portmap,
and try to start mountd. mountd will fail with no active IP address
found.
>Fix:
Fix code of "find_local" function in /usr/src/usr.sbin/portmap/
from_local.c: you can use the code of a similar function in bind
(named). Here is the new code for find_local() (for 2.2.5 and 3.0)
which will fix this problem and correct a potential problem: a inet
address may have more than one entry in the "addrs" array.

=================================================================
/* find_local - find all IP addresses for this host */

int
find_local()
{
    int sock, n, i, found;
    struct ifconf ifc;
    struct ifreq *ifr, *the_end, *ifnext;
    struct ifreq ibuf[MAX_LOCAL], ifreq;
    struct sockaddr_in *sin;

    /* Get list of network interfaces. */

    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	return (0);
    }
    ifc.ifc_len = sizeof ibuf ;
    ifc.ifc_buf = (caddr_t)ibuf;

    if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0 ||
	    ifc.ifc_len < sizeof(struct ifreq) ) {
	perror("SIOCGIFCONF");
	(void) close(sock);
	return (0);
    }

    /* Get IP address of each active IP network interface. */

    the_end = (struct ifreq *) ((char *)ibuf + ifc.ifc_len);
    num_local = 0;
    for (ifr = ibuf; ifr < the_end; ifr = ifnext) {
      
        n = ifr->ifr_addr.sa_len + sizeof(ifr->ifr_name);
        if (n < sizeof(*ifr))
	  ifnext = ifr + 1;
        else
	  ifnext = (struct ifreq *)((char *)ifr + n);

	if (ifr->ifr_addr.sa_family == AF_INET) {	/* IP net interface */
	    strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
	    if (ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
		perror("SIOCGIFFLAGS");
	    } else if (ifreq.ifr_flags & IFF_UP) {	/* active interface */
		if (ioctl(sock, SIOCGIFADDR, (char *) &ifreq) < 0) {
		    perror("SIOCGIFADDR");
		} else {
		    sin = (struct sockaddr_in *) & ifreq.ifr_addr;

		    /* due to "alias" addresses, an interface may
		     * appear more than once, with the same IP address
		     */
		    for (found = 0, i = 0; i < num_local && !found; i++)
		      found = (memcmp((char *) &(sin->sin_addr), 
				      (char *) &(addrs[i]),
				      sizeof(struct in_addr)) == 0);
		    if (!found)
		      addrs[num_local++] = sin->sin_addr;
		}
	    }
	}
	if (num_local >= MAX_LOCAL)
	    break;
    }
    (void) close(sock);
    return (num_local);
}


>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711241954.LAA28861>