printf(" request");
if (opt->type & OT_NOREQ)
printf(" norequest");
+ if (opt->type & OT_TRUNCATED)
+ printf(" truncated");
putchar('\n');
fflush(stdout);
}
return (ssize_t)dl;
}
if (dl < sz) {
+ if (opt->type & OT_TRUNCATED)
+ return (ssize_t)dl;
errno = EOVERFLOW;
return -1;
}
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' &&
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;
#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)))
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
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
.\" 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
.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.
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
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;
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++)
{