diff options
| author | Marcel Moolenaar <marcel@FreeBSD.org> | 2002-02-11 04:48:51 +0000 |
|---|---|---|
| committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2002-02-11 04:48:51 +0000 |
| commit | 001bd9841f0d99964054c9b2370179891ebb16ad (patch) | |
| tree | 36cba4cd0327655dfbc2c552daac1d3584a60ff4 /sys/compat | |
| parent | 1218efc5db42a7340b0187ddc3bc841de5ea0ff3 (diff) | |
Notes
Diffstat (limited to 'sys/compat')
| -rw-r--r-- | sys/compat/linux/linux_ioctl.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 6a39bd255923..4342851c4f88 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -1355,17 +1355,30 @@ linux_ioctl_console(struct proc *p, struct linux_ioctl_args *args) #define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER) /* - * Construct the Linux name for an interface + * Interface function used by linprocfs (at the time of writing). It's not + * used by the Linuxulator itself. */ - int -linux_ifname(struct ifnet *ifp, char *name, size_t size) +linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen) { - if (IFP_IS_ETH(ifp)) - return snprintf(name, LINUX_IFNAMSIZ, - "eth%d", ifp->if_index); - return snprintf(name, LINUX_IFNAMSIZ, - "%s%d", ifp->if_name, ifp->if_unit); + struct ifnet *ifscan; + int ethno; + + /* Short-circuit non ethernet interfaces */ + if (!IFP_IS_ETH(ifp)) + return (snprintf(buffer, buflen, "%s%d", ifp->if_name, + ifp->if_unit)); + + /* Determine the (relative) unit number for ethernet interfaces */ + ethno = 0; + TAILQ_FOREACH(ifscan, &ifnet, if_link) { + if (ifscan == ifp) + return (snprintf(buffer, buflen, "eth%d", ethno)); + if (IFP_IS_ETH(ifscan)) + ethno++; + } + + return (0); } /* @@ -1420,6 +1433,7 @@ linux_ifconf(struct proc *p, 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; @@ -1442,10 +1456,11 @@ linux_ifconf(struct proc *p, 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", @@ -1453,9 +1468,25 @@ linux_ifconf(struct proc *p, 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; |
