From dc30922e418be6271ad177f3f9d4ecf0c1eb3f01 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Thu, 23 Jan 2014 17:05:18 +0100 Subject: [PATCH] allow disabling "client fqdn" and "accept reconfiguration" options Some DHCPv6 servers require these to be absent, so add command line switches that allow disabling them. (includes "Combination of command line switches -f and -a broke "-N none" and IA_PD." from Christian Carstensen) Contributed by T-Labs, Deutsche Telekom Innovation Laboratories --- src/dhcpv6.c | 15 +++++++++++++-- src/odhcp6c.c | 20 ++++++++++++++++---- src/odhcp6c.h | 8 +++++++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 973ca8f..eab9cbf 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -105,8 +105,13 @@ static bool accept_reconfig = false; // Reconfigure key static uint8_t reconf_key[16]; -int init_dhcpv6(const char *ifname, bool strict_options, int sol_timeout) +// client options +static unsigned int client_options = 0; + + +int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) { + client_options = options; dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout; sock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); @@ -156,7 +161,7 @@ int init_dhcpv6(const char *ifname, bool strict_options, int sol_timeout) } // Create ORO - if (!strict_options) { + if (!(client_options & DHCPV6_STRICT_OPTIONS)) { uint16_t oro[] = { htons(DHCPV6_OPT_SIP_SERVER_D), htons(DHCPV6_OPT_SIP_SERVER_A), @@ -413,6 +418,12 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) if (na_mode == IA_MODE_NONE) iov[7].iov_len = 0; + if (!(client_options & DHCPV6_ACCEPT_RECONFIGURE)) + iov[5].iov_len = 0; + + if (!(client_options & DHCPV6_CLIENT_FQDN)) + iov[6].iov_len = 0; + struct sockaddr_in6 srv = {AF_INET6, htons(DHCPV6_SERVER_PORT), 0, ALL_DHCPV6_RELAYS, ifindex}; struct msghdr msg = {&srv, sizeof(srv), iov, cnt, NULL, 0, 0}; diff --git a/src/odhcp6c.c b/src/odhcp6c.c index fdfc327..9334c7a 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -71,10 +71,12 @@ int main(_unused int argc, char* const argv[]) int bfd_interval = 0, bfd_loss = 3; #endif - bool help = false, daemonize = false, strict_options = false; + bool help = false, daemonize = false; int logopt = LOG_PID; int c; - while ((c = getopt(argc, argv, "S::N:P:FB:c:i:r:Rs:kt:hedp:")) != -1) { + unsigned int client_options = DHCPV6_CLIENT_FQDN | DHCPV6_ACCEPT_RECONFIGURE; + + while ((c = getopt(argc, argv, "S::N:P:FB:c:i:r:Rs:kt:hedp:fa")) != -1) { switch (c) { case 'S': allow_slaac_only = (optarg) ? atoi(optarg) : -1; @@ -160,7 +162,7 @@ int main(_unused int argc, char* const argv[]) break; case 'R': - strict_options = true; + client_options |= DHCPV6_STRICT_OPTIONS; break; case 's': @@ -187,6 +189,14 @@ int main(_unused int argc, char* const argv[]) pidfile = optarg; break; + case 'f': + client_options &= ~DHCPV6_CLIENT_FQDN; + break; + + case 'a': + client_options &= ~DHCPV6_ACCEPT_RECONFIGURE; + break; + default: help = true; break; @@ -208,7 +218,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, strict_options, sol_timeout) || + init_dhcpv6(ifname, client_options, sol_timeout) || ra_init(ifname, &ifid) || script_init(script, ifname)) { syslog(LOG_ERR, "failed to initialize: %s", strerror(errno)); return 3; @@ -412,6 +422,8 @@ static int usage(void) " -r Options to be requested (comma-separated)\n" " -R Do not request any options except those specified with -r\n" " -s