From 33923925185e0ce9198ecc909a072f2b799c7df4 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 18 May 2020 14:46:50 +0200 Subject: [PATCH 1/3] sd-network: DHCPv6 - add support to send userclass option sd-network: DHCPv6 - add support to send userclass option 21.15. User Class Option The User Class option is used by a client to identify the type or category of users or applications it represents. The format of the User Class option is: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | OPTION_USER_CLASS | option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . user-class-data . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 26: User Class Option Format option-code OPTION_USER_CLASS (15). option-len Length of user-class-data field. user-class-data The user classes carried by the client. The length, in octets, is specified by option-len. The information contained in the data area of this option is contained in one or more opaque fields that represent the user class or classes of which the client is a member. A server selects configuration information for the client based on the classes identified in this option. For example, the User Class option can be used to configure all clients of people in the accounting department with a different printer than clients of people in the marketing department. The user class information carried in this option MUST be configurable on the client. The data area of the User Class option MUST contain one or more instances of user-class-data information. Each instance of user-class-data is formatted as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ | user-class-len | opaque-data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ Figure 27: Format of user-class-data Field --- src/libsystemd-network/dhcp6-internal.h | 1 + src/libsystemd-network/dhcp6-option.c | 30 +++++++++++++++++ src/libsystemd-network/sd-dhcp6-client.c | 43 ++++++++++++++++++++++++ src/systemd/sd-dhcp6-client.h | 4 +++ 4 files changed, 78 insertions(+) diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index db80585a22..8b651636ca 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -97,6 +97,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia); int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix); int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn); +int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class); int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen, uint8_t **optvalue); int dhcp6_option_parse_status(DHCP6Option *option, size_t len); diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index 3b7c89edd7..d1a02da35f 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -167,6 +167,36 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) { return r; } +int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class) { + _cleanup_free_ uint8_t *p = NULL; + size_t total = 0, offset = 0; + char **s; + + assert_return(buf && *buf && buflen && user_class, -EINVAL); + + STRV_FOREACH(s, user_class) { + size_t len = strlen(*s); + uint8_t *q; + + if (len > 0xffff) + return -ENAMETOOLONG; + + q = realloc(p, total + len + 2); + if (!q) + return -ENOMEM; + + p = q; + + unaligned_write_be16(&p[offset], len); + memcpy(&p[offset + 2], *s, len); + + offset += 2 + len; + total += 2 + len; + } + + return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_USER_CLASS, total, p); +} + int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Address *hint_pd_prefix) { DHCP6Option *option = (DHCP6Option *)buf; size_t i = sizeof(*option) + sizeof(pd->ia_pd); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 51716c28bb..0240f1b7c7 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -67,6 +67,7 @@ struct sd_dhcp6_client { size_t req_opts_len; char *fqdn; char *mudurl; + char **user_class; sd_event_source *receive_message; usec_t retransmit_time; uint8_t retransmit_count; @@ -385,6 +386,27 @@ int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, const char *mud return free_and_strdup(&client->mudurl, mudurl); } +int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char **user_class) { + _cleanup_strv_free_ char **s = NULL; + char **p; + + assert_return(client, -EINVAL); + assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY); + assert_return(user_class, -EINVAL); + + STRV_FOREACH(p, user_class) + if (strlen(*p) > UINT16_MAX) + return -ENAMETOOLONG; + + s = strv_copy((char **) user_class); + if (!s) + return -ENOMEM; + + client->user_class = TAKE_PTR(s); + + return 0; +} + int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) { assert_return(client, -EINVAL); assert_return(delegation, -EINVAL); @@ -565,6 +587,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->user_class) { + r = dhcp6_option_append_user_class(&opt, &optlen, client->user_class); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix); if (r < 0) @@ -611,6 +639,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->user_class) { + r = dhcp6_option_append_user_class(&opt, &optlen, client->user_class); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); if (r < 0) @@ -645,6 +679,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->user_class) { + r = dhcp6_option_append_user_class(&opt, &optlen, client->user_class); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); if (r < 0) @@ -1602,7 +1642,10 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { free(client->req_opts); free(client->fqdn); free(client->mudurl); + ordered_hashmap_free(client->extra_options); + strv_free(client->user_class); + return mfree(client); } diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index d365fc7638..8011457b76 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -125,6 +125,10 @@ int sd_dhcp6_client_set_request_option( int sd_dhcp6_client_set_request_mud_url( sd_dhcp6_client *client, const char *mudurl); + +int sd_dhcp6_client_set_request_user_class( + sd_dhcp6_client *client, + char** user_class); int sd_dhcp6_client_set_prefix_delegation_hint( sd_dhcp6_client *client, uint8_t prefixlen, From f37f2a6b8afe915e5a451eed04ecf8da62e05527 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 18 May 2020 14:49:47 +0200 Subject: [PATCH 2/3] network: DHCPv6 - Add support to send user class Frame 115: 171 bytes on wire (1368 bits), 171 bytes captured (1368 bits) on interface veth-peer, id 0 Ethernet II, Src: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4), Dst: IPv6mcast_01:00:02 (33:33:00:01:00:02) Internet Protocol Version 6, Src: fe80::1c04:f8ff:feb8:2fd4, Dst: ff02::1:2 User Datagram Protocol, Src Port: 546, Dst Port: 547 DHCPv6 Message type: Solicit (1) Transaction ID: 0x673257 Rapid Commit Option: Rapid Commit (14) Length: 0 Identity Association for Non-temporary Address Option: Identity Association for Non-temporary Address (3) Length: 12 Value: d0cc94090000000000000000 IAID: d0cc9409 T1: 0 T2: 0 Fully Qualified Domain Name Option: Fully Qualified Domain Name (39) Length: 6 Value: 01045a657573 0000 0... = Reserved: 0x00 .... .0.. = N bit: Server should perform DNS updates .... ..0. = O bit: Server has not overridden client's S bit preference .... ...1 = S bit: Server should perform forward DNS updates Client FQDN: Zeus User Class Option: User Class (15) Length: 17 Value: 000f68656c6c6f30313233343031323334 Identity Association for Prefix Delegation Option: Identity Association for Prefix Delegation (25) Length: 12 Value: d0cc94090000000000000000 IAID: d0cc9409 T1: 0 T2: 0 Option Request Option: Option Request (6) Length: 10 Value: 001700180038001f000e Requested Option code: DNS recursive name server (23) Requested Option code: Domain Search List (24) Requested Option code: NTP Server (56) Requested Option code: Simple Network Time Protocol Server (31) Requested Option code: Rapid Commit (14) Client Identifier Option: Client Identifier (1) Length: 14 Value: 00020000ab11d258482fc7eee651 DUID: 00020000ab11d258482fc7eee651 DUID Type: assigned by vendor based on Enterprise number (2) Enterprise ID: Tom Gundersen (systemd) (43793) Identifier: d258482fc7eee651 Elapsed time Option: Elapsed time (8) Length: 2 Value: 0bd0 Elapsed time: 30240ms --- man/systemd.network.xml | 14 ++++ src/network/networkd-dhcp-common.c | 65 ++++++++++++++++++- src/network/networkd-dhcp-common.h | 1 + src/network/networkd-dhcp4.c | 54 --------------- src/network/networkd-dhcp4.h | 1 - src/network/networkd-dhcp6.c | 6 ++ src/network/networkd-network-gperf.gperf | 5 +- src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + .../fuzz-network-parser/directives.network | 1 + 10 files changed, 90 insertions(+), 59 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index e6d005400b..19b49702f3 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1774,6 +1774,20 @@ option numbers, the option number is an integer in the range 1..65536. + + + UserClass= + + A DHCPv6 client can use User Class option to identify the type or category of user or applications + it represents. The information contained in this option is a string that represents the user class of which + the client is a member. Each class sets an identifying string of information to be used by the DHCP + service to classify clients. Special characters in the data string may be escaped using + C-style + escapes. This setting can be specified multiple times. If an empty string is specified, + then all options specified earlier are cleared. Takes a whitespace-separated list of strings. Note that + currently NUL bytes are not allowed. + + diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index ae1c4493c7..71ee955432 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -267,7 +267,7 @@ int config_parse_dhcp6_pd_hint( return 0; } -int config_parse_dhcp6_mud_url( +int config_parse_dhcp_user_class( const char *unit, const char *filename, unsigned line, @@ -279,6 +279,67 @@ int config_parse_dhcp6_mud_url( void *data, void *userdata) { + char ***l = data; + int r; + + assert(l); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + *l = strv_free(*l); + return 0; + } + + for (;;) { + _cleanup_free_ char *w = NULL; + + r = extract_first_word(&rvalue, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to split user classes option, ignoring: %s", rvalue); + break; + } + if (r == 0) + break; + + if (ltype == AF_INET) { + if (strlen(w) > UINT8_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "%s length is not in the range 1-255, ignoring.", w); + continue; + } + } else { + if (strlen(w) > UINT16_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "%s length is not in the range 1-65535, ignoring.", w); + continue; + } + } + + r = strv_push(l, w); + if (r < 0) + return log_oom(); + + w = NULL; + } + + return 0; +} + +int config_parse_dhcp6_mud_url( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { _cleanup_free_ char *unescaped = NULL; Network *network = data; int r; @@ -362,7 +423,7 @@ int config_parse_dhcp_send_option( "Invalid DHCP option, ignoring assignment: %s", rvalue); return 0; } - if (u16 < 1 || u16 >= 65535) { + if (u16 < 1 || u16 >= UINT16_MAX) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue); return 0; diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index efadcebe21..bf8bc2bf67 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -50,5 +50,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 7d52a3a6a1..6bfa6e6dd0 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1605,60 +1605,6 @@ int config_parse_dhcp_black_listed_ip_address( return 0; } -int config_parse_dhcp_user_class( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - char ***l = data; - int r; - - assert(l); - assert(lvalue); - assert(rvalue); - - if (isempty(rvalue)) { - *l = strv_free(*l); - return 0; - } - - for (;;) { - _cleanup_free_ char *w = NULL; - - r = extract_first_word(&rvalue, &w, NULL, 0); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to split user classes option, ignoring: %s", rvalue); - break; - } - if (r == 0) - break; - - if (strlen(w) > 255) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "%s length is not in the range 1-255, ignoring.", w); - continue; - } - - r = strv_push(l, w); - if (r < 0) - return log_oom(); - - w = NULL; - } - - return 0; -} - int config_parse_dhcp_ip_service_type( const char *unit, const char *filename, diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h index 78e10d9299..93fa7d372c 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -25,6 +25,5 @@ int dhcp4_set_promote_secondaries(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier); 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_ip_service_type); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 05df41cd3a..a33f22880b 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -706,6 +706,12 @@ int dhcp6_configure(Link *link) { return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for '%u': %m", option); } + if (link->network->dhcp6_user_class) { + r = sd_dhcp6_client_set_request_user_class(client, link->network->dhcp6_user_class); + if (r < 0) + return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set user class: %m"); + } + r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m"); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 711bec7588..798781cfe4 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -174,7 +174,7 @@ DHCPv4.RequestBroadcast, config_parse_bool, DHCPv4.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0 DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0 -DHCPv4.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class) +DHCPv4.UserClass, config_parse_dhcp_user_class, AF_INET, offsetof(Network, dhcp_user_class) DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCPv4.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) @@ -194,6 +194,7 @@ DHCPv6.UseNTP, config_parse_bool, DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) DHCPv6.MUDURL, config_parse_dhcp6_mud_url, 0, 0 DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0 +DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class) DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.WithoutRA, config_parse_bool, 0, offsetof(Network, dhcp6_without_ra) @@ -384,7 +385,7 @@ DHCP.Hostname, config_parse_hostname, DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) -DHCP.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class) +DHCP.UserClass, config_parse_dhcp_user_class, AF_INET, offsetof(Network, dhcp_user_class) DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index a15f884ab0..1c2100d89f 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -653,6 +653,7 @@ static Network *network_free(Network *network) { set_free(network->dhcp6_request_options); free(network->mac); free(network->dhcp6_mudurl); + strv_free(network->dhcp6_user_class); if (network->dhcp_acd) sd_ipv4acd_unref(network->dhcp_acd); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 019bd7676b..8a6de4df01 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -132,6 +132,7 @@ struct Network { bool dhcp6_without_ra; uint8_t dhcp6_pd_length; char *dhcp6_mudurl; + char **dhcp6_user_class; struct in6_addr dhcp6_pd_address; OrderedHashmap *dhcp6_client_send_options; Set *dhcp6_request_options; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 743ab903ea..9ce0fc3f99 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -115,6 +115,7 @@ WithoutRA= MUDURL= SendOption= RequestOptions= +UserClass= [Route] Destination= Protocol= From ffed0205c70531ef001ff3f580091f6f233afc5f Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Tue, 19 May 2020 11:16:57 +0200 Subject: [PATCH 3/3] DHCP: Use UINT8_MAX instead of 255 --- src/network/networkd-dhcp-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 71ee955432..9ab0187d2d 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -360,7 +360,7 @@ int config_parse_dhcp6_mud_url( return 0; } - if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) { + if (!http_url_is_valid(unescaped) || strlen(unescaped) > UINT8_MAX) { log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse MUD URL '%s', ignoring: %m", rvalue); @@ -435,7 +435,7 @@ int config_parse_dhcp_send_option( "Invalid DHCP option, ignoring assignment: %s", rvalue); return 0; } - if (u8 < 1 || u8 >= 255) { + if (u8 < 1 || u8 >= UINT8_MAX) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue); return 0; @@ -631,7 +631,7 @@ int config_parse_dhcp_request_options( continue; } - if (i < 1 || i >= 255) { + if (i < 1 || i >= UINT8_MAX) { log_syntax(unit, LOG_ERR, filename, line, r, "DHCP request option is invalid, valid range is 1-254, ignoring assignment: %s", n); continue;