]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Improve FreeBSD support by using the actual AF_LINK address.
authorRoy Marples <roy@marples.name>
Fri, 10 Oct 2014 20:35:13 +0000 (20:35 +0000)
committerRoy Marples <roy@marples.name>
Fri, 10 Oct 2014 20:35:13 +0000 (20:35 +0000)
compat/linkaddr.c [deleted file]
configure
dhcpcd.h
if-bsd.c
if.c
ipv6nd.c

diff --git a/compat/linkaddr.c b/compat/linkaddr.c
deleted file mode 100644 (file)
index c4e6fa5..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if_dl.h>
-
-#include <string.h>
-
-/* States*/
-#define NAMING 0
-#define GOTONE 1
-#define GOTTWO 2
-#define RESET  3
-/* Inputs */
-#define        DIGIT   (4*0)
-#define        END     (4*1)
-#define DELIM  (4*2)
-#define LETTER (4*3)
-
-void
-link_addr(addr, sdl)
-       const char *addr;
-       struct sockaddr_dl *sdl;
-{
-       char *cp = sdl->sdl_data;
-       char *cplim = sdl->sdl_len + (char *)(void *)sdl;
-       int byte = 0, state = NAMING;
-       int newaddr = 0;
-
-       (void)memset(&sdl->sdl_family, 0, (size_t)sdl->sdl_len - 1);
-       sdl->sdl_family = AF_LINK;
-       do {
-               state &= ~LETTER;
-               if ((*addr >= '0') && (*addr <= '9')) {
-                       newaddr = *addr - '0';
-               } else if ((*addr >= 'a') && (*addr <= 'f')) {
-                       newaddr = *addr - 'a' + 10;
-               } else if ((*addr >= 'A') && (*addr <= 'F')) {
-                       newaddr = *addr - 'A' + 10;
-               } else if (*addr == 0) {
-                       state |= END;
-               } else if (state == NAMING &&
-                          (((*addr >= 'A') && (*addr <= 'Z')) ||
-                          ((*addr >= 'a') && (*addr <= 'z'))))
-                       state |= LETTER;
-               else
-                       state |= DELIM;
-               addr++;
-               switch (state /* | INPUT */) {
-               case NAMING | DIGIT:
-               case NAMING | LETTER:
-                       *cp++ = addr[-1];
-                       continue;
-               case NAMING | DELIM:
-                       state = RESET;
-                       sdl->sdl_nlen = cp - sdl->sdl_data;
-                       continue;
-               case GOTTWO | DIGIT:
-                       *cp++ = byte;
-                       /* FALLTHROUGH */
-               case RESET | DIGIT:
-                       state = GOTONE;
-                       byte = newaddr;
-                       continue;
-               case GOTONE | DIGIT:
-                       state = GOTTWO;
-                       byte = newaddr + (byte << 4);
-                       continue;
-               default: /* | DELIM */
-                       state = RESET;
-                       *cp++ = byte;
-                       byte = 0;
-                       continue;
-               case GOTONE | END:
-               case GOTTWO | END:
-                       *cp++ = byte;
-                       /* FALLTHROUGH */
-               case RESET | END:
-                       break;
-               }
-               break;
-       } while (cp < cplim);
-       sdl->sdl_alen = cp - LLADDR(sdl);
-       newaddr = cp - (char *)(void *)sdl;
-       if ((size_t) newaddr > sizeof(*sdl))
-               sdl->sdl_len = newaddr;
-       return;
-}
index 294f49a0edb80711eb530d79365803ff45d935d1..25714c09d157b5cb70e1fc73bb9c6ba76b907ab3 100755 (executable)
--- a/configure
+++ b/configure
@@ -370,7 +370,6 @@ linux*)
 kfreebsd*)
        echo "CPPFLAGS+=        -D_GNU_SOURCE" >>$CONFIG_MK
        echo "DHCPCD_SRCS+=     if-bsd.c" >>$CONFIG_MK
-       echo "COMPAT_SRCS+=     compat/linkaddr.c" >>$CONFIG_MK
        ;;
 sunos*)
        echo "WARNING!!! Solaris support is at early development stage!" >&2
index 34c727215e50dfddc094979bf6db8eea4845bdd9..63a0c4a392da40eda88c55cb2a694a4eada08aa4 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -63,6 +63,7 @@ struct interface {
        unsigned int index;
        unsigned int flags;
        sa_family_t family;
+       struct sockaddr_storage linkaddr;
        unsigned char hwaddr[HWADDR_LEN];
        uint8_t hwlen;
        unsigned int metric;
index 1e7d6262099f7fef9aa117a27d7fb31e1052c570..62393250ca54c5775f873ed7a11b1ed24829c43b 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -524,10 +524,9 @@ if_route(const struct rt *rt, int action)
                    rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
                    !(rtm.hdr.rtm_flags & RTF_STATIC))
                {
-                       /* Make us a link layer socket for the host gateway */
-                       memset(&su, 0, sizeof(su));
-                       su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-                       link_addr(rt->iface->name, &su.sdl);
+                       memcpy(&su.sdl,
+                           &rt->iface->linkaddr, sizeof(struct sockaddr_dl));
+                       su.sdl.sdl_nlen = su.sdl.sdl_alen = su.sdl.sdl_slen = 0;
                        ADDSU;
                } else
                        ADDADDR(&rt->gate);
