Skip to content

Commit f9fbe94

Browse files
committed
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.
1 parent b1c17c3 commit f9fbe94

File tree

6 files changed

+41
-8
lines changed

6 files changed

+41
-8
lines changed

src/dhcp-common.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols)
135135
printf(" request");
136136
if (opt->type & OT_NOREQ)
137137
printf(" norequest");
138+
if (opt->type & OT_TRUNCATED)
139+
printf(" truncated");
138140
putchar('\n');
139141
fflush(stdout);
140142
}
@@ -614,6 +616,8 @@ dhcp_optlen(const struct dhcp_opt *opt, size_t dl)
614616
return (ssize_t)dl;
615617
}
616618
if (dl < sz) {
619+
if (opt->type & OT_TRUNCATED)
620+
return (ssize_t)dl;
617621
errno = EOVERFLOW;
618622
return -1;
619623
}
@@ -751,6 +755,11 @@ print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt,
751755
l < sizeof(opt->bitflags);
752756
l++, sl--)
753757
{
758+
if (opt->bitflags[l] == '1') {
759+
if (fprintf(fp, "%d", *data & (1 << sl)) == -1)
760+
goto err;
761+
continue;
762+
}
754763
/* Don't print NULL or 0 flags */
755764
if (opt->bitflags[l] != '\0' &&
756765
opt->bitflags[l] != '0' &&
@@ -808,9 +817,14 @@ print_option(FILE *fp, const char *prefix, const struct dhcp_opt *opt,
808817
goto err;
809818
data += sizeof(addr.s_addr);
810819
} else if (opt->type & OT_ADDRIPV6) {
820+
uint8_t databuf[sizeof(struct in6_addr)] = { 0 };
821+
size_t datalen = e - data >= 16 ? 16 : (size_t)(e - data);
811822
char buf[INET6_ADDRSTRLEN];
812823

813-
if (inet_ntop(AF_INET6, data, buf, sizeof(buf)) == NULL)
824+
/* avoid inet_ntop going beyond our option space by
825+
* copying out into a temporary buffer. */
826+
memcpy(databuf, data, datalen);
827+
if (inet_ntop(AF_INET6, databuf, buf, sizeof(buf)) == NULL)
814828
goto err;
815829
if (fprintf(fp, "%s", buf) == -1)
816830
goto err;

src/dhcp-common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#define OT_BITFLAG (1 << 27)
7777
#define OT_RESERVED (1 << 28)
7878
#define OT_URI (1 << 29)
79+
#define OT_TRUNCATED (1 << 30)
7980

8081
#define DHC_REQ(r, n, o) \
8182
(has_option_mask((r), (o)) && !has_option_mask((n), (o)))

src/dhcpcd-definitions-small.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ embed uint32 mtu
7171

7272
definend 24 index embed route_information
7373
embed byte length
74-
# bits 4 and 5 are route preference, but we can't express this
75-
embed byte reserved
74+
# bits 4 and 5 are route preference
75+
embed bitflags=00011 prf
7676
embed uint32 lifetime
77-
embed ip6address prefix
77+
embed truncated ip6address prefix
7878

7979
# ND6 options, RFC6101
8080
definend 25 index embed rdnss

src/dhcpcd-definitions.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,10 @@ embed uint16 lifetime
414414

415415
definend 24 index embed route_information
416416
embed byte length
417-
# bits 4 and 5 are route preference, but we can't express this
418-
embed byte reserved
417+
# bits 4 and 5 are route preference
418+
embed bitflags=00011 prf
419419
embed uint32 lifetime
420-
embed ip6address prefix
420+
embed truncated ip6address prefix
421421

422422
# ND6 options, RFC6101
423423
definend 25 index embed rdnss

src/dhcpcd.conf.5.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2525
.\" SUCH DAMAGE.
2626
.\"
27-
.Dd April 15, 2025
27+
.Dd June 12, 2025
2828
.Dt DHCPCD.CONF 5
2929
.Os
3030
.Sh NAME
@@ -957,6 +957,10 @@ The option can appear more than once and will be indexed.
957957
.It Ic array
958958
The option data is split into a space separated array, each element being
959959
the same type.
960+
.It Ic truncated
961+
The option might truncated from its normal length.
962+
The end of the normal size is zero padded on expansion.
963+
Currently this is only supported for ip6address where it's a prefix.
960964
.El
961965
.Ss Types to define
962966
The type directly affects the length of data consumed inside the option.
@@ -979,6 +983,7 @@ C 00100000, etc.
979983
If the bit is not set, the flag is not printed.
980984
A flag of 0 is not printed even if the bit position is set.
981985
This is to allow reservation of the first bits while assigning the last bits.
986+
A flag of 1 prints the bit set or unset.
982987
.It Ic int16
983988
A signed 16bit integer, 2 bytes.
984989
.It Ic uint16

src/if-options.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,15 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
19951995
return -1;
19961996
}
19971997
*fp++ = '\0';
1998+
} else if (strcasecmp(arg, "truncated") == 0) {
1999+
t |= OT_TRUNCATED;
2000+
arg = strskipwhite(fp);
2001+
fp = strwhite(arg);
2002+
if (fp == NULL) {
2003+
logerrx("incomplete truncated type");
2004+
return -1;
2005+
}
2006+
*fp++ = '\0';
19982007
}
19992008
if (strcasecmp(arg, "ipaddress") == 0)
20002009
t |= OT_ADDRIPV4;
@@ -2084,6 +2093,10 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
20842093
t |= OT_RESERVED;
20852094
}
20862095
}
2096+
if (t & OT_TRUNCATED && t != (OT_ADDRIPV6 | OT_TRUNCATED)) {
2097+
logerrx("truncated only works for ip6address");
2098+
return -1;
2099+
}
20872100
if (opt != O_EMBED) {
20882101
for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++)
20892102
{

0 commit comments

Comments
 (0)