aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linux/linux_ioctl.c
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2002-01-29 06:00:11 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2002-01-29 06:00:11 +0000
commit75387a278e2031449fb369d681edfed8de04ce27 (patch)
treed796ca170c5bf7d635c8f426413adcf51bb11d21 /sys/compat/linux/linux_ioctl.c
parent9fecc8d840dd88028a7f2cdd9a30689a2048b60d (diff)
downloadsrc-75387a278e2031449fb369d681edfed8de04ce27.tar.gz
src-75387a278e2031449fb369d681edfed8de04ce27.zip
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
Notes
Notes: svn path=/head/; revision=89944
Diffstat (limited to 'sys/compat/linux/linux_ioctl.c')
-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 4e72f85e4911..ec96415880e4 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;