From 923599523c10d8897551e081e6b00cd8002309c3 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Mon, 6 Nov 2023 17:05:11 +0100 Subject: [PATCH] network-generator: correctly handle IPv6 DNS servers in ip= IPv6 addresses in the ip= assignment need to be enclosed in [], which was handled for all IP-related fields except for the two optional DNS fields. --- src/network/generator/network-generator.c | 60 +++++++++++++++++------ 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index d9fca213844..4619a3394e1 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -611,9 +611,47 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c return 0; } +static int parse_ip_dns_address_one(Context *context, const char *ifname, int family, const char **value) { + const char *p = *value, *q, *buf; + int r; + + if (isempty(p)) + return 0; + + if (family == AF_INET6) { + if (p[0] != '[') + return -EINVAL; + + q = strchr(p + 1, ']'); + if (!q) + return -EINVAL; + + buf = strndupa_safe(p + 1, q - p - 1); + p = q + 1; + } else { + q = strchr(p, ':'); + if (!q) + buf = *value; + else + buf = strndupa_safe(*value, q - *value); + + p += strlen(buf); + } + + r = network_set_dns(context, ifname, buf); + if (r < 0) + return r; + + if (p[0] == ':') + p++; + + *value = p; + return 0; +} + static int parse_cmdline_ip_address(Context *context, int family, const char *value) { union in_addr_union addr = {}, peer = {}, gateway = {}; - const char *hostname = NULL, *ifname, *dhcp_type, *dns, *p; + const char *hostname = NULL, *ifname, *dhcp_type, *p; unsigned char prefixlen; int r; @@ -689,20 +727,12 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va /* Next, try [][:] */ value = p + 1; - p = strchr(value, ':'); - if (!p) { - r = network_set_dns(context, ifname, value); - if (r < 0) - return r; - } else { - dns = strndupa_safe(value, p - value); - r = network_set_dns(context, ifname, dns); - if (r < 0) - return r; - r = network_set_dns(context, ifname, p + 1); - if (r < 0) - return r; - } + r = parse_ip_dns_address_one(context, ifname, family, &value); + if (r < 0) + return r; + r = parse_ip_dns_address_one(context, ifname, family, &value); + if (r < 0) + return r; return 0; }