From: Roy Marples Date: Thu, 12 Jun 2025 10:43:48 +0000 (+0100) Subject: Add truncate to defintions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9fbe9420d75bea1177f6651ac76c9df1e920f04;p=thirdparty%2Fdhcpcd.git Add truncate to defintions This indicates an option might be truncated from it's natural length and will be zero padded on expansion. Only supported for the ip6address option. While here, support 1 as a bitflag to just print the bit. Fixes #508. --- diff --git a/src/dhcp-common.c b/src/dhcp-common.c index 8370adda..14d2d92a 100644 --- a/src/dhcp-common.c +++ b/src/dhcp-common.c @@ -135,6 +135,8 @@ dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols) printf(" request"); if (opt->type & OT_NOREQ) printf(" norequest"); + if (opt->type & OT_TRUNCATED) + printf(" truncated"); putchar('\n'); fflush(stdout); } @@ -614,6 +616,8 @@ dhcp_optlen(const struct dhcp_opt *opt, size_t dl) return (ssize_t)dl; } if (dl < sz) { + if (opt->type & OT_TRUNCATED) + return (ssize_t)dl; errno = EOVERFLOW; return -1; } @@ -751,6 +755,11 @@ print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt, l < sizeof(opt->bitflags); l++, sl--) { + if (opt->bitflags[l] == '1') { + if (fprintf(fp, "%d", *data & (1 << sl)) == -1) + goto err; + continue; + } /* Don't print NULL or 0 flags */ if (opt->bitflags[l] != '\0' && opt->bitflags[l] != '0' && @@ -808,9 +817,14 @@ print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt, goto err; data += sizeof(addr.s_addr); } else if (opt->type & OT_ADDRIPV6) { + uint8_t databuf[sizeof(struct in6_addr)] = { 0 }; + size_t datalen = e - data >= 16 ? 16 : (size_t)(e - data); char buf[INET6_ADDRSTRLEN]; - if (inet_ntop(AF_INET6, data, buf, sizeof(buf)) == NULL) + /* avoid inet_ntop going beyond our option space by + * copying out into a temporary buffer. */ + memcpy(databuf, data, datalen); + if (inet_ntop(AF_INET6, databuf, buf, sizeof(buf)) == NULL) goto err; if (fprintf(fp, "%s", buf) == -1) goto err; diff --git a/src/dhcp-common.h b/src/dhcp-common.h index 6a1800cf..ecee7674 100644 --- a/src/dhcp-common.h +++ b/src/dhcp-common.h @@ -76,6 +76,7 @@ #define OT_BITFLAG (1 << 27) #define OT_RESERVED (1 << 28) #define OT_URI (1 << 29) +#define OT_TRUNCATED (1 << 30) #define DHC_REQ(r, n, o) \ (has_option_mask((r), (o)) && !has_option_mask((n), (o))) diff --git a/src/dhcpcd-definitions-small.conf b/src/dhcpcd-definitions-small.conf index 4d39e2eb..3e7091b0 100644 --- a/src/dhcpcd-definitions-small.conf +++ b/src/dhcpcd-definitions-small.conf @@ -71,10 +71,10 @@ embed uint32 mtu definend 24 index embed route_information embed byte length -# bits 4 and 5 are route preference, but we can't express this -embed byte reserved +# bits 4 and 5 are route preference +embed bitflags=00011 prf embed uint32 lifetime -embed ip6address prefix +embed truncated ip6address prefix # ND6 options, RFC6101 definend 25 index embed rdnss diff --git a/src/dhcpcd-definitions.conf b/src/dhcpcd-definitions.conf index dc245337..f7372114 100644 --- a/src/dhcpcd-definitions.conf +++ b/src/dhcpcd-definitions.conf @@ -414,10 +414,10 @@ embed uint16 lifetime definend 24 index embed route_information embed byte length -# bits 4 and 5 are route preference, but we can't express this -embed byte reserved +# bits 4 and 5 are route preference +embed bitflags=00011 prf embed uint32 lifetime -embed ip6address prefix +embed truncated ip6address prefix # ND6 options, RFC6101 definend 25 index embed rdnss diff --git a/src/dhcpcd.conf.5.in b/src/dhcpcd.conf.5.in index 6b63c6f7..179be73e 100644 --- a/src/dhcpcd.conf.5.in +++ b/src/dhcpcd.conf.5.in @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 15, 2025 +.Dd June 12, 2025 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -957,6 +957,10 @@ The option can appear more than once and will be indexed. .It Ic array The option data is split into a space separated array, each element being the same type. +.It Ic truncated +The option might truncated from its normal length. +The end of the normal size is zero padded on expansion. +Currently this is only supported for ip6address where it's a prefix. .El .Ss Types to define The type directly affects the length of data consumed inside the option. @@ -979,6 +983,7 @@ C 00100000, etc. If the bit is not set, the flag is not printed. A flag of 0 is not printed even if the bit position is set. This is to allow reservation of the first bits while assigning the last bits. +A flag of 1 prints the bit set or unset. .It Ic int16 A signed 16bit integer, 2 bytes. .It Ic uint16 diff --git a/src/if-options.c b/src/if-options.c index 1b256fa9..3cb89f35 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -1995,6 +1995,15 @@ err_sla: return -1; } *fp++ = '\0'; + } else if (strcasecmp(arg, "truncated") == 0) { + t |= OT_TRUNCATED; + arg = strskipwhite(fp); + fp = strwhite(arg); + if (fp == NULL) { + logerrx("incomplete truncated type"); + return -1; + } + *fp++ = '\0'; } if (strcasecmp(arg, "ipaddress") == 0) t |= OT_ADDRIPV4; @@ -2084,6 +2093,10 @@ err_sla: t |= OT_RESERVED; } } + if (t & OT_TRUNCATED && t != (OT_ADDRIPV6 | OT_TRUNCATED)) { + logerrx("truncated only works for ip6address"); + return -1; + } if (opt != O_EMBED) { for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) {