diff options
| author | jdolecek <jdolecek@NetBSD.org> | 2000-01-12 17:19:11 +0000 |
|---|---|---|
| committer | jdolecek <jdolecek@NetBSD.org> | 2000-01-12 17:19:11 +0000 |
| commit | 600be45ffcbc989afa66a82b1247f33c6ad1d3dd (patch) | |
| tree | 650dccfa21aed7b83dd8e14cb91ed80c2026624d /sys/compat/linux/common/linux_socket.c | |
| parent | e42b2c6cb7c593a79053928426905f1b176abfbc (diff) | |
Improve emulation of SIOCGIFHWADDR ioctl:
* when finding an interface, try the real name first before faking eth*
* Linux kernel returns ENODEV if the request goes to unknown interface,
so do the same here
This change makes Linux ICA client work.
Patch sent by Zdenek Salvet <salvet@ics.muni.cz> in kern/9169.
Diffstat (limited to 'sys/compat/linux/common/linux_socket.c')
| -rw-r--r-- | sys/compat/linux/common/linux_socket.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/sys/compat/linux/common/linux_socket.c b/sys/compat/linux/common/linux_socket.c index ac644a6cabe..76bcb780024 100644 --- a/sys/compat/linux/common/linux_socket.c +++ b/sys/compat/linux/common/linux_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_socket.c,v 1.21 1999/07/17 22:03:55 jtk Exp $ */ +/* $NetBSD: linux_socket.c,v 1.22 2000/01/12 17:19:11 jdolecek Exp $ */ /*- * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. @@ -500,9 +500,39 @@ linux_getifhwaddr(p, retval, fd, data) lreq.if_name[IF_NAME_LEN-1] = '\0'; /* just in case */ /* - * Only support finding addresses for "ethX". Should we - * do otherwise? XXX + * Try real interface name first, then fake "ethX" */ + for (ifp = ifnet.tqh_first, found = 0; + ifp != 0 && !found; + ifp = ifp->if_list.tqe_next) { + if (strcmp(lreq.if_name, ifp->if_xname)) + /* not this interface */ + continue; + found=1; + if ((ifa = ifp->if_addrlist.tqh_first) != 0) { + for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { + sadl = (struct sockaddr_dl *)ifa->ifa_addr; + /* only return ethernet addresses */ + /* XXX what about FDDI, etc. ? */ + if (sadl->sdl_family != AF_LINK || + sadl->sdl_type != IFT_ETHER) + continue; + memcpy((caddr_t)&lreq.hwaddr.sa_data, + LLADDR(sadl), + MIN(sadl->sdl_alen, + sizeof(lreq.hwaddr.sa_data))); + lreq.hwaddr.sa_family = + sadl->sdl_family; + error = copyout((caddr_t)&lreq, data, + sizeof(lreq)); + goto out; + } + } else { + error = ENODEV; + goto out; + } + } + if (lreq.if_name[0] == 'e' && lreq.if_name[1] == 't' && lreq.if_name[2] == 'h') { @@ -545,9 +575,10 @@ linux_getifhwaddr(p, retval, fd, data) break; } } - } else - /* not an "eth*" name */ - error = EINVAL; + } else { + /* unknown interface, not even an "eth*" name */ + error = ENODEV; + } out: FILE_UNUSE(fp, p); |
