From: Roy Marples Date: Fri, 10 Oct 2014 20:35:13 +0000 (+0000) Subject: Improve FreeBSD support by using the actual AF_LINK address. X-Git-Tag: v6.5.1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91692ea1c7b7d180c233ceee7b874f6b045a4ffd;p=thirdparty%2Fdhcpcd.git Improve FreeBSD support by using the actual AF_LINK address. --- diff --git a/compat/linkaddr.c b/compat/linkaddr.c deleted file mode 100644 index c4e6fa54..00000000 --- a/compat/linkaddr.c +++ /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 -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#include - -/* 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; -} diff --git a/configure b/configure index 294f49a0..25714c09 100755 --- 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 diff --git a/dhcpcd.h b/dhcpcd.h index 34c72721..63a0c4a3 100644 --- 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; diff --git a/if-bsd.c b/if-bsd.c index 1e7d6262..62393250 100644 --- 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 8e8a869a..f73c6546 100644 --- 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) { diff --git a/ipv6nd.c b/ipv6nd.c index c5ddab2f..0af3b6af 100644 --- 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 }