diff --git a/src/libsystemd-network/dhcp-client-internal.h b/src/libsystemd-network/dhcp-client-internal.h index fab4ff24aa..7db0a91fa9 100644 --- a/src/libsystemd-network/dhcp-client-internal.h +++ b/src/libsystemd-network/dhcp-client-internal.h @@ -5,9 +5,11 @@ #include "dhcp-client-id-internal.h" #include "ether-addr-util.h" +#include "iovec-wrapper.h" #include "network-common.h" #include "sd-forward.h" #include "socket-util.h" +#include "tlv-util.h" typedef enum DHCPState { DHCP_STATE_STOPPED, @@ -54,7 +56,7 @@ struct sd_dhcp_client { char *hostname; char *vendor_class_identifier; char *mudurl; - char **user_class; + struct iovec_wrapper user_class; uint32_t mtu; usec_t fallback_lease_lifetime; uint32_t xid; @@ -65,8 +67,8 @@ struct sd_dhcp_client { uint64_t discover_attempt; uint64_t request_attempt; uint64_t max_discover_attempts; - OrderedHashmap *extra_options; - OrderedHashmap *vendor_options; + TLV *extra_options; + TLV *vendor_options; sd_event_source *timeout_t1; sd_event_source *timeout_t2; sd_event_source *timeout_expire; @@ -90,6 +92,10 @@ int dhcp_client_set_state_callback( void *userdata); int dhcp_client_get_state(sd_dhcp_client *client); +int dhcp_client_set_extra_options(sd_dhcp_client *client, TLV *options); +int dhcp_client_set_vendor_options(sd_dhcp_client *client, TLV *options); +int dhcp_client_set_user_class(sd_dhcp_client *client, const struct iovec_wrapper *user_class); + int client_receive_message_raw( sd_event_source *s, int fd, diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c index a195a4b098..c5e8b29794 100644 --- a/src/libsystemd-network/dhcp-option.c +++ b/src/libsystemd-network/dhcp-option.c @@ -11,9 +11,7 @@ #include "dns-domain.h" #include "hostname-util.h" #include "memory-util.h" -#include "ordered-set.h" #include "string-util.h" -#include "strv.h" #include "utf8.h" /* Append type-length value structure to the options buffer */ @@ -58,43 +56,6 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, *offset += 1; break; - case SD_DHCP_OPTION_USER_CLASS: { - /* When called with raw data (optlen > 0), e.g. from SendOption=, append as a plain TLV. - * The structured handling below expects optval to be a strv. */ - if (optlen > 0) - return dhcp_option_append_tlv(options, size, offset, code, optlen, optval); - - size_t total = 0; - - if (strv_isempty((char **) optval)) - return -EINVAL; - - STRV_FOREACH(s, (const char* const*) optval) { - size_t len = strlen(*s); - - if (len > 255 || len == 0) - return -EINVAL; - - total += 1 + len; - } - - if (*offset + 2 + total > size) - return -ENOBUFS; - - options[*offset] = code; - options[*offset + 1] = total; - *offset += 2; - - STRV_FOREACH(s, (const char* const*) optval) { - size_t len = strlen(*s); - - options[*offset] = len; - memcpy(&options[*offset + 1], *s, len); - *offset += 1 + len; - } - - break; - } case SD_DHCP_OPTION_SIP_SERVER: if (*offset + 3 + optlen > size) return -ENOBUFS; @@ -107,33 +68,6 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, *offset += 3 + optlen; break; - case SD_DHCP_OPTION_VENDOR_SPECIFIC: { - /* When called with raw data (optlen > 0), e.g. from SendOption=, append as a plain TLV. - * The structured handling below expects optval to be an OrderedSet*. */ - if (optlen > 0) - return dhcp_option_append_tlv(options, size, offset, code, optlen, optval); - - OrderedSet *s = (OrderedSet *) optval; - struct sd_dhcp_option *p; - size_t l = 0; - - ORDERED_SET_FOREACH(p, s) - l += p->length + 2; - - if (*offset + l + 2 > size) - return -ENOBUFS; - - options[*offset] = code; - options[*offset + 1] = l; - *offset += 2; - - ORDERED_SET_FOREACH(p, s) { - r = dhcp_option_append_tlv(options, size, offset, p->option, p->length, p->data); - if (r < 0) - return r; - } - break; - } case SD_DHCP_OPTION_RELAY_AGENT_INFORMATION: { /* When called with raw data (optlen > 0), e.g. from SendOption=, append as a plain TLV. * The structured handling below expects optval to be an sd_dhcp_server*. */ @@ -462,43 +396,3 @@ int dhcp_option_parse_hostname(const uint8_t *option, size_t len, char **ret) { *ret = TAKE_PTR(hostname); return 0; } - -static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) { - if (!i) - return NULL; - - free(i->data); - return mfree(i); -} - -int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret) { - assert_return(ret, -EINVAL); - assert_return(length == 0 || data, -EINVAL); - - _cleanup_free_ void *q = memdup(data, length); - if (!q) - return -ENOMEM; - - sd_dhcp_option *p = new(sd_dhcp_option, 1); - if (!p) - return -ENOMEM; - - *p = (sd_dhcp_option) { - .n_ref = 1, - .option = option, - .length = length, - .data = TAKE_PTR(q), - }; - - *ret = TAKE_PTR(p); - return 0; -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free); -DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR( - dhcp_option_hash_ops, - void, - trivial_hash_func, - trivial_compare_func, - sd_dhcp_option, - sd_dhcp_option_unref); diff --git a/src/libsystemd-network/dhcp-option.h b/src/libsystemd-network/dhcp-option.h index 5ca1cafe38..f0afd892e6 100644 --- a/src/libsystemd-network/dhcp-option.h +++ b/src/libsystemd-network/dhcp-option.h @@ -1,21 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "sd-dhcp-option.h" /* IWYU pragma: export */ - #include "dhcp-protocol.h" #include "sd-forward.h" -#include "hash-funcs.h" - -struct sd_dhcp_option { - unsigned n_ref; - - uint8_t option; - void *data; - size_t length; -}; - -extern const struct hash_ops dhcp_option_hash_ops; typedef struct DHCPServerData { struct in_addr *addr; diff --git a/src/libsystemd-network/dhcp-protocol.c b/src/libsystemd-network/dhcp-protocol.c index 3a22e0f225..caf92c494e 100644 --- a/src/libsystemd-network/dhcp-protocol.c +++ b/src/libsystemd-network/dhcp-protocol.c @@ -34,157 +34,157 @@ static const char * const dhcp_message_type_table[_DHCP_MESSAGE_TYPE_MAX] = { DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dhcp_message_type, DHCPMessageType); static const char * const dhcp_option_code_table[] = { - [SD_DHCP_OPTION_PAD] = "pad", - [SD_DHCP_OPTION_SUBNET_MASK] = "subnet mask", - [SD_DHCP_OPTION_TIME_OFFSET] = "time offset", - [SD_DHCP_OPTION_ROUTER] = "router", - [SD_DHCP_OPTION_TIME_SERVER] = "time server", - [SD_DHCP_OPTION_NAME_SERVER] = "name server", - [SD_DHCP_OPTION_DOMAIN_NAME_SERVER] = "domain name server", - [SD_DHCP_OPTION_LOG_SERVER] = "log server", - [SD_DHCP_OPTION_QUOTES_SERVER] = "quotes server", - [SD_DHCP_OPTION_LPR_SERVER] = "LPR server", - [SD_DHCP_OPTION_IMPRESS_SERVER] = "impress server", - [SD_DHCP_OPTION_RLP_SERVER] = "RLP server", - [SD_DHCP_OPTION_HOST_NAME] = "hostname", - [SD_DHCP_OPTION_BOOT_FILE_SIZE] = "boot file size", - [SD_DHCP_OPTION_MERIT_DUMP_FILE] = "merit dump file", - [SD_DHCP_OPTION_DOMAIN_NAME] = "domain name", - [SD_DHCP_OPTION_SWAP_SERVER] = "swap server", - [SD_DHCP_OPTION_ROOT_PATH] = "root path", - [SD_DHCP_OPTION_EXTENSION_FILE] = "extension file", - [SD_DHCP_OPTION_FORWARD] = "IP forwarding", - [SD_DHCP_OPTION_SOURCE_ROUTE] = "source routing", - [SD_DHCP_OPTION_POLICY_FILTER] = "policy filter", - [SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY] = "max datagram assembly", - [SD_DHCP_OPTION_DEFAULT_IP_TTL] = "default IP TTL", - [SD_DHCP_OPTION_MTU_TIMEOUT] = "MTU timeout", - [SD_DHCP_OPTION_MTU_PLATEAU] = "MTU plateau", - [SD_DHCP_OPTION_MTU_INTERFACE] = "MTU size", - [SD_DHCP_OPTION_MTU_SUBNET] = "MTU subnet", - [SD_DHCP_OPTION_BROADCAST] = "broadcast address", - [SD_DHCP_OPTION_MASK_DISCOVERY] = "mask discovery", - [SD_DHCP_OPTION_MASK_SUPPLIER] = "mask supplier", - [SD_DHCP_OPTION_ROUTER_DISCOVERY] = "router discovery", - [SD_DHCP_OPTION_ROUTER_REQUEST] = "router request", - [SD_DHCP_OPTION_STATIC_ROUTE] = "static route", - [SD_DHCP_OPTION_TRAILERS] = "trailers", - [SD_DHCP_OPTION_ARP_TIMEOUT] = "ARP timeout", - [SD_DHCP_OPTION_ETHERNET] = "Ethernet encapsulation", - [SD_DHCP_OPTION_DEFAULT_TCP_TTL] = "default TCP TTL", - [SD_DHCP_OPTION_KEEPALIVE_TIME] = "keepalive time", - [SD_DHCP_OPTION_KEEPALIVE_DATA] = "keepalive data", - [SD_DHCP_OPTION_NIS_DOMAIN] = "NIS domain", - [SD_DHCP_OPTION_NIS_SERVER] = "NIS server", - [SD_DHCP_OPTION_NTP_SERVER] = "NTP server", - [SD_DHCP_OPTION_VENDOR_SPECIFIC] = "vendor specific", - [SD_DHCP_OPTION_NETBIOS_NAME_SERVER] = "NETBIOS name server", - [SD_DHCP_OPTION_NETBIOS_DIST_SERVER] = "NETBIOS distribution server", - [SD_DHCP_OPTION_NETBIOS_NODE_TYPE] = "NETBIOS node type", - [SD_DHCP_OPTION_NETBIOS_SCOPE] = "NETBIOS scope", - [SD_DHCP_OPTION_X_WINDOW_FONT] = "X Window font", - [SD_DHCP_OPTION_X_WINDOW_MANAGER] = "X Window manager", - [SD_DHCP_OPTION_REQUESTED_IP_ADDRESS] = "requested IP address", - [SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME] = "lease time", - [SD_DHCP_OPTION_OVERLOAD] = "overload", - [SD_DHCP_OPTION_MESSAGE_TYPE] = "message type", - [SD_DHCP_OPTION_SERVER_IDENTIFIER] = "server identifier", - [SD_DHCP_OPTION_PARAMETER_REQUEST_LIST] = "parameter request list", - [SD_DHCP_OPTION_ERROR_MESSAGE] = "error message", - [SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE] = "max message size", - [SD_DHCP_OPTION_RENEWAL_TIME] = "renewal time", - [SD_DHCP_OPTION_REBINDING_TIME] = "rebinding time", - [SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER] = "vendor class identifier", - [SD_DHCP_OPTION_CLIENT_IDENTIFIER] = "client identifier", - [SD_DHCP_OPTION_NETWARE_IP_DOMAIN] = "NetWare IP domain", - [SD_DHCP_OPTION_NETWARE_IP_OPTION] = "NetWare IP option", - [SD_DHCP_OPTION_NIS_DOMAIN_NAME] = "NIS+ v3 domain", - [SD_DHCP_OPTION_NIS_SERVER_ADDR] = "NIS+ v3 server", - [SD_DHCP_OPTION_BOOT_SERVER_NAME] = "TFTP server name", - [SD_DHCP_OPTION_BOOT_FILENAME] = "boot file name", - [SD_DHCP_OPTION_HOME_AGENT_ADDRESS] = "home agent address", - [SD_DHCP_OPTION_SMTP_SERVER] = "SMTP server", - [SD_DHCP_OPTION_POP3_SERVER] = "POP3 server", - [SD_DHCP_OPTION_NNTP_SERVER] = "NNTP server", - [SD_DHCP_OPTION_WWW_SERVER] = "WWW server", - [SD_DHCP_OPTION_FINGER_SERVER] = "finger server", - [SD_DHCP_OPTION_IRC_SERVER] = "IRC server", - [SD_DHCP_OPTION_STREETTALK_SERVER] = "StreetTalk server", - [SD_DHCP_OPTION_STDA_SERVER] = "STDA server", - [SD_DHCP_OPTION_USER_CLASS] = "user class", - [SD_DHCP_OPTION_DIRECTORY_AGENT] = "directory agent", - [SD_DHCP_OPTION_SERVICE_SCOPE] = "service scope", - [SD_DHCP_OPTION_RAPID_COMMIT] = "rapid commit", - [SD_DHCP_OPTION_FQDN] = "FQDN", - [SD_DHCP_OPTION_RELAY_AGENT_INFORMATION] = "relay agent information", - [SD_DHCP_OPTION_ISNS] = "iSNS", - [SD_DHCP_OPTION_NDS_SERVER] = "NDS server", - [SD_DHCP_OPTION_NDS_TREE_NAME] = "NDS tree name", - [SD_DHCP_OPTION_NDS_CONTEXT] = "NDS context", - [SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAME] = "BCMCS controller domain name", - [SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS] = "BCMCS controller address", - [SD_DHCP_OPTION_AUTHENTICATION] = "authentication", - [SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME] = "client last transaction time", - [SD_DHCP_OPTION_ASSOCIATED_IP] = "associated IP", - [SD_DHCP_OPTION_CLIENT_SYSTEM] = "client system", - [SD_DHCP_OPTION_CLIENT_NDI] = "client NDI", - [SD_DHCP_OPTION_LDAP] = "LDAP", - [SD_DHCP_OPTION_UUID] = "UUID", - [SD_DHCP_OPTION_USER_AUTHENTICATION] = "user authentication", - [SD_DHCP_OPTION_GEOCONF_CIVIC] = "geoconf civic", - [SD_DHCP_OPTION_POSIX_TIMEZONE] = "posix timezone", - [SD_DHCP_OPTION_TZDB_TIMEZONE] = "tzdb timezone", - [SD_DHCP_OPTION_IPV6_ONLY_PREFERRED] = "IPv6-only preferred", - [SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS] = "DHCPv4 over DHCPv6 source address", - [SD_DHCP_OPTION_NETINFO_ADDRESS] = "Netinfo address", - [SD_DHCP_OPTION_NETINFO_TAG] = "Netinfo tag", - [SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL] = "captive portal", - [SD_DHCP_OPTION_AUTO_CONFIG] = "auto config", - [SD_DHCP_OPTION_NAME_SERVICE_SEARCH] = "name service search", - [SD_DHCP_OPTION_SUBNET_SELECTION] = "subnet selection", - [SD_DHCP_OPTION_DOMAIN_SEARCH] = "domain search", - [SD_DHCP_OPTION_SIP_SERVER] = "SIP server", - [SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE] = "classless static route", - [SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION] = "CableLabs client configuration", - [SD_DHCP_OPTION_GEOCONF] = "geoconf", - [SD_DHCP_OPTION_VENDOR_CLASS] = "vendor class", - [SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION] = "vendor specific information", - [SD_DHCP_OPTION_PANA_AGENT] = "PANA agent", - [SD_DHCP_OPTION_LOST_SERVER_FQDN] = "LoST server", - [SD_DHCP_OPTION_CAPWAP_AC_ADDRESS] = "CAPWAP access controller address", - [SD_DHCP_OPTION_MOS_ADDRESS] = "MoS address", - [SD_DHCP_OPTION_MOS_FQDN] = "MoS FQDN", - [SD_DHCP_OPTION_SIP_SERVICE_DOMAIN] = "SIP service domain", - [SD_DHCP_OPTION_ANDSF_ADDRESS] = "ANDSF address", - [SD_DHCP_OPTION_SZTP_REDIRECT] = "SZTP server", - [SD_DHCP_OPTION_GEOLOC] = "geospatial location", - [SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE] = "forcerenew nonce capable", - [SD_DHCP_OPTION_RDNSS_SELECTION] = "RDNSS selection", - [SD_DHCP_OPTION_DOTS_RI] = "DOTS agent name", - [SD_DHCP_OPTION_DOTS_ADDRESS] = "DOTS agent address", - [SD_DHCP_OPTION_TFTP_SERVER_ADDRESS] = "TFTP server address", - [SD_DHCP_OPTION_STATUS_CODE] = "status code", - [SD_DHCP_OPTION_BASE_TIME] = "base time", - [SD_DHCP_OPTION_START_TIME_OF_STATE] = "start time of state", - [SD_DHCP_OPTION_QUERY_START_TIME] = "query start time", - [SD_DHCP_OPTION_QUERY_END_TIME] = "query end time", - [SD_DHCP_OPTION_DHCP_STATE] = "DHCP state", - [SD_DHCP_OPTION_DATA_SOURCE] = "data source", - [SD_DHCP_OPTION_PCP_SERVER] = "PCP server", - [SD_DHCP_OPTION_PORT_PARAMS] = "port parameter", - [SD_DHCP_OPTION_MUD_URL] = "MUD URL", - [SD_DHCP_OPTION_V4_DNR] = "encrypted DNS server", - [SD_DHCP_OPTION_PXELINUX_MAGIC] = "PXELinux magic", - [SD_DHCP_OPTION_CONFIGURATION_FILE] = "configuration file", - [SD_DHCP_OPTION_PATH_PREFIX] = "path prefix", - [SD_DHCP_OPTION_REBOOT_TIME] = "reboot time", - [SD_DHCP_OPTION_6RD] = "6rd", - [SD_DHCP_OPTION_ACCESS_DOMAIN] = "access network domain", - [SD_DHCP_OPTION_SUBNET_ALLOCATION] = "subnet allocation", - [SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION] = "virtual subnet selection", - [SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE] = "(private) classless static route", - [SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY] = "(private) proxy autodiscovery", - [SD_DHCP_OPTION_END] = "end", + [SD_DHCP_OPTION_PAD] = "pad", + [SD_DHCP_OPTION_SUBNET_MASK] = "subnet mask", + [SD_DHCP_OPTION_TIME_OFFSET] = "time offset", + [SD_DHCP_OPTION_ROUTER] = "router", + [SD_DHCP_OPTION_TIME_SERVER] = "time server", + [SD_DHCP_OPTION_NAME_SERVER] = "name server", + [SD_DHCP_OPTION_DOMAIN_NAME_SERVER] = "domain name server", + [SD_DHCP_OPTION_LOG_SERVER] = "log server", + [SD_DHCP_OPTION_QUOTES_SERVER] = "quotes server", + [SD_DHCP_OPTION_LPR_SERVER] = "LPR server", + [SD_DHCP_OPTION_IMPRESS_SERVER] = "impress server", + [SD_DHCP_OPTION_RLP_SERVER] = "RLP server", + [SD_DHCP_OPTION_HOST_NAME] = "hostname", + [SD_DHCP_OPTION_BOOT_FILE_SIZE] = "boot file size", + [SD_DHCP_OPTION_MERIT_DUMP_FILE] = "merit dump file", + [SD_DHCP_OPTION_DOMAIN_NAME] = "domain name", + [SD_DHCP_OPTION_SWAP_SERVER] = "swap server", + [SD_DHCP_OPTION_ROOT_PATH] = "root path", + [SD_DHCP_OPTION_EXTENSION_FILE] = "extension file", + [SD_DHCP_OPTION_FORWARD] = "IP forwarding", + [SD_DHCP_OPTION_SOURCE_ROUTE] = "source routing", + [SD_DHCP_OPTION_POLICY_FILTER] = "policy filter", + [SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY] = "max datagram assembly", + [SD_DHCP_OPTION_DEFAULT_IP_TTL] = "default IP TTL", + [SD_DHCP_OPTION_MTU_TIMEOUT] = "MTU timeout", + [SD_DHCP_OPTION_MTU_PLATEAU] = "MTU plateau", + [SD_DHCP_OPTION_MTU_INTERFACE] = "MTU size", + [SD_DHCP_OPTION_MTU_SUBNET] = "MTU subnet", + [SD_DHCP_OPTION_BROADCAST] = "broadcast address", + [SD_DHCP_OPTION_MASK_DISCOVERY] = "mask discovery", + [SD_DHCP_OPTION_MASK_SUPPLIER] = "mask supplier", + [SD_DHCP_OPTION_ROUTER_DISCOVERY] = "router discovery", + [SD_DHCP_OPTION_ROUTER_REQUEST] = "router request", + [SD_DHCP_OPTION_STATIC_ROUTE] = "static route", + [SD_DHCP_OPTION_TRAILERS] = "trailers", + [SD_DHCP_OPTION_ARP_TIMEOUT] = "ARP timeout", + [SD_DHCP_OPTION_ETHERNET] = "Ethernet encapsulation", + [SD_DHCP_OPTION_DEFAULT_TCP_TTL] = "default TCP TTL", + [SD_DHCP_OPTION_KEEPALIVE_TIME] = "keepalive time", + [SD_DHCP_OPTION_KEEPALIVE_DATA] = "keepalive data", + [SD_DHCP_OPTION_NIS_DOMAIN] = "NIS domain", + [SD_DHCP_OPTION_NIS_SERVER] = "NIS server", + [SD_DHCP_OPTION_NTP_SERVER] = "NTP server", + [SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION] = "vendor-specific information", + [SD_DHCP_OPTION_NETBIOS_NAME_SERVER] = "NETBIOS name server", + [SD_DHCP_OPTION_NETBIOS_DIST_SERVER] = "NETBIOS distribution server", + [SD_DHCP_OPTION_NETBIOS_NODE_TYPE] = "NETBIOS node type", + [SD_DHCP_OPTION_NETBIOS_SCOPE] = "NETBIOS scope", + [SD_DHCP_OPTION_X_WINDOW_FONT] = "X Window font", + [SD_DHCP_OPTION_X_WINDOW_MANAGER] = "X Window manager", + [SD_DHCP_OPTION_REQUESTED_IP_ADDRESS] = "requested IP address", + [SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME] = "lease time", + [SD_DHCP_OPTION_OVERLOAD] = "overload", + [SD_DHCP_OPTION_MESSAGE_TYPE] = "message type", + [SD_DHCP_OPTION_SERVER_IDENTIFIER] = "server identifier", + [SD_DHCP_OPTION_PARAMETER_REQUEST_LIST] = "parameter request list", + [SD_DHCP_OPTION_ERROR_MESSAGE] = "error message", + [SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE] = "max message size", + [SD_DHCP_OPTION_RENEWAL_TIME] = "renewal time", + [SD_DHCP_OPTION_REBINDING_TIME] = "rebinding time", + [SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER] = "vendor class identifier", + [SD_DHCP_OPTION_CLIENT_IDENTIFIER] = "client identifier", + [SD_DHCP_OPTION_NETWARE_IP_DOMAIN] = "NetWare IP domain", + [SD_DHCP_OPTION_NETWARE_IP_OPTION] = "NetWare IP option", + [SD_DHCP_OPTION_NIS_DOMAIN_NAME] = "NIS+ v3 domain", + [SD_DHCP_OPTION_NIS_SERVER_ADDR] = "NIS+ v3 server", + [SD_DHCP_OPTION_BOOT_SERVER_NAME] = "TFTP server name", + [SD_DHCP_OPTION_BOOT_FILENAME] = "boot file name", + [SD_DHCP_OPTION_HOME_AGENT_ADDRESS] = "home agent address", + [SD_DHCP_OPTION_SMTP_SERVER] = "SMTP server", + [SD_DHCP_OPTION_POP3_SERVER] = "POP3 server", + [SD_DHCP_OPTION_NNTP_SERVER] = "NNTP server", + [SD_DHCP_OPTION_WWW_SERVER] = "WWW server", + [SD_DHCP_OPTION_FINGER_SERVER] = "finger server", + [SD_DHCP_OPTION_IRC_SERVER] = "IRC server", + [SD_DHCP_OPTION_STREETTALK_SERVER] = "StreetTalk server", + [SD_DHCP_OPTION_STDA_SERVER] = "STDA server", + [SD_DHCP_OPTION_USER_CLASS] = "user class", + [SD_DHCP_OPTION_DIRECTORY_AGENT] = "directory agent", + [SD_DHCP_OPTION_SERVICE_SCOPE] = "service scope", + [SD_DHCP_OPTION_RAPID_COMMIT] = "rapid commit", + [SD_DHCP_OPTION_FQDN] = "FQDN", + [SD_DHCP_OPTION_RELAY_AGENT_INFORMATION] = "relay agent information", + [SD_DHCP_OPTION_ISNS] = "iSNS", + [SD_DHCP_OPTION_NDS_SERVER] = "NDS server", + [SD_DHCP_OPTION_NDS_TREE_NAME] = "NDS tree name", + [SD_DHCP_OPTION_NDS_CONTEXT] = "NDS context", + [SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAME] = "BCMCS controller domain name", + [SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS] = "BCMCS controller address", + [SD_DHCP_OPTION_AUTHENTICATION] = "authentication", + [SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME] = "client last transaction time", + [SD_DHCP_OPTION_ASSOCIATED_IP] = "associated IP", + [SD_DHCP_OPTION_CLIENT_SYSTEM] = "client system", + [SD_DHCP_OPTION_CLIENT_NDI] = "client NDI", + [SD_DHCP_OPTION_LDAP] = "LDAP", + [SD_DHCP_OPTION_UUID] = "UUID", + [SD_DHCP_OPTION_USER_AUTHENTICATION] = "user authentication", + [SD_DHCP_OPTION_GEOCONF_CIVIC] = "geoconf civic", + [SD_DHCP_OPTION_POSIX_TIMEZONE] = "posix timezone", + [SD_DHCP_OPTION_TZDB_TIMEZONE] = "tzdb timezone", + [SD_DHCP_OPTION_IPV6_ONLY_PREFERRED] = "IPv6-only preferred", + [SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS] = "DHCPv4 over DHCPv6 source address", + [SD_DHCP_OPTION_NETINFO_ADDRESS] = "Netinfo address", + [SD_DHCP_OPTION_NETINFO_TAG] = "Netinfo tag", + [SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL] = "captive portal", + [SD_DHCP_OPTION_AUTO_CONFIG] = "auto config", + [SD_DHCP_OPTION_NAME_SERVICE_SEARCH] = "name service search", + [SD_DHCP_OPTION_SUBNET_SELECTION] = "subnet selection", + [SD_DHCP_OPTION_DOMAIN_SEARCH] = "domain search", + [SD_DHCP_OPTION_SIP_SERVER] = "SIP server", + [SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE] = "classless static route", + [SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION] = "CableLabs client configuration", + [SD_DHCP_OPTION_GEOCONF] = "geoconf", + [SD_DHCP_OPTION_VENDOR_IDENTIFYING_VENDOR_CLASS] = "vendor-identifying vendor class", + [SD_DHCP_OPTION_VENDOR_IDENTIFYING_VENDOR_SPECIFIC_INFORMATION] = "vendor-identifying vendor-specific information", + [SD_DHCP_OPTION_PANA_AGENT] = "PANA agent", + [SD_DHCP_OPTION_LOST_SERVER_FQDN] = "LoST server", + [SD_DHCP_OPTION_CAPWAP_AC_ADDRESS] = "CAPWAP access controller address", + [SD_DHCP_OPTION_MOS_ADDRESS] = "MoS address", + [SD_DHCP_OPTION_MOS_FQDN] = "MoS FQDN", + [SD_DHCP_OPTION_SIP_SERVICE_DOMAIN] = "SIP service domain", + [SD_DHCP_OPTION_ANDSF_ADDRESS] = "ANDSF address", + [SD_DHCP_OPTION_SZTP_REDIRECT] = "SZTP server", + [SD_DHCP_OPTION_GEOLOC] = "geospatial location", + [SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE] = "forcerenew nonce capable", + [SD_DHCP_OPTION_RDNSS_SELECTION] = "RDNSS selection", + [SD_DHCP_OPTION_DOTS_RI] = "DOTS agent name", + [SD_DHCP_OPTION_DOTS_ADDRESS] = "DOTS agent address", + [SD_DHCP_OPTION_TFTP_SERVER_ADDRESS] = "TFTP server address", + [SD_DHCP_OPTION_STATUS_CODE] = "status code", + [SD_DHCP_OPTION_BASE_TIME] = "base time", + [SD_DHCP_OPTION_START_TIME_OF_STATE] = "start time of state", + [SD_DHCP_OPTION_QUERY_START_TIME] = "query start time", + [SD_DHCP_OPTION_QUERY_END_TIME] = "query end time", + [SD_DHCP_OPTION_DHCP_STATE] = "DHCP state", + [SD_DHCP_OPTION_DATA_SOURCE] = "data source", + [SD_DHCP_OPTION_PCP_SERVER] = "PCP server", + [SD_DHCP_OPTION_PORT_PARAMS] = "port parameter", + [SD_DHCP_OPTION_MUD_URL] = "MUD URL", + [SD_DHCP_OPTION_V4_DNR] = "encrypted DNS server", + [SD_DHCP_OPTION_PXELINUX_MAGIC] = "PXELinux magic", + [SD_DHCP_OPTION_CONFIGURATION_FILE] = "configuration file", + [SD_DHCP_OPTION_PATH_PREFIX] = "path prefix", + [SD_DHCP_OPTION_REBOOT_TIME] = "reboot time", + [SD_DHCP_OPTION_6RD] = "6rd", + [SD_DHCP_OPTION_ACCESS_DOMAIN] = "access network domain", + [SD_DHCP_OPTION_SUBNET_ALLOCATION] = "subnet allocation", + [SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION] = "virtual subnet selection", + [SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE] = "(private) classless static route", + [SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY] = "(private) proxy autodiscovery", + [SD_DHCP_OPTION_END] = "end", }; DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dhcp_option_code, int); diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 8b7c856d21..a8e2cbf5c7 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -13,6 +13,7 @@ #include "sd-forward.h" #include "network-common.h" #include "sparse-endian.h" +#include "tlv-util.h" typedef enum DHCPRawOption { DHCP_RAW_OPTION_DATA_UINT8, @@ -53,8 +54,8 @@ typedef struct sd_dhcp_server { char *boot_server_name; char *boot_filename; - OrderedSet *extra_options; - OrderedSet *vendor_options; + TLV *extra_options; + TLV *vendor_options; bool emit_router; struct in_addr router_address; @@ -99,6 +100,9 @@ typedef struct DHCPRequest { triple_timestamp timestamp; } DHCPRequest; +int dhcp_server_set_extra_options(sd_dhcp_server *server, TLV *options); +int dhcp_server_set_vendor_options(sd_dhcp_server *server, TLV *options); + int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, size_t length, const triple_timestamp *timestamp); int dhcp_server_send_packet(sd_dhcp_server *server, diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index c6a4d02f96..8b517982b6 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -19,6 +19,7 @@ #include "event-util.h" #include "hostname-util.h" #include "iovec-util.h" +#include "iovec-wrapper.h" #include "memory-util.h" #include "network-common.h" #include "random-util.h" @@ -26,7 +27,6 @@ #include "sort-util.h" #include "string-table.h" #include "string-util.h" -#include "strv.h" #include "time-util.h" #include "web-util.h" @@ -65,7 +65,7 @@ static const uint8_t default_req_opts_anonymize[] = { SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */ SD_DHCP_OPTION_ROUTER_DISCOVERY, /* 31 */ SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */ - SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */ + SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION, /* 43 */ SD_DHCP_OPTION_NETBIOS_NAME_SERVER, /* 44 */ SD_DHCP_OPTION_NETBIOS_NODE_TYPE, /* 46 */ SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */ @@ -433,28 +433,30 @@ int sd_dhcp_client_set_mud_url( return free_and_strdup(&client->mudurl, mudurl); } -int sd_dhcp_client_set_user_class( - sd_dhcp_client *client, - char * const *user_class) { - - char **s = NULL; +int dhcp_client_set_user_class(sd_dhcp_client *client, const struct iovec_wrapper *user_class) { + int r; assert_return(client, -EINVAL); assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - assert_return(!strv_isempty(user_class), -EINVAL); - STRV_FOREACH(p, user_class) { - size_t n = strlen(*p); - - if (n > 255 || n == 0) - return -EINVAL; + if (iovw_isempty(user_class)) { + iovw_done_free(&client->user_class); + return 0; } - s = strv_copy(user_class); - if (!s) - return -ENOMEM; + _cleanup_(iovw_done_free) struct iovec_wrapper iovw = {}; + FOREACH_ARRAY(iovec, user_class->iovec, user_class->count) { + if (iovec->iov_len == 0 || iovec->iov_len > UINT8_MAX) + return -EINVAL; - return strv_free_and_replace(client->user_class, s); + r = iovw_extend_iov(&iovw, iovec); + if (r < 0) + return r; + } + + iovw_done_free(&client->user_class); + client->user_class = TAKE_STRUCT(iovw); + return 0; } int sd_dhcp_client_set_client_port( @@ -502,39 +504,18 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt return 0; } -int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v) { - int r; +int dhcp_client_set_extra_options(sd_dhcp_client *client, TLV *options) { + assert(client); + assert(!sd_dhcp_client_is_running(client)); - assert_return(client, -EINVAL); - assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - assert_return(v, -EINVAL); - - r = ordered_hashmap_ensure_put(&client->extra_options, &dhcp_option_hash_ops, UINT_TO_PTR(v->option), v); - if (r < 0) - return r; - - sd_dhcp_option_ref(v); - return 0; + return unref_and_replace_new_ref(client->extra_options, options, tlv_ref, tlv_unref); } -int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v) { - int r; +int dhcp_client_set_vendor_options(sd_dhcp_client *client, TLV *options) { + assert(client); + assert(!sd_dhcp_client_is_running(client)); - assert_return(client, -EINVAL); - assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - assert_return(v, -EINVAL); - - r = ordered_hashmap_ensure_allocated(&client->vendor_options, &dhcp_option_hash_ops); - if (r < 0) - return -ENOMEM; - - r = ordered_hashmap_put(client->vendor_options, v, v); - if (r < 0) - return r; - - sd_dhcp_option_ref(v); - - return 1; + return unref_and_replace_new_ref(client->vendor_options, options, tlv_ref, tlv_unref); } int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) { @@ -912,7 +893,6 @@ static int client_append_fqdn_option( } static int client_append_common_discover_request_options(sd_dhcp_client *client, DHCPPacket *packet, size_t *optoffset, size_t optlen) { - sd_dhcp_option *j; int r; assert(client); @@ -954,26 +934,53 @@ static int client_append_common_discover_request_options(sd_dhcp_client *client, return r; } - if (client->user_class) { - r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0, - SD_DHCP_OPTION_USER_CLASS, - /* optlen= */ 0, client->user_class); - if (r < 0) - return r; + if (!iovw_isempty(&client->user_class)) { + size_t sz = iovw_size(&client->user_class) + client->user_class.count; + if (sz <= UINT8_MAX) { + _cleanup_free_ uint8_t *buf = new(uint8_t, sz); + if (!buf) + return -ENOMEM; + + uint8_t *p = buf; + FOREACH_ARRAY(iovec, client->user_class.iovec, client->user_class.count) { + assert(iovec->iov_len > 0 && iovec->iov_len <= UINT8_MAX); + *p++ = iovec->iov_len; + p = mempcpy(p, iovec->iov_base, iovec->iov_len); + } + + r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0, + SD_DHCP_OPTION_USER_CLASS, + sz, buf); + if (r < 0) + return r; + } } - ORDERED_HASHMAP_FOREACH(j, client->extra_options) { - r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0, - j->option, j->length, j->data); - if (r < 0) - return r; + if (client->extra_options) { + void *key; + struct iovec_wrapper *iovw; + HASHMAP_FOREACH_KEY(iovw, key, client->extra_options->entries) { + uint32_t tag = PTR_TO_UINT32(key); + + FOREACH_ARRAY(iov, iovw->iovec, iovw->count) { + r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0, + tag, iov->iov_len, iov->iov_base); + if (r < 0) + return r; + } + } } - if (!ordered_hashmap_isempty(client->vendor_options)) { + if (!tlv_isempty(client->vendor_options)) { + _cleanup_(iovec_done) struct iovec iov = {}; + r = tlv_build(client->vendor_options, &iov); + if (r < 0) + return r; + r = dhcp_option_append( &packet->dhcp, optlen, optoffset, 0, - SD_DHCP_OPTION_VENDOR_SPECIFIC, - /* optlen= */ 0, client->vendor_options); + SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION, + iov.iov_len, iov.iov_base); if (r < 0) return r; } @@ -2305,9 +2312,9 @@ static sd_dhcp_client* dhcp_client_free(sd_dhcp_client *client) { free(client->hostname); free(client->vendor_class_identifier); free(client->mudurl); - client->user_class = strv_free(client->user_class); - ordered_hashmap_free(client->extra_options); - ordered_hashmap_free(client->vendor_options); + iovw_done_free(&client->user_class); + tlv_unref(client->extra_options); + tlv_unref(client->vendor_options); free(client->ifname); return mfree(client); } diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index fa41d293da..1eec439d81 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -1092,7 +1092,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void break; - case SD_DHCP_OPTION_VENDOR_SPECIFIC: + case SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION: if (len <= 0) lease->vendor_specific = mfree(lease->vendor_specific); diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index ba2b035821..48c481809f 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -16,11 +16,12 @@ #include "dns-domain.h" #include "errno-util.h" #include "fd-util.h" +#include "hashmap.h" #include "in-addr-util.h" #include "iovec-util.h" +#include "iovec-wrapper.h" #include "memory-util.h" #include "network-common.h" -#include "ordered-set.h" #include "path-util.h" #include "siphash24.h" #include "socket-util.h" @@ -138,8 +139,8 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) { server->static_leases_by_address = hashmap_free(server->static_leases_by_address); server->static_leases_by_client_id = hashmap_free(server->static_leases_by_client_id); - ordered_set_free(server->extra_options); - ordered_set_free(server->vendor_options); + tlv_unref(server->extra_options); + tlv_unref(server->vendor_options); free(server->agent_circuit_id); free(server->agent_remote_id); @@ -618,7 +619,6 @@ static int server_send_offer_or_ack( }; _cleanup_free_ DHCPPacket *packet = NULL; - sd_dhcp_option *j; be32_t lease_time; size_t offset; int r; @@ -718,18 +718,31 @@ static int server_send_offer_or_ack( return r; } - ORDERED_SET_FOREACH(j, server->extra_options) { - r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, - j->option, j->length, j->data); - if (r < 0) - return r; + if (server->extra_options) { + void *key; + struct iovec_wrapper *iovw; + HASHMAP_FOREACH_KEY(iovw, key, server->extra_options->entries) { + uint32_t tag = PTR_TO_UINT32(key); + + FOREACH_ARRAY(iov, iovw->iovec, iovw->count) { + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, + tag, iov->iov_len, iov->iov_base); + if (r < 0) + return r; + } + } } - if (!ordered_set_isempty(server->vendor_options)) { + if (!tlv_isempty(server->vendor_options)) { + _cleanup_(iovec_done) struct iovec iov = {}; + r = tlv_build(server->vendor_options, &iov); + if (r < 0) + return r; + r = dhcp_option_append( &packet->dhcp, req->max_optlen, &offset, 0, - SD_DHCP_OPTION_VENDOR_SPECIFIC, - /* optlen= */ 0, server->vendor_options); + SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION, + iov.iov_len, iov.iov_base); if (r < 0) return r; } @@ -1611,33 +1624,14 @@ int sd_dhcp_server_set_router(sd_dhcp_server *server, const struct in_addr *rout return 0; } -int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v) { - int r; - - assert_return(server, -EINVAL); - assert_return(v, -EINVAL); - - r = ordered_set_ensure_put(&server->extra_options, &dhcp_option_hash_ops, v); - if (r < 0) - return r; - - sd_dhcp_option_ref(v); - return 0; +int dhcp_server_set_extra_options(sd_dhcp_server *server, TLV *options) { + assert(server); + return unref_and_replace_new_ref(server->extra_options, options, tlv_ref, tlv_unref); } -int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v) { - int r; - - assert_return(server, -EINVAL); - assert_return(v, -EINVAL); - - r = ordered_set_ensure_put(&server->vendor_options, &dhcp_option_hash_ops, v); - if (r < 0) - return r; - - sd_dhcp_option_ref(v); - - return 1; +int dhcp_server_set_vendor_options(sd_dhcp_server *server, TLV *options) { + assert(server); + return unref_and_replace_new_ref(server->vendor_options, options, tlv_ref, tlv_unref); } int sd_dhcp_server_set_callback(sd_dhcp_server *server, sd_dhcp_server_callback_t cb, void *userdata) { diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 3e7cca991b..5d83835580 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -11,12 +11,12 @@ #include "alloc-util.h" #include "bus-error.h" #include "bus-locator.h" -#include "dhcp-option.h" #include "dhcp6-option.h" #include "escape.h" #include "extract-word.h" #include "hexdecoct.h" #include "in-addr-prefix-util.h" +#include "iovec-util.h" #include "networkd-dhcp-common.h" #include "networkd-dhcp-prefix-delegation.h" #include "networkd-link.h" @@ -636,7 +636,52 @@ int config_parse_iaid( return 0; } -int config_parse_dhcp_user_or_vendor_class( +int config_parse_dhcp4_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) { + + struct iovec_wrapper *iovw = ASSERT_PTR(data); + int r; + + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + iovw_done_free(iovw); + return 0; + } + + for (const char *p = rvalue;;) { + _cleanup_free_ char *w = NULL; + + r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + if (r == 0) + return 0; + + size_t len = strlen(w); + if (len > UINT8_MAX || len == 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "The length of the %s entry '%s' is not in the range 1…255, ignoring.", lvalue, w); + continue; + } + + r = iovw_consume(iovw, TAKE_PTR(w), len); + if (r < 0) + return log_oom(); + } +} + +int config_parse_dhcp6_user_or_vendor_class( const char *unit, const char *filename, unsigned line, @@ -653,7 +698,6 @@ int config_parse_dhcp_user_or_vendor_class( assert(lvalue); assert(rvalue); - assert(IN_SET(ltype, AF_INET, AF_INET6)); if (isempty(rvalue)) { *l = strv_free(*l); @@ -662,32 +706,18 @@ int config_parse_dhcp_user_or_vendor_class( for (const char *p = rvalue;;) { _cleanup_free_ char *w = NULL; - size_t len; r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to split user classes option, ignoring: %s", rvalue); - return 0; - } + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); if (r == 0) return 0; - len = strlen(w); - if (ltype == AF_INET) { - if (len > UINT8_MAX || len == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "%s length is not in the range 1…255, ignoring.", w); - continue; - } - } else { - if (len > UINT16_MAX || len == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "%s length is not in the range 1…65535, ignoring.", w); - continue; - } + size_t len = strlen(w); + if (len > UINT16_MAX || len == 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "The length of the %s entry '%s' is not in the range 1…65535, ignoring.", lvalue, w); + continue; } r = strv_consume(l, TAKE_PTR(w)); @@ -696,7 +726,7 @@ int config_parse_dhcp_user_or_vendor_class( } } -int config_parse_dhcp_send_option( +int config_parse_dhcp6_send_option( const char *unit, const char *filename, unsigned line, @@ -708,17 +738,15 @@ int config_parse_dhcp_send_option( void *data, void *userdata) { - _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL; _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL; - _unused_ _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *old4 = NULL; _unused_ _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *old6 = NULL; uint32_t uint32_data, enterprise_identifier = 0; _cleanup_free_ char *word = NULL, *q = NULL; - OrderedHashmap **options = ASSERT_PTR(data); + OrderedHashmap **dhcp6_options = ASSERT_PTR(data); uint16_t u16, uint16_data; union in_addr_union addr; DHCPOptionDataType type; - uint8_t u8, uint8_data; + uint8_t uint8_data; const void *udata; const char *p; ssize_t sz; @@ -729,12 +757,12 @@ int config_parse_dhcp_send_option( assert(rvalue); if (isempty(rvalue)) { - *options = ordered_hashmap_free(*options); + *dhcp6_options = ordered_hashmap_free(*dhcp6_options); return 0; } p = rvalue; - if (ltype == AF_INET6 && streq(lvalue, "SendVendorOption")) { + if (streq(lvalue, "SendVendorOption")) { r = extract_first_word(&p, &word, ":", 0); if (r == -ENOMEM) return log_oom(); @@ -762,30 +790,16 @@ int config_parse_dhcp_send_option( return 0; } - if (ltype == AF_INET6) { - r = safe_atou16(word, &u16); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid DHCP option, ignoring assignment: %s", rvalue); - return 0; - } - if (u16 < 1 || u16 >= UINT16_MAX) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue); - return 0; - } - } else { - r = safe_atou8(word, &u8); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid DHCP option, ignoring assignment: %s", rvalue); - return 0; - } - if (u8 < 1 || u8 >= UINT8_MAX) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid DHCP option, valid range is 1-254, ignoring assignment: %s", rvalue); - return 0; - } + r = safe_atou16(word, &u16); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid DHCP option, ignoring assignment: %s", rvalue); + return 0; + } + if (u16 < 1 || u16 >= UINT16_MAX) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid DHCP option, valid range is 1-65535, ignoring assignment: %s", rvalue); + return 0; } word = mfree(word); @@ -887,49 +901,193 @@ int config_parse_dhcp_send_option( return -EINVAL; } - if (ltype == AF_INET6) { - r = sd_dhcp6_option_new(u16, udata, sz, enterprise_identifier, &opt6); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); - return 0; - } - - r = ordered_hashmap_ensure_allocated(options, &dhcp6_option_hash_ops); - if (r < 0) - return log_oom(); - - /* Overwrite existing option */ - old6 = ordered_hashmap_get(*options, UINT_TO_PTR(u16)); - r = ordered_hashmap_replace(*options, UINT_TO_PTR(u16), opt6); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); - return 0; - } - TAKE_PTR(opt6); - } else { - r = sd_dhcp_option_new(u8, udata, sz, &opt4); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); - return 0; - } - - r = ordered_hashmap_ensure_allocated(options, &dhcp_option_hash_ops); - if (r < 0) - return log_oom(); - - /* Overwrite existing option */ - old4 = ordered_hashmap_get(*options, UINT_TO_PTR(u8)); - r = ordered_hashmap_replace(*options, UINT_TO_PTR(u8), opt4); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); - return 0; - } - TAKE_PTR(opt4); + r = sd_dhcp6_option_new(u16, udata, sz, enterprise_identifier, &opt6); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); + return 0; } + + r = ordered_hashmap_ensure_allocated(dhcp6_options, &dhcp6_option_hash_ops); + if (r < 0) + return log_oom(); + + /* Overwrite existing option */ + old6 = ordered_hashmap_get(*dhcp6_options, UINT_TO_PTR(u16)); + r = ordered_hashmap_replace(*dhcp6_options, UINT_TO_PTR(u16), opt6); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); + return 0; + } + TAKE_PTR(opt6); + + return 0; +} + +int config_parse_dhcp_option( + 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) { + + struct iovec *iov = ASSERT_PTR(data); + bool check_length = ltype; + int r; + + if (isempty(rvalue)) { + iovec_done(iov); + return 0; + } + + _cleanup_free_ char *word = NULL; + const char *p = rvalue; + r = extract_first_word(&p, &word, ":", 0); + if (r == -ENOMEM) + return log_oom(); + if (r <= 0 || isempty(p)) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + DHCPOptionDataType type = dhcp_option_data_type_from_string(word); + if (type < 0) + return log_syntax_parse_error(unit, filename, line, type, lvalue, rvalue); + + switch (type) { + case DHCP_OPTION_DATA_UINT8:{ + uint8_t u; + + r = safe_atou8(p, &u); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + r = iovec_done_and_memdup(iov, &IOVEC_MAKE(&u, sizeof(u))); + if (r < 0) + return log_oom(); + + return 1; + } + case DHCP_OPTION_DATA_UINT16:{ + uint16_t u; + + r = safe_atou16(p, &u); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + u = htobe16(u); + r = iovec_done_and_memdup(iov, &IOVEC_MAKE(&u, sizeof(u))); + if (r < 0) + return log_oom(); + + return 1; + } + case DHCP_OPTION_DATA_UINT32: { + uint32_t u; + + r = safe_atou32(p, &u); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + u = htobe32(u); + r = iovec_done_and_memdup(iov, &IOVEC_MAKE(&u, sizeof(u))); + if (r < 0) + return log_oom(); + + return 1; + } + case DHCP_OPTION_DATA_IPV4ADDRESS: { + union in_addr_union a; + + r = in_addr_from_string(AF_INET, p, &a); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + r = iovec_done_and_memdup(iov, &IOVEC_MAKE(&a.in, sizeof(a.in))); + if (r < 0) + return log_oom(); + + return 1; + } + case DHCP_OPTION_DATA_IPV6ADDRESS: { + union in_addr_union a; + + r = in_addr_from_string(AF_INET6, p, &a); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + r = iovec_done_and_memdup(iov, &IOVEC_MAKE(&a.in6, sizeof(a.in6))); + if (r < 0) + return log_oom(); + + return 1; + } + case DHCP_OPTION_DATA_STRING: { + _cleanup_free_ char *s = NULL; + ssize_t sz = cunescape(p, UNESCAPE_ACCEPT_NUL, &s); + if (sz < 0) + return log_syntax_parse_error(unit, filename, line, sz, lvalue, rvalue); + if (check_length && sz > UINT8_MAX) + return log_syntax_parse_error(unit, filename, line, 0, lvalue, rvalue); + + iovec_done(iov); + *iov = IOVEC_MAKE(TAKE_PTR(s), sz); + return 1; + } + default: + return -EINVAL; + } +} + +int config_parse_dhcp_option_tlv( + 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) { + + TLV *options = ASSERT_PTR(data); + int r; + + if (isempty(rvalue)) { + tlv_done(options); + return 0; + } + + _cleanup_free_ char *word = NULL; + const char *p = rvalue; + r = extract_first_word(&p, &word, ":", 0); + if (r == -ENOMEM) + return log_oom(); + if (r <= 0 || isempty(p)) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + + uint8_t code; + r = safe_atou8(word, &code); + if (r < 0) + return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); + if (code < 1 || code >= UINT8_MAX) + return log_syntax_parse_error(unit, filename, line, 0, lvalue, rvalue); + + _cleanup_(iovec_done) struct iovec iov = {}; + r = config_parse_dhcp_option(unit, filename, line, section, section_line, lvalue, ltype, p, &iov, userdata); + if (r <= 0) + return r; + + r = tlv_append_iov(options, code, &iov); + if (r < 0) + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to store '%s=%s', ignoring assignment: %m", lvalue, rvalue); + return 0; } diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index 9eb9331923..6be8bcd6dc 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -81,8 +81,11 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_route_metric); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_hostname); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_or_ra_route_table); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_or_vendor_class); -CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp4_user_class); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_user_or_vendor_class); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_send_option); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_option); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_option_tlv); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); CONFIG_PARSER_PROTOTYPE(config_parse_duid_type); CONFIG_PARSER_PROTOTYPE(config_parse_manager_duid_type); diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index c88488258f..9903c6b9d3 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -7,6 +7,7 @@ #include "conf-parser.h" #include "dhcp-protocol.h" +#include "dhcp-server-internal.h" #include "dhcp-server-lease-internal.h" #include "dns-domain.h" #include "errno-util.h" @@ -567,7 +568,6 @@ static int dhcp_server_set_domain(Link *link) { static int dhcp4_server_configure(Link *link) { bool acquired_uplink = false; - sd_dhcp_option *p; DHCPStaticLease *static_lease; Link *uplink = NULL; Address *address; @@ -721,21 +721,13 @@ static int dhcp4_server_configure(Link *link) { else if (r < 0) return log_link_error_errno(link, r, "Failed to set domain name for DHCP server: %m"); - ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_send_options) { - r = sd_dhcp_server_add_option(link->dhcp_server, p); - if (r == -EEXIST) - continue; - if (r < 0) - return log_link_error_errno(link, r, "Failed to set DHCPv4 option: %m"); - } + r = dhcp_server_set_extra_options(link->dhcp_server, &link->network->dhcp_server_extra_options); + if (r < 0) + return log_link_error_errno(link, r, "Failed to set DHCPv4 extra options: %m"); - ORDERED_HASHMAP_FOREACH(p, link->network->dhcp_server_send_vendor_options) { - r = sd_dhcp_server_add_vendor_option(link->dhcp_server, p); - if (r == -EEXIST) - continue; - if (r < 0) - return log_link_error_errno(link, r, "Failed to set DHCPv4 option: %m"); - } + r = dhcp_server_set_vendor_options(link->dhcp_server, &link->network->dhcp_server_vendor_options); + if (r < 0) + return log_link_error_errno(link, r, "Failed to set DHCPv4 vendor options: %m"); HASHMAP_FOREACH(static_lease, link->network->dhcp_static_leases_by_section) { r = sd_dhcp_server_set_static_lease( diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index dc6b78e326..b5210e9ddf 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1477,7 +1477,6 @@ static bool link_dhcp4_ipv6_only_mode(Link *link) { } static int dhcp4_configure(Link *link) { - sd_dhcp_option *send_option; void *request_options; int r; @@ -1619,21 +1618,13 @@ static int dhcp4_configure(Link *link) { return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for '%u': %m", option); } - ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options) { - r = sd_dhcp_client_add_option(link->dhcp_client, send_option); - if (r == -EEXIST) - continue; - if (r < 0) - return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m"); - } + r = dhcp_client_set_extra_options(link->dhcp_client, &link->network->dhcp_extra_options); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set extra options: %m"); - ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_vendor_options) { - r = sd_dhcp_client_add_vendor_option(link->dhcp_client, send_option); - if (r == -EEXIST) - continue; - if (r < 0) - return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m"); - } + r = dhcp_client_set_vendor_options(link->dhcp_client, &link->network->dhcp_vendor_options); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set vendor options: %m"); r = dhcp4_set_hostname(link); if (r < 0) @@ -1652,11 +1643,9 @@ static int dhcp4_configure(Link *link) { return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MUD URL: %m"); } - if (link->network->dhcp_user_class) { - r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class); - if (r < 0) - return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set user class: %m"); - } + r = dhcp_client_set_user_class(link->dhcp_client, &link->network->dhcp_user_class); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set user class: %m"); } if (link->network->dhcp_client_port > 0) { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index aaf974e312..b925cd3a2b 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -278,7 +278,7 @@ DHCPv4.RequestBroadcast, config_parse_tristate, DHCPv4.VendorClassIdentifier, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_vendor_class_identifier) DHCPv4.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp_mudurl) DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0 -DHCPv4.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class) +DHCPv4.UserClass, config_parse_dhcp4_user_class, 0, offsetof(Network, dhcp_user_class) DHCPv4.IAID, config_parse_iaid, AF_INET, 0 DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0 DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 @@ -293,8 +293,8 @@ DHCPv4.DenyList, config_parse_in_addr_prefixes, DHCPv4.AllowList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_allow_listed_ip) DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, dhcp_ip_service_type) DHCPv4.SocketPriority, config_parse_dhcp_socket_priority, 0, 0 -DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options) -DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options) +DHCPv4.SendOption, config_parse_dhcp_option_tlv, 0, offsetof(Network, dhcp_extra_options) +DHCPv4.SendVendorOption, config_parse_dhcp_option_tlv, 0, offsetof(Network, dhcp_vendor_options) DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu) DHCPv4.InitialCongestionWindow, config_parse_tcp_window, 0, offsetof(Network, dhcp_initial_congestion_window) DHCPv4.InitialAdvertisedReceiveWindow, config_parse_tcp_window, 0, offsetof(Network, dhcp_advertised_receive_window) @@ -318,13 +318,13 @@ DHCPv6.MUDURL, config_parse_mud_url, DHCPv6.SendHostname, config_parse_dhcp_send_hostname, AF_INET6, 0 DHCPv6.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp6_hostname) DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0 -DHCPv6.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET6, offsetof(Network, dhcp6_user_class) -DHCPv6.VendorClass, config_parse_dhcp_user_or_vendor_class, AF_INET6, offsetof(Network, dhcp6_vendor_class) -DHCPv6.SendVendorOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_vendor_options) +DHCPv6.UserClass, config_parse_dhcp6_user_or_vendor_class, 0, offsetof(Network, dhcp6_user_class) +DHCPv6.VendorClass, config_parse_dhcp6_user_or_vendor_class, 0, offsetof(Network, dhcp6_vendor_class) +DHCPv6.SendVendorOption, config_parse_dhcp6_send_option, 0, offsetof(Network, dhcp6_client_send_vendor_options) DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_prefix_hint, 0, 0 DHCPv6.UnassignedSubnetPolicy, config_parse_dhcp_pd_prefix_route_type, 0, offsetof(Network, dhcp6_pd_prefix_route_type) DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_client_start_mode) -DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options) +DHCPv6.SendOption, config_parse_dhcp6_send_option, 0, offsetof(Network, dhcp6_client_send_options) DHCPv6.IAID, config_parse_iaid, AF_INET6, 0 DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid) DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid) @@ -387,8 +387,8 @@ DHCPServer.EmitDomain, config_parse_bool, DHCPServer.Domain, config_parse_dns_name, 0, offsetof(Network, dhcp_server_domain) DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset) DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size) -DHCPServer.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_vendor_options) -DHCPServer.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_options) +DHCPServer.SendOption, config_parse_dhcp_option_tlv, 0, offsetof(Network, dhcp_server_extra_options) +DHCPServer.SendVendorOption, config_parse_dhcp_option_tlv, 0, offsetof(Network, dhcp_server_vendor_options) DHCPServer.BindToInterface, config_parse_bool, 0, offsetof(Network, dhcp_server_bind_to_interface) DHCPServer.BootServerAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_boot_server_address) DHCPServer.BootServerName, config_parse_dns_name, 0, offsetof(Network, dhcp_server_boot_server_name) @@ -664,7 +664,7 @@ DHCP.Hostname, config_parse_hostname, DHCP.RequestBroadcast, config_parse_tristate, 0, offsetof(Network, dhcp_broadcast) DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) DHCP.VendorClassIdentifier, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_vendor_class_identifier) -DHCP.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class) +DHCP.UserClass, config_parse_dhcp4_user_class, 0, offsetof(Network, dhcp_user_class) DHCP.IAID, config_parse_iaid, AF_INET, 0 DHCP.DUIDType, config_parse_network_duid_type, 0, 0 DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 3ffe1640e7..5cd47ca0a8 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -397,6 +397,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp_use_gateway = -1, .dhcp_send_hostname = true, .dhcp_send_release = true, + .dhcp_extra_options = TLV_INIT(TLV_DHCP4), + .dhcp_vendor_options = TLV_INIT(TLV_DHCP4_SUBOPTION), .dhcp_route_metric = DHCP_ROUTE_METRIC, .dhcp_use_rapid_commit = -1, .dhcp_client_identifier = _DHCP_CLIENT_ID_INVALID, @@ -436,6 +438,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .dhcp_server_emit_router = true, .dhcp_server_emit_timezone = true, .dhcp_server_rapid_commit = true, + .dhcp_server_extra_options = TLV_INIT(TLV_DHCP4), + .dhcp_server_vendor_options = TLV_INIT(TLV_DHCP4_SUBOPTION), .dhcp_server_persist_leases = _DHCP_SERVER_PERSIST_LEASES_INVALID, .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC, @@ -771,8 +775,8 @@ static Network *network_free(Network *network) { free(network->dhcp_server_uplink_name); for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++) free(network->dhcp_server_emit[t].addresses); - ordered_hashmap_free(network->dhcp_server_send_options); - ordered_hashmap_free(network->dhcp_server_send_vendor_options); + tlv_done(&network->dhcp_server_extra_options); + tlv_done(&network->dhcp_server_vendor_options); free(network->dhcp_server_local_lease_domain); /* DHCP client */ @@ -782,10 +786,10 @@ static Network *network_free(Network *network) { free(network->dhcp_label); set_free(network->dhcp_deny_listed_ip); set_free(network->dhcp_allow_listed_ip); - strv_free(network->dhcp_user_class); + iovw_done_free(&network->dhcp_user_class); set_free(network->dhcp_request_options); - ordered_hashmap_free(network->dhcp_client_send_options); - ordered_hashmap_free(network->dhcp_client_send_vendor_options); + tlv_done(&network->dhcp_extra_options); + tlv_done(&network->dhcp_vendor_options); free(network->dhcp_netlabel); nft_set_context_clear(&network->dhcp_nft_set_context); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 9a36c312f8..c4020a4341 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -7,6 +7,7 @@ #include "bridge.h" #include "firewall-util.h" #include "ipoib.h" +#include "iovec-wrapper.h" #include "net-condition.h" #include "network-util.h" #include "networkd-bridge-vlan.h" @@ -23,6 +24,7 @@ #include "networkd-sysctl.h" #include "networkd-wwan-bus.h" #include "resolve-util.h" +#include "tlv-util.h" typedef enum KeepConfiguration { KEEP_CONFIGURATION_NO = 0, @@ -123,7 +125,7 @@ typedef struct Network { bool dhcp_iaid_set; char *dhcp_vendor_class_identifier; char *dhcp_mudurl; - char **dhcp_user_class; + struct iovec_wrapper dhcp_user_class; char *dhcp_hostname; char *dhcp_label; uint64_t dhcp_max_attempts; @@ -168,8 +170,8 @@ typedef struct Network { Set *dhcp_deny_listed_ip; Set *dhcp_allow_listed_ip; Set *dhcp_request_options; - OrderedHashmap *dhcp_client_send_options; - OrderedHashmap *dhcp_client_send_vendor_options; + TLV dhcp_extra_options; + TLV dhcp_vendor_options; char *dhcp_netlabel; NFTSetContext dhcp_nft_set_context; @@ -226,8 +228,8 @@ typedef struct Network { usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec; uint32_t dhcp_server_pool_offset; uint32_t dhcp_server_pool_size; - OrderedHashmap *dhcp_server_send_options; - OrderedHashmap *dhcp_server_send_vendor_options; + TLV dhcp_server_extra_options; + TLV dhcp_server_vendor_options; struct in_addr dhcp_server_boot_server_address; char *dhcp_server_boot_server_name; char *dhcp_server_boot_filename; diff --git a/src/systemd/meson.build b/src/systemd/meson.build index d7335cee55..ad455d73b2 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -28,7 +28,6 @@ _not_installed_headers = [ 'sd-dhcp-client.h', 'sd-dhcp-duid.h', 'sd-dhcp-lease.h', - 'sd-dhcp-option.h', 'sd-dhcp-protocol.h', 'sd-dhcp-server-lease.h', 'sd-dhcp-server.h', diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 378271aef8..4e7e79da65 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -30,7 +30,6 @@ struct in_addr; typedef struct sd_device sd_device; typedef struct sd_dhcp_client_id sd_dhcp_client_id; typedef struct sd_dhcp_lease sd_dhcp_lease; -typedef struct sd_dhcp_option sd_dhcp_option; typedef struct sd_event sd_event; enum { @@ -130,9 +129,6 @@ int sd_dhcp_client_set_vendor_class_identifier( int sd_dhcp_client_set_mud_url( sd_dhcp_client *client, const char *mudurl); -int sd_dhcp_client_set_user_class( - sd_dhcp_client *client, - char * const *user_class); int sd_dhcp_client_get_lease( sd_dhcp_client *client, sd_dhcp_lease **ret); @@ -150,9 +146,6 @@ int sd_dhcp_client_set_bootp( int bootp); int sd_dhcp_client_set_send_release(sd_dhcp_client *client, int enable); -int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v); -int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v); - int sd_dhcp_client_is_running(sd_dhcp_client *client); int sd_dhcp_client_stop(sd_dhcp_client *client); int sd_dhcp_client_start(sd_dhcp_client *client); diff --git a/src/systemd/sd-dhcp-option.h b/src/systemd/sd-dhcp-option.h deleted file mode 100644 index edc671b1b5..0000000000 --- a/src/systemd/sd-dhcp-option.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef foosddhcpoptionhfoo -#define foosddhcpoptionhfoo - -/*** - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see . -***/ - -#include "_sd-common.h" -#include "sd-dhcp-protocol.h" /* IWYU pragma: export */ - -_SD_BEGIN_DECLARATIONS; - -typedef struct sd_dhcp_option sd_dhcp_option; - -int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret); -_SD_DECLARE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option); - -_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref); - -_SD_END_DECLARATIONS; - -#endif diff --git a/src/systemd/sd-dhcp-protocol.h b/src/systemd/sd-dhcp-protocol.h index 1d3b635c31..55ce189cf4 100644 --- a/src/systemd/sd-dhcp-protocol.h +++ b/src/systemd/sd-dhcp-protocol.h @@ -23,174 +23,174 @@ _SD_BEGIN_DECLARATIONS; /* https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options */ enum { - SD_DHCP_OPTION_PAD = 0, /* [RFC2132] */ - SD_DHCP_OPTION_SUBNET_MASK = 1, /* [RFC2132] */ - SD_DHCP_OPTION_TIME_OFFSET = 2, /* [RFC2132], deprecated by 100 and 101 */ - SD_DHCP_OPTION_ROUTER = 3, /* [RFC2132] */ - SD_DHCP_OPTION_TIME_SERVER = 4, /* [RFC2132] */ - SD_DHCP_OPTION_NAME_SERVER = 5, /* [RFC2132] */ - SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6, /* [RFC2132] */ - SD_DHCP_OPTION_LOG_SERVER = 7, /* [RFC2132] */ - SD_DHCP_OPTION_QUOTES_SERVER = 8, /* [RFC2132] */ - SD_DHCP_OPTION_LPR_SERVER = 9, /* [RFC2132] */ - SD_DHCP_OPTION_IMPRESS_SERVER = 10, /* [RFC2132] */ - SD_DHCP_OPTION_RLP_SERVER = 11, /* [RFC2132] */ - SD_DHCP_OPTION_HOST_NAME = 12, /* [RFC2132] */ - SD_DHCP_OPTION_BOOT_FILE_SIZE = 13, /* [RFC2132] */ - SD_DHCP_OPTION_MERIT_DUMP_FILE = 14, /* [RFC2132] */ - SD_DHCP_OPTION_DOMAIN_NAME = 15, /* [RFC2132] */ - SD_DHCP_OPTION_SWAP_SERVER = 16, /* [RFC2132] */ - SD_DHCP_OPTION_ROOT_PATH = 17, /* [RFC2132] */ - SD_DHCP_OPTION_EXTENSION_FILE = 18, /* [RFC2132] */ - SD_DHCP_OPTION_FORWARD = 19, /* [RFC2132] */ - SD_DHCP_OPTION_SOURCE_ROUTE = 20, /* [RFC2132] */ - SD_DHCP_OPTION_POLICY_FILTER = 21, /* [RFC2132] */ - SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY = 22, /* [RFC2132] */ - SD_DHCP_OPTION_DEFAULT_IP_TTL = 23, /* [RFC2132] */ - SD_DHCP_OPTION_MTU_TIMEOUT = 24, /* [RFC2132] */ - SD_DHCP_OPTION_MTU_PLATEAU = 25, /* [RFC2132] */ - SD_DHCP_OPTION_MTU_INTERFACE = 26, /* [RFC2132] */ - SD_DHCP_OPTION_MTU_SUBNET = 27, /* [RFC2132] */ - SD_DHCP_OPTION_BROADCAST = 28, /* [RFC2132] */ - SD_DHCP_OPTION_MASK_DISCOVERY = 29, /* [RFC2132] */ - SD_DHCP_OPTION_MASK_SUPPLIER = 30, /* [RFC2132] */ - SD_DHCP_OPTION_ROUTER_DISCOVERY = 31, /* [RFC2132] */ - SD_DHCP_OPTION_ROUTER_REQUEST = 32, /* [RFC2132] */ - SD_DHCP_OPTION_STATIC_ROUTE = 33, /* [RFC2132] */ - SD_DHCP_OPTION_TRAILERS = 34, /* [RFC2132] */ - SD_DHCP_OPTION_ARP_TIMEOUT = 35, /* [RFC2132] */ - SD_DHCP_OPTION_ETHERNET = 36, /* [RFC2132] */ - SD_DHCP_OPTION_DEFAULT_TCP_TTL = 37, /* [RFC2132] */ - SD_DHCP_OPTION_KEEPALIVE_TIME = 38, /* [RFC2132] */ - SD_DHCP_OPTION_KEEPALIVE_DATA = 39, /* [RFC2132] */ - SD_DHCP_OPTION_NIS_DOMAIN = 40, /* [RFC2132] */ - SD_DHCP_OPTION_NIS_SERVER = 41, /* [RFC2132] */ - SD_DHCP_OPTION_NTP_SERVER = 42, /* [RFC2132] */ - SD_DHCP_OPTION_VENDOR_SPECIFIC = 43, /* [RFC2132] */ - SD_DHCP_OPTION_NETBIOS_NAME_SERVER = 44, /* [RFC2132] */ - SD_DHCP_OPTION_NETBIOS_DIST_SERVER = 45, /* [RFC2132] */ - SD_DHCP_OPTION_NETBIOS_NODE_TYPE = 46, /* [RFC2132] */ - SD_DHCP_OPTION_NETBIOS_SCOPE = 47, /* [RFC2132] */ - SD_DHCP_OPTION_X_WINDOW_FONT = 48, /* [RFC2132] */ - SD_DHCP_OPTION_X_WINDOW_MANAGER = 49, /* [RFC2132] */ - SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, /* [RFC2132] */ - SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, /* [RFC2132] */ - SD_DHCP_OPTION_OVERLOAD = 52, /* [RFC2132] */ - SD_DHCP_OPTION_MESSAGE_TYPE = 53, /* [RFC2132] */ - SD_DHCP_OPTION_SERVER_IDENTIFIER = 54, /* [RFC2132] */ - SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55, /* [RFC2132] */ - SD_DHCP_OPTION_ERROR_MESSAGE = 56, /* [RFC2132] */ - SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57, /* [RFC2132] */ - SD_DHCP_OPTION_RENEWAL_TIME = 58, /* [RFC2132] */ - SD_DHCP_OPTION_REBINDING_TIME = 59, /* [RFC2132] */ - SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, /* [RFC2132] */ - SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, /* [RFC2132] */ - SD_DHCP_OPTION_NETWARE_IP_DOMAIN = 62, /* [RFC2242] */ - SD_DHCP_OPTION_NETWARE_IP_OPTION = 63, /* [RFC2242] */ - SD_DHCP_OPTION_NIS_DOMAIN_NAME = 64, /* [RFC2132] */ - SD_DHCP_OPTION_NIS_SERVER_ADDR = 65, /* [RFC2132] */ - SD_DHCP_OPTION_BOOT_SERVER_NAME = 66, /* [RFC2132] */ - SD_DHCP_OPTION_BOOT_FILENAME = 67, /* [RFC2132] */ - SD_DHCP_OPTION_HOME_AGENT_ADDRESS = 68, /* [RFC2132] */ - SD_DHCP_OPTION_SMTP_SERVER = 69, /* [RFC2132] */ - SD_DHCP_OPTION_POP3_SERVER = 70, /* [RFC2132] */ - SD_DHCP_OPTION_NNTP_SERVER = 71, /* [RFC2132] */ - SD_DHCP_OPTION_WWW_SERVER = 72, /* [RFC2132] */ - SD_DHCP_OPTION_FINGER_SERVER = 73, /* [RFC2132] */ - SD_DHCP_OPTION_IRC_SERVER = 74, /* [RFC2132] */ - SD_DHCP_OPTION_STREETTALK_SERVER = 75, /* [RFC2132] */ - SD_DHCP_OPTION_STDA_SERVER = 76, /* [RFC2132] */ - SD_DHCP_OPTION_USER_CLASS = 77, /* [RFC3004] */ - SD_DHCP_OPTION_DIRECTORY_AGENT = 78, /* [RFC2610] */ - SD_DHCP_OPTION_SERVICE_SCOPE = 79, /* [RFC2610] */ - SD_DHCP_OPTION_RAPID_COMMIT = 80, /* [RFC4039] */ - SD_DHCP_OPTION_FQDN = 81, /* [RFC4702] */ - SD_DHCP_OPTION_RELAY_AGENT_INFORMATION = 82, /* [RFC3046] */ - SD_DHCP_OPTION_ISNS = 83, /* [RFC4174] */ + SD_DHCP_OPTION_PAD = 0, /* [RFC2132] */ + SD_DHCP_OPTION_SUBNET_MASK = 1, /* [RFC2132] */ + SD_DHCP_OPTION_TIME_OFFSET = 2, /* [RFC2132], deprecated by 100 and 101 */ + SD_DHCP_OPTION_ROUTER = 3, /* [RFC2132] */ + SD_DHCP_OPTION_TIME_SERVER = 4, /* [RFC2132] */ + SD_DHCP_OPTION_NAME_SERVER = 5, /* [RFC2132] */ + SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6, /* [RFC2132] */ + SD_DHCP_OPTION_LOG_SERVER = 7, /* [RFC2132] */ + SD_DHCP_OPTION_QUOTES_SERVER = 8, /* [RFC2132] */ + SD_DHCP_OPTION_LPR_SERVER = 9, /* [RFC2132] */ + SD_DHCP_OPTION_IMPRESS_SERVER = 10, /* [RFC2132] */ + SD_DHCP_OPTION_RLP_SERVER = 11, /* [RFC2132] */ + SD_DHCP_OPTION_HOST_NAME = 12, /* [RFC2132] */ + SD_DHCP_OPTION_BOOT_FILE_SIZE = 13, /* [RFC2132] */ + SD_DHCP_OPTION_MERIT_DUMP_FILE = 14, /* [RFC2132] */ + SD_DHCP_OPTION_DOMAIN_NAME = 15, /* [RFC2132] */ + SD_DHCP_OPTION_SWAP_SERVER = 16, /* [RFC2132] */ + SD_DHCP_OPTION_ROOT_PATH = 17, /* [RFC2132] */ + SD_DHCP_OPTION_EXTENSION_FILE = 18, /* [RFC2132] */ + SD_DHCP_OPTION_FORWARD = 19, /* [RFC2132] */ + SD_DHCP_OPTION_SOURCE_ROUTE = 20, /* [RFC2132] */ + SD_DHCP_OPTION_POLICY_FILTER = 21, /* [RFC2132] */ + SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY = 22, /* [RFC2132] */ + SD_DHCP_OPTION_DEFAULT_IP_TTL = 23, /* [RFC2132] */ + SD_DHCP_OPTION_MTU_TIMEOUT = 24, /* [RFC2132] */ + SD_DHCP_OPTION_MTU_PLATEAU = 25, /* [RFC2132] */ + SD_DHCP_OPTION_MTU_INTERFACE = 26, /* [RFC2132] */ + SD_DHCP_OPTION_MTU_SUBNET = 27, /* [RFC2132] */ + SD_DHCP_OPTION_BROADCAST = 28, /* [RFC2132] */ + SD_DHCP_OPTION_MASK_DISCOVERY = 29, /* [RFC2132] */ + SD_DHCP_OPTION_MASK_SUPPLIER = 30, /* [RFC2132] */ + SD_DHCP_OPTION_ROUTER_DISCOVERY = 31, /* [RFC2132] */ + SD_DHCP_OPTION_ROUTER_REQUEST = 32, /* [RFC2132] */ + SD_DHCP_OPTION_STATIC_ROUTE = 33, /* [RFC2132] */ + SD_DHCP_OPTION_TRAILERS = 34, /* [RFC2132] */ + SD_DHCP_OPTION_ARP_TIMEOUT = 35, /* [RFC2132] */ + SD_DHCP_OPTION_ETHERNET = 36, /* [RFC2132] */ + SD_DHCP_OPTION_DEFAULT_TCP_TTL = 37, /* [RFC2132] */ + SD_DHCP_OPTION_KEEPALIVE_TIME = 38, /* [RFC2132] */ + SD_DHCP_OPTION_KEEPALIVE_DATA = 39, /* [RFC2132] */ + SD_DHCP_OPTION_NIS_DOMAIN = 40, /* [RFC2132] */ + SD_DHCP_OPTION_NIS_SERVER = 41, /* [RFC2132] */ + SD_DHCP_OPTION_NTP_SERVER = 42, /* [RFC2132] */ + SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION = 43, /* [RFC2132] */ + SD_DHCP_OPTION_NETBIOS_NAME_SERVER = 44, /* [RFC2132] */ + SD_DHCP_OPTION_NETBIOS_DIST_SERVER = 45, /* [RFC2132] */ + SD_DHCP_OPTION_NETBIOS_NODE_TYPE = 46, /* [RFC2132] */ + SD_DHCP_OPTION_NETBIOS_SCOPE = 47, /* [RFC2132] */ + SD_DHCP_OPTION_X_WINDOW_FONT = 48, /* [RFC2132] */ + SD_DHCP_OPTION_X_WINDOW_MANAGER = 49, /* [RFC2132] */ + SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, /* [RFC2132] */ + SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, /* [RFC2132] */ + SD_DHCP_OPTION_OVERLOAD = 52, /* [RFC2132] */ + SD_DHCP_OPTION_MESSAGE_TYPE = 53, /* [RFC2132] */ + SD_DHCP_OPTION_SERVER_IDENTIFIER = 54, /* [RFC2132] */ + SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55, /* [RFC2132] */ + SD_DHCP_OPTION_ERROR_MESSAGE = 56, /* [RFC2132] */ + SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57, /* [RFC2132] */ + SD_DHCP_OPTION_RENEWAL_TIME = 58, /* [RFC2132] */ + SD_DHCP_OPTION_REBINDING_TIME = 59, /* [RFC2132] */ + SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, /* [RFC2132] */ + SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, /* [RFC2132] */ + SD_DHCP_OPTION_NETWARE_IP_DOMAIN = 62, /* [RFC2242] */ + SD_DHCP_OPTION_NETWARE_IP_OPTION = 63, /* [RFC2242] */ + SD_DHCP_OPTION_NIS_DOMAIN_NAME = 64, /* [RFC2132] */ + SD_DHCP_OPTION_NIS_SERVER_ADDR = 65, /* [RFC2132] */ + SD_DHCP_OPTION_BOOT_SERVER_NAME = 66, /* [RFC2132] */ + SD_DHCP_OPTION_BOOT_FILENAME = 67, /* [RFC2132] */ + SD_DHCP_OPTION_HOME_AGENT_ADDRESS = 68, /* [RFC2132] */ + SD_DHCP_OPTION_SMTP_SERVER = 69, /* [RFC2132] */ + SD_DHCP_OPTION_POP3_SERVER = 70, /* [RFC2132] */ + SD_DHCP_OPTION_NNTP_SERVER = 71, /* [RFC2132] */ + SD_DHCP_OPTION_WWW_SERVER = 72, /* [RFC2132] */ + SD_DHCP_OPTION_FINGER_SERVER = 73, /* [RFC2132] */ + SD_DHCP_OPTION_IRC_SERVER = 74, /* [RFC2132] */ + SD_DHCP_OPTION_STREETTALK_SERVER = 75, /* [RFC2132] */ + SD_DHCP_OPTION_STDA_SERVER = 76, /* [RFC2132] */ + SD_DHCP_OPTION_USER_CLASS = 77, /* [RFC3004] */ + SD_DHCP_OPTION_DIRECTORY_AGENT = 78, /* [RFC2610] */ + SD_DHCP_OPTION_SERVICE_SCOPE = 79, /* [RFC2610] */ + SD_DHCP_OPTION_RAPID_COMMIT = 80, /* [RFC4039] */ + SD_DHCP_OPTION_FQDN = 81, /* [RFC4702] */ + SD_DHCP_OPTION_RELAY_AGENT_INFORMATION = 82, /* [RFC3046] */ + SD_DHCP_OPTION_ISNS = 83, /* [RFC4174] */ /* option code 84 is unassigned [RFC3679] */ - SD_DHCP_OPTION_NDS_SERVER = 85, /* [RFC2241] */ - SD_DHCP_OPTION_NDS_TREE_NAME = 86, /* [RFC2241] */ - SD_DHCP_OPTION_NDS_CONTEXT = 87, /* [RFC2241] */ - SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAME = 88, /* [RFC4280] */ - SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS = 89, /* [RFC4280] */ - SD_DHCP_OPTION_AUTHENTICATION = 90, /* [RFC3118] */ - SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME = 91, /* [RFC4388] */ - SD_DHCP_OPTION_ASSOCIATED_IP = 92, /* [RFC4388] */ - SD_DHCP_OPTION_CLIENT_SYSTEM = 93, /* [RFC4578] */ - SD_DHCP_OPTION_CLIENT_NDI = 94, /* [RFC4578] */ - SD_DHCP_OPTION_LDAP = 95, /* [RFC3679] */ + SD_DHCP_OPTION_NDS_SERVER = 85, /* [RFC2241] */ + SD_DHCP_OPTION_NDS_TREE_NAME = 86, /* [RFC2241] */ + SD_DHCP_OPTION_NDS_CONTEXT = 87, /* [RFC2241] */ + SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAME = 88, /* [RFC4280] */ + SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS = 89, /* [RFC4280] */ + SD_DHCP_OPTION_AUTHENTICATION = 90, /* [RFC3118] */ + SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME = 91, /* [RFC4388] */ + SD_DHCP_OPTION_ASSOCIATED_IP = 92, /* [RFC4388] */ + SD_DHCP_OPTION_CLIENT_SYSTEM = 93, /* [RFC4578] */ + SD_DHCP_OPTION_CLIENT_NDI = 94, /* [RFC4578] */ + SD_DHCP_OPTION_LDAP = 95, /* [RFC3679] */ /* option code 96 is unassigned [RFC3679] */ - SD_DHCP_OPTION_UUID = 97, /* [RFC4578] */ - SD_DHCP_OPTION_USER_AUTHENTICATION = 98, /* [RFC2485] */ - SD_DHCP_OPTION_GEOCONF_CIVIC = 99, /* [RFC4776] */ - SD_DHCP_OPTION_POSIX_TIMEZONE = 100, /* [RFC4833] */ - SD_DHCP_OPTION_TZDB_TIMEZONE = 101, /* [RFC4833] */ + SD_DHCP_OPTION_UUID = 97, /* [RFC4578] */ + SD_DHCP_OPTION_USER_AUTHENTICATION = 98, /* [RFC2485] */ + SD_DHCP_OPTION_GEOCONF_CIVIC = 99, /* [RFC4776] */ + SD_DHCP_OPTION_POSIX_TIMEZONE = 100, /* [RFC4833] */ + SD_DHCP_OPTION_TZDB_TIMEZONE = 101, /* [RFC4833] */ /* option codes 102-107 are unassigned [RFC3679] */ - SD_DHCP_OPTION_IPV6_ONLY_PREFERRED = 108, /* [RFC8925] */ - SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS = 109, /* [RFC8539] */ + SD_DHCP_OPTION_IPV6_ONLY_PREFERRED = 108, /* [RFC8925] */ + SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS = 109, /* [RFC8539] */ /* option codes 110-111 are unassigned [RFC3679] */ - SD_DHCP_OPTION_NETINFO_ADDRESS = 112, /* [RFC3679] */ - SD_DHCP_OPTION_NETINFO_TAG = 113, /* [RFC3679] */ - SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL = 114, /* [RFC8910] */ + SD_DHCP_OPTION_NETINFO_ADDRESS = 112, /* [RFC3679] */ + SD_DHCP_OPTION_NETINFO_TAG = 113, /* [RFC3679] */ + SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL = 114, /* [RFC8910] */ /* option code 115 is unassigned [RFC3679] */ - SD_DHCP_OPTION_AUTO_CONFIG = 116, /* [RFC2563] */ - SD_DHCP_OPTION_NAME_SERVICE_SEARCH = 117, /* [RFC2937] */ - SD_DHCP_OPTION_SUBNET_SELECTION = 118, /* [RFC3011] */ - SD_DHCP_OPTION_DOMAIN_SEARCH = 119, /* [RFC3397] */ - SD_DHCP_OPTION_SIP_SERVER = 120, /* [RFC3361] */ - SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, /* [RFC3442] */ - SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION = 122, /* [RFC3495] */ - SD_DHCP_OPTION_GEOCONF = 123, /* [RFC6225] */ - SD_DHCP_OPTION_VENDOR_CLASS = 124, /* [RFC3925] */ - SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION = 125, /* [RFC3925] */ + SD_DHCP_OPTION_AUTO_CONFIG = 116, /* [RFC2563] */ + SD_DHCP_OPTION_NAME_SERVICE_SEARCH = 117, /* [RFC2937] */ + SD_DHCP_OPTION_SUBNET_SELECTION = 118, /* [RFC3011] */ + SD_DHCP_OPTION_DOMAIN_SEARCH = 119, /* [RFC3397] */ + SD_DHCP_OPTION_SIP_SERVER = 120, /* [RFC3361] */ + SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, /* [RFC3442] */ + SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION = 122, /* [RFC3495] */ + SD_DHCP_OPTION_GEOCONF = 123, /* [RFC6225] */ + SD_DHCP_OPTION_VENDOR_IDENTIFYING_VENDOR_CLASS = 124, /* [RFC3925] */ + SD_DHCP_OPTION_VENDOR_IDENTIFYING_VENDOR_SPECIFIC_INFORMATION = 125, /* [RFC3925] */ /* option codes 126-127 are unassigned [RFC3679] */ /* option codes 128-135 are assigned to use by PXE, but they are vendor specific [RFC4578] */ - SD_DHCP_OPTION_PANA_AGENT = 136, /* [RFC5192] */ - SD_DHCP_OPTION_LOST_SERVER_FQDN = 137, /* [RFC5223] */ - SD_DHCP_OPTION_CAPWAP_AC_ADDRESS = 138, /* [RFC5417] */ - SD_DHCP_OPTION_MOS_ADDRESS = 139, /* [RFC5678] */ - SD_DHCP_OPTION_MOS_FQDN = 140, /* [RFC5678] */ - SD_DHCP_OPTION_SIP_SERVICE_DOMAIN = 141, /* [RFC6011] */ - SD_DHCP_OPTION_ANDSF_ADDRESS = 142, /* [RFC6153] */ - SD_DHCP_OPTION_SZTP_REDIRECT = 143, /* [RFC8572] */ - SD_DHCP_OPTION_GEOLOC = 144, /* [RFC6225] */ - SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE = 145, /* [RFC6704] */ - SD_DHCP_OPTION_RDNSS_SELECTION = 146, /* [RFC6731] */ - SD_DHCP_OPTION_DOTS_RI = 147, /* [RFC8973] */ - SD_DHCP_OPTION_DOTS_ADDRESS = 148, /* [RFC8973] */ + SD_DHCP_OPTION_PANA_AGENT = 136, /* [RFC5192] */ + SD_DHCP_OPTION_LOST_SERVER_FQDN = 137, /* [RFC5223] */ + SD_DHCP_OPTION_CAPWAP_AC_ADDRESS = 138, /* [RFC5417] */ + SD_DHCP_OPTION_MOS_ADDRESS = 139, /* [RFC5678] */ + SD_DHCP_OPTION_MOS_FQDN = 140, /* [RFC5678] */ + SD_DHCP_OPTION_SIP_SERVICE_DOMAIN = 141, /* [RFC6011] */ + SD_DHCP_OPTION_ANDSF_ADDRESS = 142, /* [RFC6153] */ + SD_DHCP_OPTION_SZTP_REDIRECT = 143, /* [RFC8572] */ + SD_DHCP_OPTION_GEOLOC = 144, /* [RFC6225] */ + SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE = 145, /* [RFC6704] */ + SD_DHCP_OPTION_RDNSS_SELECTION = 146, /* [RFC6731] */ + SD_DHCP_OPTION_DOTS_RI = 147, /* [RFC8973] */ + SD_DHCP_OPTION_DOTS_ADDRESS = 148, /* [RFC8973] */ /* option code 149 is unassigned [RFC3942] */ - SD_DHCP_OPTION_TFTP_SERVER_ADDRESS = 150, /* [RFC5859] */ - SD_DHCP_OPTION_STATUS_CODE = 151, /* [RFC6926] */ - SD_DHCP_OPTION_BASE_TIME = 152, /* [RFC6926] */ - SD_DHCP_OPTION_START_TIME_OF_STATE = 153, /* [RFC6926] */ - SD_DHCP_OPTION_QUERY_START_TIME = 154, /* [RFC6926] */ - SD_DHCP_OPTION_QUERY_END_TIME = 155, /* [RFC6926] */ - SD_DHCP_OPTION_DHCP_STATE = 156, /* [RFC6926] */ - SD_DHCP_OPTION_DATA_SOURCE = 157, /* [RFC6926] */ - SD_DHCP_OPTION_PCP_SERVER = 158, /* [RFC7291] */ - SD_DHCP_OPTION_PORT_PARAMS = 159, /* [RFC7618] */ + SD_DHCP_OPTION_TFTP_SERVER_ADDRESS = 150, /* [RFC5859] */ + SD_DHCP_OPTION_STATUS_CODE = 151, /* [RFC6926] */ + SD_DHCP_OPTION_BASE_TIME = 152, /* [RFC6926] */ + SD_DHCP_OPTION_START_TIME_OF_STATE = 153, /* [RFC6926] */ + SD_DHCP_OPTION_QUERY_START_TIME = 154, /* [RFC6926] */ + SD_DHCP_OPTION_QUERY_END_TIME = 155, /* [RFC6926] */ + SD_DHCP_OPTION_DHCP_STATE = 156, /* [RFC6926] */ + SD_DHCP_OPTION_DATA_SOURCE = 157, /* [RFC6926] */ + SD_DHCP_OPTION_PCP_SERVER = 158, /* [RFC7291] */ + SD_DHCP_OPTION_PORT_PARAMS = 159, /* [RFC7618] */ /* option code 160 is unassigned [RFC7710][RFC8910] */ - SD_DHCP_OPTION_MUD_URL = 161, /* [RFC8520] */ - SD_DHCP_OPTION_V4_DNR = 162, /* [RFC9463] */ + SD_DHCP_OPTION_MUD_URL = 161, /* [RFC8520] */ + SD_DHCP_OPTION_V4_DNR = 162, /* [RFC9463] */ /* option codes 163-174 are unassigned [RFC3942] */ /* option codes 175-177 are temporary assigned. */ /* option codes 178-207 are unassigned [RFC3942] */ - SD_DHCP_OPTION_PXELINUX_MAGIC = 208, /* [RFC5071] Deprecated */ - SD_DHCP_OPTION_CONFIGURATION_FILE = 209, /* [RFC5071] */ - SD_DHCP_OPTION_PATH_PREFIX = 210, /* [RFC5071] */ - SD_DHCP_OPTION_REBOOT_TIME = 211, /* [RFC5071] */ - SD_DHCP_OPTION_6RD = 212, /* [RFC5969] */ - SD_DHCP_OPTION_ACCESS_DOMAIN = 213, /* [RFC5986] */ + SD_DHCP_OPTION_PXELINUX_MAGIC = 208, /* [RFC5071] Deprecated */ + SD_DHCP_OPTION_CONFIGURATION_FILE = 209, /* [RFC5071] */ + SD_DHCP_OPTION_PATH_PREFIX = 210, /* [RFC5071] */ + SD_DHCP_OPTION_REBOOT_TIME = 211, /* [RFC5071] */ + SD_DHCP_OPTION_6RD = 212, /* [RFC5969] */ + SD_DHCP_OPTION_ACCESS_DOMAIN = 213, /* [RFC5986] */ /* option codes 214-219 are unassigned */ - SD_DHCP_OPTION_SUBNET_ALLOCATION = 220, /* [RFC6656] */ - SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION = 221, /* [RFC6607] */ + SD_DHCP_OPTION_SUBNET_ALLOCATION = 220, /* [RFC6656] */ + SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION = 221, /* [RFC6607] */ /* option codes 222-223 are unassigned [RFC3942] */ /* option codes 224-254 are reserved for private use */ - SD_DHCP_OPTION_PRIVATE_BASE = 224, - SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, /* [RFC7844] */ - SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252, /* [RFC7844] */ - SD_DHCP_OPTION_PRIVATE_LAST = 254, - SD_DHCP_OPTION_END = 255 /* [RFC2132] */ + SD_DHCP_OPTION_PRIVATE_BASE = 224, + SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, /* [RFC7844] */ + SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252, /* [RFC7844] */ + SD_DHCP_OPTION_PRIVATE_LAST = 254, + SD_DHCP_OPTION_END = 255 /* [RFC2132] */ }; /* Suboptions for SD_DHCP_OPTION_RELAY_AGENT_INFORMATION option */ diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index ef13776201..4f2fc68835 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -26,7 +26,6 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_event sd_event; -typedef struct sd_dhcp_option sd_dhcp_option; typedef struct sd_dhcp_server sd_dhcp_server; enum { @@ -76,8 +75,6 @@ int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], s int sd_dhcp_server_set_pop3(sd_dhcp_server *server, const struct in_addr pop3[], size_t n); int sd_dhcp_server_set_smtp(sd_dhcp_server *server, const struct in_addr smtp[], size_t n); -int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v); -int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v); int sd_dhcp_server_set_static_lease( sd_dhcp_server *server, const struct in_addr *address,