diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 6f08edb369..538f4b8e7b 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1640,12 +1640,16 @@ - SendOptions= + SendOption= - Send a raw option with value via DHCPv4 client. Takes a DHCP option and base64 encoded - data separated with a colon (option:value). The option ranges [1-254]. This option can be - specified multiple times. If an empty string is specified, then all options specified earlier - are cleared. Defaults to unset. + Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number and an arbitrary + data string separated with a colon + (option:value). The + option number must be an interger in the range 1..254. Special characters in the data string may + be escaped using + C-style + escapes. This option can be specified multiple times. If an empty string is specified, + then all options specified earlier are cleared. Defaults to unset. diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 70ab9b2a54..947853e2c4 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -6,7 +6,7 @@ #include "alloc-util.h" #include "dhcp-client-internal.h" -#include "hexdecoct.h" +#include "escape.h" #include "hostname-util.h" #include "parse-util.h" #include "network-internal.h" @@ -1566,7 +1566,7 @@ int config_parse_dhcp_request_options( return 0; } -int config_parse_dhcp_send_options( +int config_parse_dhcp_send_option( const char *unit, const char *filename, unsigned line, @@ -1579,12 +1579,11 @@ int config_parse_dhcp_send_options( void *userdata) { _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; - _cleanup_free_ char *word = NULL; - _cleanup_free_ void *q = NULL; + _cleanup_free_ char *word = NULL, *q = NULL; Network *network = data; const char *p; uint8_t u; - size_t sz; + ssize_t sz; int r; assert(filename); @@ -1619,10 +1618,10 @@ int config_parse_dhcp_send_options( return 0; } - r = unbase64mem(p, (size_t) -1, &q, &sz); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to decode base64 data, ignoring assignment: %s", p); + sz = cunescape(p, 0, &q); + if (sz < 0) { + log_syntax(unit, LOG_ERR, filename, line, sz, + "Failed to decode option data, ignoring assignment: %s", p); return 0; } diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h index dbaec18781..2c0ccd80df 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -27,4 +27,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_options); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 1375626e86..870a4c8886 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -175,12 +175,12 @@ DHCPv4.ListenPort, config_parse_uint16, DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0 DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type) -DHCPv4.SendOptions, config_parse_dhcp_send_options, 0, 0 +DHCPv4.SendOption, config_parse_dhcp_send_option, 0, 0 DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns) DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp) DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) -DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 +DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 0d0892fd3a..f01a20118b 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -97,7 +97,7 @@ RequestOptions= SendRelease= MaxAttempts= IPServiceType= -SendOptions= +SendOption= [DHCPv6] UseNTP= UseDNS=