Subject: kern/9169: Linux emulation of SIOCGIFHWADDR
To: None <gnats-bugs@gnats.netbsd.org>
From: None <salvet@ics.muni.cz>
List: netbsd-bugs
Date: 01/11/2000 13:24:47
>Number: 9169
>Category: kern
>Synopsis: Linux ICA client does now work
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jan 11 13:24:01 2000
>Last-Modified:
>Originator: Zdenek Salvet
>Organization:
Institute of Computer Science, Masaryk University, Czech Republic
>Release: 1.4K
>Environment:
NetBSD/i386 1.4K
>Description:
1)
Linux ICA client (http://download.citrix.com/download.asp?client=LINUX)
does not work, because it is not able to get the MAC address
of the network interface with SIOCGIFHWADDR ioctl - it uses real interface
name, not eth*.
2) Linux kernel uses ENODEV errno for requests to unknown interfaces
>How-To-Repeat:
>Fix:
--- sys/compat/linux/common/linux_socket.c.orig Tue Jan 11 21:15:25 2000
+++ sys/compat/linux/common/linux_socket.c Tue Jan 11 22:07:51 2000
@@ -500,9 +500,39 @@
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') {
@@ -546,8 +576,8 @@
}
}
} else
- /* not an "eth*" name */
- error = EINVAL;
+ /* unknown interface, not even an "eth*" name */
+ error = ENODEV;
out:
FILE_UNUSE(fp, p);
>Audit-Trail:
>Unformatted: