X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=src%2Fra.c;h=9a579851524786704875d675100d8fded72ef6b7;hb=e3e24645a00ff0aea4760265840bde21baeab3f1;hp=b1526aed6ccacaba046b10072fd8e8887628fb29;hpb=83114b179091cb080f09cf4142ee1c9949ea4e30;p=odhcp6c.git diff --git a/src/ra.c b/src/ra.c index b1526ae..9a57985 100644 --- a/src/ra.c +++ b/src/ra.c @@ -42,11 +42,12 @@ static struct in6_addr lladdr = IN6ADDR_ANY_INIT; static void ra_send_rs(int signal __attribute__((unused))); -int ra_init(const char *ifname) +int ra_init(const char *ifname, const struct in6_addr *ifid) { sock = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6); if_index = if_nametoindex(ifname); strncpy(if_name, ifname, sizeof(if_name) - 1); + lladdr = *ifid; // Filter ICMPv6 package types struct icmp6_filter filt; @@ -74,17 +75,19 @@ int ra_init(const char *ifname) fcntl(sock, F_SETOWN, ourpid); fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_ASYNC); - // Get LL-addr - FILE *fp = fopen("/proc/net/if_inet6", "r"); - if (fp) { - char addrbuf[33], ifbuf[16]; - while (fscanf(fp, "%32s %*x %*x %*x %*x %15s", addrbuf, ifbuf) == 2) { - if (!strcmp(ifbuf, if_name)) { - script_unhexlify((uint8_t*)&lladdr, sizeof(lladdr), addrbuf); - break; + if (IN6_IS_ADDR_UNSPECIFIED(&lladdr)) { + // Autodetect interface-id if not specified + FILE *fp = fopen("/proc/net/if_inet6", "r"); + if (fp) { + char addrbuf[33], ifbuf[16]; + while (fscanf(fp, "%32s %*x %*x %*x %*x %15s", addrbuf, ifbuf) == 2) { + if (!strcmp(ifbuf, if_name)) { + script_unhexlify((uint8_t*)&lladdr, sizeof(lladdr), addrbuf); + break; + } } + fclose(fp); } - fclose(fp); } // Open rtnetlink socket @@ -139,7 +142,7 @@ static void update_proc(const char *sect, const char *opt, uint32_t value) static bool ra_deduplicate(const struct in6_addr *any, uint8_t length) { - struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, length, 0, *any, 0, 0}; + struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, length, 0, *any, 0, 0, 0}; struct odhcp6c_entry *x = odhcp6c_find_entry(STATE_RA_PREFIX, &entry); if (x && IN6_ARE_ADDR_EQUAL(&x->target, any)) { odhcp6c_random(&x->target.s6_addr32[2], 2 * sizeof(uint32_t)); @@ -199,7 +202,7 @@ bool ra_process(void) bool found = false; uint8_t buf[1500]; struct nd_router_advert *adv = (struct nd_router_advert*)buf; - struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, 0, 0, IN6ADDR_ANY_INIT, 0, 0}; + struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT, 0, 0, IN6ADDR_ANY_INIT, 0, 0, 0}; const struct in6_addr any = IN6ADDR_ANY_INIT; while (true) {