From: Hans Dedecker Date: Fri, 8 Jun 2018 14:29:50 +0000 (+0200) Subject: odhcp6c: add support for user string options X-Git-Url: http://git.openwrt.org/?p=project%2Fodhcp6c.git;a=commitdiff_plain;h=ca8822bc7bd0797eaa6b6160f234471ee1a8fb2c odhcp6c: add support for user string options Support user defined options having a string as option value. The option value is detected as a string if it starts and ends with either a double or single quote. Signed-off-by: Hans Dedecker --- diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 48e3dee..2fb8abf 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -560,6 +560,7 @@ static int usage(void) " -x dns:2001:2001::1,2001:2001::2 - option 23\n" " -x 15:office - option 15 (userclass)\n" " -x 0x1f4:ABBA - option 500\n" + " -x 202:'\"file\"' - option 202\n" " -c Override client-ID (base-16 encoded 16-bit type + value)\n" " -i Use a custom interface identifier for RA handling\n" " -r Options to be requested (comma-separated)\n" @@ -969,6 +970,40 @@ static int parse_opt_u8(const char *src, uint8_t **dst) return script_unhexlify(*dst, len, src); } +static int parse_opt_string(const char *src, uint8_t **dst, const bool array) +{ + int i_len = strlen(src); + int o_len = 0; + char *sep = get_sep_pos(src, ARRAY_SEP); + + if (sep && !array) + return -1; + + do { + if (sep) { + *sep = 0; + sep++; + } + + int len = strlen(src); + + *dst = realloc(*dst, o_len + len); + if (!*dst) + return -1; + + memcpy(&((*dst)[o_len]), src, len); + + o_len += len; + i_len -= strlen(src) + (sep ? 1 : 0); + src = sep; + + if (sep) + sep = get_sep_pos(src, ARRAY_SEP); + } while (i_len); + + return o_len; +} + static int parse_opt_dns_string(const char *src, uint8_t **dst, const bool array) { int i_len = strlen(src); @@ -1091,6 +1126,10 @@ static int parse_opt_data(const char *data, uint8_t **dst, const unsigned int ty ret = parse_opt_u8(data, dst); break; + case OPT_STR: + ret = parse_opt_string(data, dst, array); + break; + case OPT_DNS_STR: ret = parse_opt_dns_string(data, dst, array); break; @@ -1151,6 +1190,16 @@ static int parse_opt(const char *opt) type = dopt->flags & OPT_MASK_SIZE; array = ((dopt->flags & OPT_ARRAY) == OPT_ARRAY) ? true : false; + } else if (data[0] == '"' || data[0] == '\'') { + char *end = strrchr(data + 1, data[0]); + + if (end && (end == (data + strlen(data) - 1))) { + /* Raw option is specified as a string */ + type = OPT_STR; + data++; + *end = '\0'; + } + } payload_len = parse_opt_data(data, &payload, type, array); diff --git a/src/odhcp6c.h b/src/odhcp6c.h index 3abe7b7..97809f1 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -325,6 +325,7 @@ struct odhcp6c_request_prefix { enum odhcp6c_opt_flags { OPT_U8 = 0, OPT_IP6, + OPT_STR, OPT_DNS_STR, OPT_USER_CLASS, OPT_MASK_SIZE = 0x0F,