Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux/common Improve emulation of SIOCGIFHWADDR i...



details:   https://anonhg.NetBSD.org/src/rev/a7dde9db7b62
branches:  trunk
changeset: 480435:a7dde9db7b62
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Wed Jan 12 17:19:11 2000 +0000

description:
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@localhost> in kern/9169.

diffstat:

 sys/compat/linux/common/linux_socket.c |  43 +++++++++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 6 deletions(-)

diffs (65 lines):

diff -r 870a1c978a8c -r a7dde9db7b62 sys/compat/linux/common/linux_socket.c
--- a/sys/compat/linux/common/linux_socket.c    Wed Jan 12 15:53:29 2000 +0000
+++ b/sys/compat/linux/common/linux_socket.c    Wed Jan 12 17:19:11 2000 +0000
@@ -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 @@
        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 @@
                                        break;
                                }
                }
-       } else
-               /* not an "eth*" name */
-               error = EINVAL;
+       } else {
+               /* unknown interface, not even an "eth*" name */
+               error = ENODEV;
+       }
     
 out:
        FILE_UNUSE(fp, p);



Home | Main Index | Thread Index | Old Index