When assigned a static prefix, it is desirable to also have a static IP, however, the link-local address assigned from the provider during ipv6cp may change on each connection. This option solves this problem - for example, you can append -H '::1' to the odhcp6c command line. --- src/odhcp6c.c | 10 ++++++++-- src/ra.c | 23 +++++++++++++---------- src/ra.h | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 4fefcd7..04b2c6b 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -50,6 +50,7 @@ int main(_unused int argc, char* const argv[]) // Allocate ressources const char *pidfile = NULL; const char *script = "/usr/sbin/odhcp6c-update"; + const char *hostid = NULL; ssize_t l; uint8_t buf[134]; char *optpos; @@ -59,7 +60,7 @@ int main(_unused int argc, char* const argv[]) bool help = false, daemonize = false; int logopt = LOG_PID; int c, request_pd = 0; - while ((c = getopt(argc, argv, "S::N:P:c:r:s:khedp:")) != -1) { + while ((c = getopt(argc, argv, "S::N:P:c:H:r:s:khedp:")) != -1) { switch (c) { case 'S': allow_slaac_only = (optarg) ? atoi(optarg) : -1; @@ -98,6 +99,10 @@ int main(_unused int argc, char* const argv[]) } break; + case 'H': + hostid = optarg; + break; + case 'r': optpos = optarg; while (optpos[0]) { @@ -151,7 +156,7 @@ int main(_unused int argc, char* const argv[]) signal(SIGUSR2, sighandler); if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 || - init_dhcpv6(ifname, request_pd) || ra_init(ifname) || + init_dhcpv6(ifname, request_pd) || ra_init(ifname, hostid) || script_init(script, ifname)) { syslog(LOG_ERR, "failed to initialize: %s", strerror(errno)); return 3; @@ -314,6 +319,7 @@ static int usage(void) " -N <mode> Mode for requesting addresses [try|force|none]\n" " -P <length> Request IPv6-Prefix (0 = auto)\n" " -c <clientid> Override client-ID (base-16 encoded)\n" + " -H <hostid> Override host id with the given IPv6 address\n" " -r <options> Options to be requested (comma-separated)\n" " -s <script> Status update script (/usr/sbin/odhcp6c-update)\n" " -k Don't send a RELEASE when stopping\n" diff --git a/src/ra.c b/src/ra.c index b1526ae..be37b2d 100644 --- a/src/ra.c +++ b/src/ra.c @@ -42,7 +42,7 @@ 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 char *hostid) { sock = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6); if_index = if_nametoindex(ifname); @@ -74,17 +74,20 @@ 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; + // Use hostid if -H was specified + if(hostid == NULL || inet_pton(AF_INET6, hostid, &lladdr) != 1) { + // Get LL-addr if -H was missing or inet_pton failed + 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 diff --git a/src/ra.h b/src/ra.h index f87c4f7..5a37694 100644 --- a/src/ra.h +++ b/src/ra.h @@ -34,6 +34,6 @@ struct icmpv6_opt { (void*)(opt + opt->len) <= (void*)(end); opt += opt->len) -int ra_init(const char *ifname); +int ra_init(const char *ifname, const char *hostid); bool ra_process(void); bool ra_rtnl_process(void); -- 1.8.3.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel