X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fndp.c;h=17ec8b48efa3657c57dba3de677b200446923906;hp=bd620682954a20bd69151ced5e3f3967feb3c70d;hb=eaff6fa14161d58af63bda2e5d56bed2593ad0d0;hpb=0b68cabeb40d6e24a677a9332d3f3db163b5d723 diff --git a/src/ndp.c b/src/ndp.c index bd62068..17ec8b4 100644 --- a/src/ndp.c +++ b/src/ndp.c @@ -111,6 +111,10 @@ int init_ndp(void) // Open ICMPv6 socket ping_socket = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6); + if (ping_socket < 0) { + syslog(LOG_ERR, "Unable to open raw socket: %s", strerror(errno)); + return -1; + } int val = 2; setsockopt(ping_socket, IPPROTO_RAW, IPV6_CHECKSUM, &val, sizeof(val)); @@ -167,6 +171,7 @@ int setup_ndp_interface(struct interface *iface, bool enable) memcpy(entry, iface->static_ndp, iface->static_ndp_len); for (entry = strtok_r(entry, " ", &saveptr); entry; entry = strtok_r(NULL, " ", &saveptr)) { + char *sep; struct ndp_neighbor *n = malloc(sizeof(*n)); if (!n) { syslog(LOG_ERR, "Malloc failed for static NDP-prefix %s", entry); @@ -176,12 +181,20 @@ int setup_ndp_interface(struct interface *iface, bool enable) n->iface = iface; n->timeout = 0; - char ipbuf[INET6_ADDRSTRLEN]; - if (sscanf(entry, "%45s/%hhu", ipbuf, &n->len) < 2 - || n->len > 128 || inet_pton(AF_INET6, ipbuf, &n->addr) != 1) { + sep = strchr(entry, '/'); + if (!sep) { + free(n); syslog(LOG_ERR, "Invalid static NDP-prefix %s", entry); return -1; } + + *sep = 0; + n->len = atoi(sep + 1); + if (inet_pton(AF_INET6, entry, &n->addr) != 1 || n->len > 128) { + free(n); + syslog(LOG_ERR, "Invalid static NDP-prefix %s/%s", entry, sep + 1); + return -1; + } list_add(&n->head, &neighbors); } @@ -234,7 +247,7 @@ static void handle_solicit(void *addr, void *data, size_t len, char ipbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &req->nd_ns_target, ipbuf, sizeof(ipbuf)); - syslog(LOG_NOTICE, "Got a NS for %s", ipbuf); + syslog(LOG_DEBUG, "Got a NS for %s", ipbuf); uint8_t mac[6]; odhcpd_get_mac(iface, mac); @@ -246,7 +259,7 @@ static void handle_solicit(void *addr, void *data, size_t len, struct ndp_neighbor *n = find_neighbor(&req->nd_ns_target, false); if (n && (n->iface || abs(n->timeout - now) < 5)) { - syslog(LOG_NOTICE, "%s is on %s", ipbuf, + syslog(LOG_DEBUG, "%s is on %s", ipbuf, (n->iface) ? n->iface->ifname : ""); if (!n->iface || n->iface == iface) return; @@ -364,41 +377,12 @@ static void free_neighbor(struct ndp_neighbor *n) --neighbor_count; } - -static bool match_neighbor(struct ndp_neighbor *n, struct in6_addr *addr) -{ - if (n->len <= 32) - return ntohl(n->addr.s6_addr32[0]) >> (32 - n->len) == - ntohl(addr->s6_addr32[0]) >> (32 - n->len); - - if (n->addr.s6_addr32[0] != addr->s6_addr32[0]) - return false; - - if (n->len <= 64) - return ntohl(n->addr.s6_addr32[1]) >> (64 - n->len) == - ntohl(addr->s6_addr32[1]) >> (64 - n->len); - - if (n->addr.s6_addr32[1] != addr->s6_addr32[1]) - return false; - - if (n->len <= 96) - return ntohl(n->addr.s6_addr32[2]) >> (96 - n->len) == - ntohl(addr->s6_addr32[2]) >> (96 - n->len); - - if (n->addr.s6_addr32[2] != addr->s6_addr32[2]) - return false; - - return ntohl(n->addr.s6_addr32[3]) >> (128 - n->len) == - ntohl(addr->s6_addr32[3]) >> (128 - n->len); -} - - static struct ndp_neighbor* find_neighbor(struct in6_addr *addr, bool strict) { time_t now = time(NULL); struct ndp_neighbor *n, *e; list_for_each_entry_safe(n, e, &neighbors, head) { - if ((!strict && match_neighbor(n, addr)) || + if ((!strict && !odhcpd_bmemcmp(&n->addr, addr, n->len)) || (n->len == 128 && IN6_ARE_ADDR_EQUAL(&n->addr, addr))) return n; @@ -534,8 +518,8 @@ static void handle_rtnetlink(_unused void *addr, void *data, size_t len, /* TODO: See if this is required for optimal operation // Keep neighbor entries alive so we don't loose routes + */ if (add && (ndm->ndm_state & NUD_STALE)) ping6(addr, iface); - */ } }