From a477e955b41d2e18ad402e91603bdf0d108490e7 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Tue, 16 Jan 2018 11:11:04 +0100 Subject: [PATCH] odhcp6c: rework userclass and vendorclass command handling Remove the userclass and vendorclass states; add the userclass and vendorclass options specified via commands to the OPTS state which contains the user specified options to be sent. Signed-off-by: Hans Dedecker --- src/dhcpv6.c | 23 ----------------------- src/odhcp6c.c | 48 ++++++++++++++++++++++++++++++++++++++---------- src/odhcp6c.h | 2 -- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index a905d5b..742c3b0 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -221,10 +221,6 @@ enum { IOV_ORO_REFRESH, IOV_CL_ID, IOV_SRV_ID, - IOV_VENDOR_CLASS_HDR, - IOV_VENDOR_CLASS, - IOV_USER_CLASS_HDR, - IOV_USER_CLASS, IOV_OPTS, IOV_RECONF_ACCEPT, IOV_FQDN, @@ -431,21 +427,6 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) size_t opts_len; void *opts = odhcp6c_get_state(STATE_OPTS, &opts_len); - // Build vendor-class option - size_t vendor_class_len, user_class_len; - struct dhcpv6_vendorclass *vendor_class = odhcp6c_get_state(STATE_VENDORCLASS, &vendor_class_len); - void *user_class = odhcp6c_get_state(STATE_USERCLASS, &user_class_len); - - struct { - uint16_t type; - uint16_t length; - } vendor_class_hdr = {htons(DHCPV6_OPT_VENDOR_CLASS), htons(vendor_class_len)}; - - struct { - uint16_t type; - uint16_t length; - } user_class_hdr = {htons(DHCPV6_OPT_USER_CLASS), htons(user_class_len)}; - // Prepare Header size_t oro_len; void *oro = odhcp6c_get_state(STATE_ORO, &oro_len); @@ -470,10 +451,6 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) [IOV_ORO_REFRESH] = {&oro_refresh, 0}, [IOV_CL_ID] = {cl_id, cl_id_len}, [IOV_SRV_ID] = {srv_id, srv_id_len}, - [IOV_VENDOR_CLASS_HDR] = {&vendor_class_hdr, vendor_class_len ? sizeof(vendor_class_hdr) : 0}, - [IOV_VENDOR_CLASS] = {vendor_class, vendor_class_len}, - [IOV_USER_CLASS_HDR] = {&user_class_hdr, user_class_len ? sizeof(user_class_hdr) : 0}, - [IOV_USER_CLASS] = {user_class, user_class_len}, [IOV_OPTS] = { opts, opts_len }, [IOV_RECONF_ACCEPT] = {&reconf_accept, sizeof(reconf_accept)}, [IOV_FQDN] = {&fqdn, fqdn_len}, diff --git a/src/odhcp6c.c b/src/odhcp6c.c index db6fe2e..e5c53c1 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -122,12 +122,12 @@ int main(_unused int argc, char* const argv[]) const char *pidfile = NULL; const char *script = "/usr/sbin/odhcp6c-update"; ssize_t l; - uint8_t buf[134]; + uint8_t buf[134], *o_data; char *optpos; uint16_t opttype; - uint16_t optlen; enum odhcp6c_ia_mode ia_na_mode = IA_MODE_TRY; enum odhcp6c_ia_mode ia_pd_mode = IA_MODE_NONE; + struct odhcp6c_opt *opt; int ia_pd_iaid_index = 0; int sol_timeout = DHCPV6_SOL_MAX_RT; int verbosity = 0; @@ -157,14 +157,27 @@ int main(_unused int argc, char* const argv[]) break; case 'V': - l = script_unhexlify(buf, sizeof(buf), optarg); - if (l) { - if (odhcp6c_add_state(STATE_VENDORCLASS, buf, l)) { - syslog(LOG_ERR, "Failed to set vendor-class option"); - return 1; + opt = odhcp6c_find_opt(DHCPV6_OPT_VENDOR_CLASS); + if (!opt) { + syslog(LOG_ERR, "Failed to set vendor-class option"); + return 1; + } + + o_data = NULL; + res = parse_opt_data(optarg, &o_data, opt->flags & OPT_MASK_SIZE, + (opt->flags & OPT_ARRAY) == OPT_ARRAY); + if (res > 0) { + res = add_opt(opt->code, o_data, res); + if (res) { + if (res > 0) + return 1; + + help = true; } } else help = true; + + free(o_data); break; case 'P': @@ -244,12 +257,27 @@ int main(_unused int argc, char* const argv[]) break; case 'u': - optlen = htons(strlen(optarg)); - if (odhcp6c_add_state(STATE_USERCLASS, &optlen, 2) || - odhcp6c_add_state(STATE_USERCLASS, optarg, strlen(optarg))) { + opt = odhcp6c_find_opt(DHCPV6_OPT_USER_CLASS); + if (!opt) { syslog(LOG_ERR, "Failed to set user-class option"); return 1; } + + o_data = NULL; + res = parse_opt_data(optarg, &o_data, opt->flags & OPT_MASK_SIZE, + (opt->flags & OPT_ARRAY) == OPT_ARRAY); + if (res > 0) { + res = add_opt(opt->code, o_data, res); + if (res) { + if (res > 0) + return 1; + + help = true; + } + } else + help = true; + + free(o_data); break; case 's': diff --git a/src/odhcp6c.h b/src/odhcp6c.h index d92b6bc..40fed3e 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -261,8 +261,6 @@ enum odhcp6c_state { STATE_RA_DNS, STATE_RA_SEARCH, STATE_AFTR_NAME, - STATE_VENDORCLASS, - STATE_USERCLASS, STATE_OPTS, STATE_CER, STATE_S46_MAPT, -- 2.25.1