]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make SendOption= also take type field 14055/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 17 Nov 2019 14:09:53 +0000 (23:09 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 17 Nov 2019 14:17:29 +0000 (23:17 +0900)
This makes SendOption= and SendRawOption= takes values in the same
format.

man/systemd.network.xml
src/network/networkd-dhcp4.c

index b38ad54e03e2a6adb7de237f49650fce6be6bd88..e87ca1f28770418927a239251e8f22c6c3866aa4 100644 (file)
         <varlistentry>
           <term><varname>SendOption=</varname></term>
           <listitem>
-            <para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number and an arbitrary
-            data string separated with a colon
-            (<literal><replaceable>option</replaceable>:<replaceable>value</replaceable></literal>). The
-            option number must be an interger in the range 1..254. Special characters in the data string may
-            be escaped using
+            <para>Send an arbitrary option in the DHCPv4 request. Takes a DHCP option number, data type
+            and data separated with a colon (<literal><replaceable>option</replaceable>:
+            <replaceable>type</replaceable>:<replaceable>value</replaceable></literal>). The option
+            number must be an interger in the range 1..254. The type takes one of
+            <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
-            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>
           </listitem>
         </varlistentry>
index 947853e2c4bf8dc20e30e6bdaa10343d1d55144e..7504e4eb2782546d6e4f7721ff49993a87fc1408 100644 (file)
@@ -1580,9 +1580,14 @@ int config_parse_dhcp_send_option(
 
         _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt = NULL, *old = NULL;
         _cleanup_free_ char *word = NULL, *q = NULL;
+        union in_addr_union addr;
+        DHCPOptionDataType type;
         Network *network = data;
+        uint8_t u, uint8_data;
+        uint16_t uint16_data;
+        uint32_t uint32_data;
         const char *p;
-        uint8_t u;
+        void *udata;
         ssize_t sz;
         int r;
 
@@ -1618,14 +1623,87 @@ int config_parse_dhcp_send_option(
                 return 0;
         }
 
-        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);
+        free(word);
+        r = extract_first_word(&p, &word, ":", 0);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r <= 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r,
+                           "Invalid DHCP send option, ignoring assignment: %s", rvalue);
                 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) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
                            "Failed to store DHCP send option '%s', ignoring assignment: %m", rvalue);