summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-01-29 06:00:11 +0000
committermarcel <marcel@FreeBSD.org>2002-01-29 06:00:11 +0000
commit5a61ac7f11300abf6cc2bcb39c2a0aa5964177ed (patch)
treed796ca170c5bf7d635c8f426413adcf51bb11d21 /sys
parent358efcfdcf2fdf9bb0177364a132eaf0e094ebac (diff)
downloadFreeBSD-src-5a61ac7f11300abf6cc2bcb39c2a0aa5964177ed.zip
FreeBSD-src-5a61ac7f11300abf6cc2bcb39c2a0aa5964177ed.tar.gz
Have SIOCGIFCONF return all (if any) AF_INET addresses for the
interfaces we encounter. In Linux, all addresses are returned for which gifconf handlers are installed. This boils down to AF_DECnet and AF_INET. We care mostly about AF_INET for now. Adding additional families is simple enough. Returning the addresses is important for RPC clients to function properly. Andrew found in some reference code that the logic that handles the retransmission looks for an interface that's up and has an AF_INET address. This obviously failed as we didn't return any addresses at all. Note also that with this change we don't return interfaces that don't have AF_INET addresses, whereas before we returned any interface present in the system. This is in line with what Linux does (modulo interfaces with only AF_DECnet addresses of course :-) Reported by: "Andrew Atrens" <atrens@nortelnetworks.com> MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/linux/linux_ioctl.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 4e72f85..ec96415 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -1896,6 +1896,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
struct ifconf ifc;
struct l_ifreq ifr;
struct ifnet *ifp;
+ struct ifaddr *ifa;
struct iovec iov;
struct uio uio;
int error, ethno;
@@ -1918,10 +1919,11 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
/* Keep track of eth interfaces */
ethno = 0;
- /* return interface names but no addresses. */
+ /* Return all AF_INET addresses of all interfaces */
TAILQ_FOREACH(ifp, &ifnet, if_link) {
if (uio.uio_resid <= 0)
break;
+
bzero(&ifr, sizeof ifr);
if (IFP_IS_ETH(ifp))
snprintf(ifr.ifr_name, LINUX_IFNAMSIZ, "eth%d",
@@ -1929,9 +1931,25 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
else
snprintf(ifr.ifr_name, LINUX_IFNAMSIZ, "%s%d",
ifp->if_name, ifp->if_unit);
- error = uiomove((caddr_t)&ifr, sizeof ifr, &uio);
- if (error != 0)
- return (error);
+
+ /* Walk the address list */
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ struct sockaddr *sa = ifa->ifa_addr;
+
+ if (uio.uio_resid <= 0)
+ break;
+
+ if (sa->sa_family == AF_INET) {
+ ifr.ifr_addr.sa_family = LINUX_AF_INET;
+ memcpy(ifr.ifr_addr.sa_data, sa->sa_data,
+ sizeof(ifr.ifr_addr.sa_data));
+
+ error = uiomove((caddr_t)&ifr, sizeof ifr,
+ &uio);
+ if (error != 0)
+ return (error);
+ }
+ }
}
ifc.ifc_len -= uio.uio_resid;
OpenPOWER on IntegriCloud