Source-Changes-HG archive

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

[src/trunk]: src/external/bsd/dhcp/dist/common Use the active link local laye...



details:   https://anonhg.NetBSD.org/src/rev/2427f412ed94
branches:  trunk
changeset: 785970:2427f412ed94
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Apr 08 02:16:03 2013 +0000

description:
Use the active link local layer address instead of the first one you find.
It would be nice if getifaddrs gave all the information needed instead of
needed a separate ioctl. Or at least if the inactive addresses were marked
down in flags?

diffstat:

 external/bsd/dhcp/dist/common/bpf.c |  51 +++++++++++++++++++++++++++++++++---
 1 files changed, 46 insertions(+), 5 deletions(-)

diffs (97 lines):

diff -r d079ae3f9a0f -r 2427f412ed94 external/bsd/dhcp/dist/common/bpf.c
--- a/external/bsd/dhcp/dist/common/bpf.c       Mon Apr 08 01:59:11 2013 +0000
+++ b/external/bsd/dhcp/dist/common/bpf.c       Mon Apr 08 02:16:03 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.c,v 1.1.1.2 2013/03/27 00:31:33 christos Exp $     */
+/*     $NetBSD: bpf.c,v 1.2 2013/04/08 02:16:03 christos Exp $ */
 
 /* bpf.c
 
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: bpf.c,v 1.1.1.2 2013/03/27 00:31:33 christos Exp $");
+__RCSID("$NetBSD: bpf.c,v 1.2 2013/04/08 02:16:03 christos Exp $");
 
 #include "dhcpd.h"
 #if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)        \
@@ -54,6 +54,7 @@
 #  endif
 # endif
 
+#include <sys/param.h>
 #include <netinet/in_systm.h>
 #include "includes/netinet/ip.h"
 #include "includes/netinet/udp.h"
@@ -556,11 +557,50 @@
        }
 }
 
+static int
+lladdr_active(int s, const char *name, const struct ifaddrs *ifa)
+{
+       if (ifa->ifa_addr->sa_family != AF_LINK)
+               return 0;
+       if (strcmp(ifa->ifa_name, name) != 0)
+               return 0;
+
+#ifdef SIOCGLIFADDR
+{
+       struct if_laddrreq iflr;
+       const struct sockaddr_dl *sdl;
+
+       sdl = satocsdl(ifa->ifa_addr);
+       memset(&iflr, 0, sizeof(iflr));
+
+       strlcpy(iflr.iflr_name, ifa->ifa_name, sizeof(iflr.iflr_name));
+       memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
+           sizeof(iflr.addr)));
+       iflr.flags = IFLR_PREFIX;
+       iflr.prefixlen = sdl->sdl_alen * NBBY;
+
+       if (ioctl(s, SIOCGLIFADDR, &iflr) == -1) {
+               log_fatal("ioctl(SIOCGLIFADDR): %m");
+       }
+
+       if ((iflr.flags & IFLR_ACTIVE) == 0)
+               return 0;
+}
+#endif
+       return 1;
+}
+
+
 void
 get_hw_addr(const char *name, struct hardware *hw) {
        struct ifaddrs *ifa;
        struct ifaddrs *p;
        struct sockaddr_dl *sa;
+       int s;
+
+       if ((s = socket(AF_LINK, SOCK_DGRAM, 0)) == -1) {
+               log_fatal("socket AF_LINK: %m");
+       }
 
        if (getifaddrs(&ifa) != 0) {
                log_fatal("Error getting interface information; %m");
@@ -570,15 +610,16 @@
         * Loop through our interfaces finding a match.
         */
        sa = NULL;
-       for (p=ifa; (p != NULL) && (sa == NULL); p = p->ifa_next) {
-               if ((p->ifa_addr->sa_family == AF_LINK) && 
-                   !strcmp(p->ifa_name, name)) {
+       for (p = ifa; p != NULL; p = p->ifa_next) {
+               if (lladdr_active(s, name, p)) {
                        sa = (struct sockaddr_dl *)p->ifa_addr;
+                       break;
                }
        }
        if (sa == NULL) {
                log_fatal("No interface called '%s'", name);
        }
+       close(s);
 
        /*
         * Pull out the appropriate information.



Home | Main Index | Thread Index | Old Index