@@ -537,10 +536,9 @@ if_route(const struct rt *rt, int action)
                ADDADDR(&rt->net);
 
        if (rtm.hdr.rtm_addrs & RTA_IFP) {
-               /* Make us a link layer socket for the host gateway */
-               memset(&su, 0, sizeof(su));
-               su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-               link_addr(rt->iface->name, &su.sdl);
+               memcpy(&su.sdl,
+                   &rt->iface->linkaddr, sizeof(struct sockaddr_dl));
+               su.sdl.sdl_nlen = su.sdl.sdl_alen = su.sdl.sdl_slen = 0;
                ADDSU;
        }
 
@@ -698,10 +696,10 @@ if_route6(const struct rt6 *rt, int action)
        lla = NULL;
        if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
                if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
-                       lla = ipv6_linklocal(rt->iface);
-                       if (lla == NULL) /* unlikely */
-                               return -1;
-                       ADDADDRS(&lla->addr, rt->iface->index);
+                       memcpy(&su.sdl,
+                           &rt->iface->linkaddr, sizeof(struct sockaddr_dl));
+                       su.sdl.sdl_nlen = su.sdl.sdl_alen = su.sdl.sdl_slen = 0;
+                       ADDSU;
                } else {
                        ADDADDRS(&rt->gate, rt->iface->index);
                }
@@ -711,10 +709,9 @@ if_route6(const struct rt6 *rt, int action)
                ADDADDR(&rt->net);
 
        if (rtm.hdr.rtm_addrs & RTA_IFP) {
-               /* Make us a link layer socket for the host gateway */
-               memset(&su, 0, sizeof(su));
-               su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-               link_addr(rt->iface->name, &su.sdl);
+               memcpy(&su.sdl,
+                   &rt->iface->linkaddr, sizeof(struct sockaddr_dl));
+               su.sdl.sdl_nlen = su.sdl.sdl_alen = su.sdl.sdl_slen = 0;
                ADDSU;
        }
 
@@ -1048,9 +1045,14 @@ if_nd6reachable(const char *ifname, struct in6_addr *addr)
        memset(&nbi, 0, sizeof(nbi));
        strlcpy(nbi.ifname, ifname, sizeof(nbi.ifname));
        nbi.addr = *addr;
-       if (ioctl(s, SIOCGNBRINFO_IN6, &nbi) == -1)
+       if (ioctl(s, SIOCGNBRINFO_IN6, &nbi) == -1) {
+#ifdef __FreeBSD__
+               /* FreeBSD doesn't support reachable routers? */
+               if (errno == EINVAL)
+                       errno = ENOTSUP;
+#endif
                flags = -1;
-       else {
+       else {
                flags = 0;
                switch(nbi.state) {
                case ND6_LLINFO_REACHABLE:
diff --git a/if.c b/if.c
index 8e8a869ae1ad1c49bae618e45632c4940756becd..f73c654603a0ea1a06d0732ea822920d142c0578 100644 (file)
--- a/if.c
+++ b/if.c
@@ -326,6 +326,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
                        }
 #endif
 
+                       memcpy(&ifp->linkaddr, sdl, sdl->sdl_len);
                        ifp->index = sdl->sdl_index;
                        sdl_type = sdl->sdl_type;
                        switch(sdl->sdl_type) {
index c5ddab2fe207aa879aeea002196c4d713347742a..0af3b6afd4e589b619926ee9f84f1a5a8a2309fb 100644 (file)
--- a/ipv6nd.c
+++ b/ipv6nd.c
@@ -368,8 +368,12 @@ ipv6nd_checkreachablerouters(void *arg)
        TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
                flags = if_nd6reachable(rap->iface->name, &rap->from);
                if (flags == -1) {
-                       /* An error occured, so it's unreachable */
-                       flags = 0;
+                       if (errno == ENOTSUP)
+                               /* Unsupported? We have to assume reachable */
+                               flags = IPV6ND_REACHABLE;
+                       else
+                               /* An error occured, so it's unreachable */
+                               flags = 0;
                }
                ipv6nd_reachable(rap, flags);
        }
@@ -1110,7 +1114,8 @@ handle_flag:
 
 #ifndef HAVE_RTM_GETNEIGH
        /* Start our reachability tests now */
-       ipv6nd_checkreachablerouters(ifp->ctx);
+       eloop_timeout_add_sec(ifp->ctx->eloop, ND6REACHABLE_TIMER,
+           ipv6nd_checkreachablerouters, ifp->ctx);
 #endif
 }