1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-11 05:17:44 +03:00

network: make SendOption= also take type field

This makes SendOption= and SendRawOption= takes values in the same
format.
This commit is contained in:
Yu Watanabe 2019-11-17 23:09:53 +09:00
parent 2e5580a8c1
commit 586ec936c6
2 changed files with 92 additions and 12 deletions

View File

@ -1642,13 +1642,15 @@
<varlistentry> <varlistentry>
<term><varname>SendOption=</varname></term> <term><varname>SendOption=</varname></term>
<listitem> <listitem>
<para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number and an arbitrary <para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number, data type
data string separated with a colon and data separated with a colon (<literal><replaceable>option</replaceable>:
(<literal><replaceable>option</replaceable>:<replaceable>value</replaceable></literal>). The <replaceable>type</replaceable>:<replaceable>value</replaceable></literal>). The option
option number must be an interger in the range 1..254. Special characters in the data string may number must be an interger in the range 1..254. The type takes one of
be escaped using <literal>uint8</literal>, <literal>uint16</literal>, <literal>uint32</literal>,
<literal>ipv4address</literal>, or <literal>string</literal>.
Special characters in the data string may be escaped using
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style <ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
escapes</ulink>. This option can be specified multiple times. If an empty string is specified, escapes</ulink>. This option can be specified multiple times. If an empty string is specified,
then all options specified earlier are cleared. Defaults to unset.</para> then all options specified earlier are cleared. Defaults to unset.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1580,9 +1580,14 @@ int config_parse_dhcp_send_option(
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL; _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
_cleanup_free_ char *word = NULL, *q = NULL; _cleanup_free_ char *word = NULL, *q = NULL;
union in_addr_union addr;
DHCPOptionDataType type;
Network *network = data; Network *network = data;
uint8_t u, uint8_data;
uint16_t uint16_data;
uint32_t uint32_data;
const char *p; const char *p;
uint8_t u; void *udata;
ssize_t sz; ssize_t sz;
int r; int r;
@ -1618,14 +1623,87 @@ int config_parse_dhcp_send_option(
return 0; return 0;
} }
sz = cunescape(p, 0, &q); free(word);
if (sz < 0) { r = extract_first_word(&p, &word, ":", 0);
log_syntax(unit, LOG_ERR, filename, line, sz, if (r == -ENOMEM)
"Failed to decode option data, ignoring assignment: %s", p); return log_oom();
if (r <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid DHCP send option, ignoring assignment: %s", rvalue);
return 0; return 0;
} }
r = sd_dhcp_option_new(u, q, sz, &opt); type = dhcp_option_data_type_from_string(word);
if (type < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid DHCP send data type, ignoring assignment: %s", p);
return 0;
}
switch(type) {
case DHCP_OPTION_DATA_UINT8:{
r = safe_atou8(p, &uint8_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DHCPv4 uint8 data, ignoring assignment: %s", p);
return 0;
}
udata = &uint8_data;
sz = sizeof(uint8_t);
break;
}
case DHCP_OPTION_DATA_UINT16:{
r = safe_atou16(p, &uint16_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DHCPv4 uint16 data, ignoring assignment: %s", p);
return 0;
}
udata = &uint16_data;
sz = sizeof(uint16_t);
break;
}
case DHCP_OPTION_DATA_UINT32: {
r = safe_atou32(p, &uint32_data);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DHCPv4 uint32 data, ignoring assignment: %s", p);
return 0;
}
udata = &uint32_data;
sz = sizeof(uint32_t);
break;
}
case DHCP_OPTION_DATA_IPV4ADDRESS: {
r = in_addr_from_string(AF_INET, p, &addr);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DHCPv4 ipv4address data, ignoring assignment: %s", p);
return 0;
}
udata = &addr.in;
sz = sizeof(addr.in.s_addr);
break;
}
case DHCP_OPTION_DATA_STRING:
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);
}
udata = q;
break;
default:
return -EINVAL;
}
r = sd_dhcp_option_new(u, udata, sz, &opt);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue); "Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue);