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>
