From dc30922e418be6271ad177f3f9d4ecf0c1eb3f01 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser <kaspar@schleiser.de> 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> Options to be requested (comma-separated)\n" " -R Do not request any options except those specified with -r\n" " -s <script> Status update script (/usr/sbin/odhcp6c-update)\n" + " -a Don't send Accept Reconfigure option\n" + " -f Don't send Client FQDN option\n" " -k Don't send a RELEASE when stopping\n" " -t <seconds> Maximum timeout for DHCPv6-SOLICIT (120)\n" "\nInvocation options:\n" diff --git a/src/odhcp6c.h b/src/odhcp6c.h index a8f4206..024ebea 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -97,6 +97,12 @@ enum dhcpv6_status { _DHCPV6_Status_Max }; +enum dhcpv6_config { + DHCPV6_STRICT_OPTIONS = 1, + DHCPV6_CLIENT_FQDN = 2, + DHCPV6_ACCEPT_RECONFIGURE = 4, +}; + typedef int(reply_handler)(enum dhcpv6_msg orig, const int rc, const void *opt, const void *end); @@ -245,7 +251,7 @@ struct odhcp6c_request_prefix { uint16_t length; }; -int init_dhcpv6(const char *ifname, bool strict_options, int sol_timeout); +int init_dhcpv6(const char *ifname, unsigned int client_options, int sol_timeout); void dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd); int dhcpv6_request(enum dhcpv6_msg type); int dhcpv6_poll_reconfigure(void); -- 2.39.5