From patchwork Thu May 24 04:47:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 919563 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40rxhl5Crhz9s0q for ; Thu, 24 May 2018 14:48:07 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="D3qZRHhn"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="AMX2bTP8"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40rxhl334JzF1Hf for ; Thu, 24 May 2018 14:48:07 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="D3qZRHhn"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="AMX2bTP8"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.28; helo=out4-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="D3qZRHhn"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="AMX2bTP8"; dkim-atps=neutral Received: from out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40rxhW41qDzF1H5 for ; Thu, 24 May 2018 14:47:55 +1000 (AEST) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 074AA21C3F; Thu, 24 May 2018 00:47:53 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Thu, 24 May 2018 00:47:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=jOQxPzPskikzo5Idpx1bktjEnh13T5j8/arO4EYmcng=; b=D3qZRHhn B0+7P6C0WYZ5iD1HqrLOkufZ4V2wlTdhxYzc1v/IwQZJEb1QbAmTXxYxakYIp3e8 okbR2EWnPc5vEjAYK9nPub8SkHgUybQ6Bqh+W+uApGkQnaTtDZobQVyj8W2x+rJt xZ0CEEDtth/BeifNVNF5Du0hfKxPNw4Y+9/117skogpbMbnqHSM2zoJL9FK/+t9t nNC8kD2exWdO1TFvv/S2SmDvql8Svcaxxxcmoh6xWhr3UNEp8lEZgqm7E30bKKTs 4WyytpjjU8EYZ7e4MmZWITaNsGonTqbtuLk1T+Oa6VBIxBZYJMOFITuOox7UgTDT nEo6VIBXEGWr9A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=jOQxPzPskikzo5Idpx1bktjEnh13T5j8/arO4EYmcng=; b=AMX2bTP8 RH/qcow2cp85UYY63UtM6U1tu4Jfx3keov3xYNYyedpPTFD0me0MmqunGbE8WRC7 aKvbR5pfb7iM1p+GOXprOVe3v+repnM1B+CtwLHIQvNI+8meayvTahuJdTi1jkLc HZ7OvmrKDoH2+cxDYaqa9KIvlIRNf/B73i7CpqDK8JeomomD7NZLbbcX0qNxs0KS 5DfdJu7qMzQDpE027oyum7iCD8LXCrNn3QMqL1x7rzyNIJtFnxsmQV6IZ7b50bNW TtEgC2mF0bTGS4VznezIqYRP5ZSY0e/6rB1rR+S8sTSCv+1FbDUlI8xfUgDg2Jvg AAWrUWr0YQVBdQ== X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Sender: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id A9913102BA; Thu, 24 May 2018 00:47:51 -0400 (EDT) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [PATCH v2 1/9] lib: Add support and helpers for IPv6 host addresses Date: Thu, 24 May 2018 14:47:34 +1000 Message-Id: <20180524044742.25889-2-sam@mendozajonas.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524044742.25889-1-sam@mendozajonas.com> References: <20180524044742.25889-1-sam@mendozajonas.com> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Recognise IPv6 addresses and URLs, and allow an interface_info struct to have both an IPv4 and IPv6 address. The addr_scheme() helper returns the address family of a given address. Signed-off-by: Samuel Mendoza-Jonas --- lib/pb-protocol/pb-protocol.c | 6 +++- lib/types/types.h | 1 + lib/url/url.c | 45 ++++++++++++++++++++++++++---- lib/url/url.h | 2 ++ test/urls/Makefile.am | 3 ++ test/urls/data/ipv6-full.test | 7 +++++ test/urls/data/ipv6-multidirs.test | 7 +++++ test/urls/data/ipv6-noport.test | 7 +++++ 8 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 test/urls/data/ipv6-full.test create mode 100644 test/urls/data/ipv6-multidirs.test create mode 100644 test/urls/data/ipv6-noport.test diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index dbbda40..87505fc 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -253,7 +253,8 @@ int pb_protocol_system_info_len(const struct system_info *sysinfo) len += 4 + if_info->hwaddr_size + 4 + optional_strlen(if_info->name) + sizeof(if_info->link) + - 4 + optional_strlen(if_info->address); + 4 + optional_strlen(if_info->address) + + 4 + optional_strlen(if_info->address_v6); } for (i = 0; i < sysinfo->n_blockdevs; i++) { @@ -494,6 +495,7 @@ int pb_protocol_serialise_system_info(const struct system_info *sysinfo, pos += sizeof(bool); pos += pb_protocol_serialise_string(pos, if_info->address); + pos += pb_protocol_serialise_string(pos, if_info->address_v6); } *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_blockdevs); @@ -1011,6 +1013,8 @@ int pb_protocol_deserialise_system_info(struct system_info *sysinfo, if (read_string(if_info, &pos, &len, &if_info->address)) goto out; + if (read_string(if_info, &pos, &len, &if_info->address_v6)) + goto out; sysinfo->interfaces[i] = if_info; } diff --git a/lib/types/types.h b/lib/types/types.h index 9ab2a43..5f99b58 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -110,6 +110,7 @@ struct interface_info { char *name; bool link; char *address; + char *address_v6; }; struct blockdev_info { diff --git a/lib/url/url.c b/lib/url/url.c index 6eeced3..f0e8b0e 100644 --- a/lib/url/url.c +++ b/lib/url/url.c @@ -197,19 +197,35 @@ struct pb_url *pb_url_parse(void *ctx, const char *url_str) goto fail; } - col = strchr(p, ':'); + col = strrchr(p, ':'); + if (col <= p) + col = NULL; + if (col && strchr(col , ']')) { + /* + * This is likely an IPv6 address with no port. + * See https://www.ietf.org/rfc/rfc2732.txt + */ + col = NULL; + } if (col) { len = path - col - 1; url->port = len ? talloc_strndup(url, col + 1, len) : NULL; len = col - p; - url->host = len ? talloc_strndup(url, p, len) : NULL; } else { url->port = NULL; - url->host = talloc_strndup(url, p, path - p); + len = path - p; } + if (p[0] == '[' && p[len - 1] == ']') + /* IPv6 */ + url->host = talloc_strndup(url, p + 1, len - 2); + else + /* IPv4 */ + url->host = talloc_strndup(url, p, len); + + /* remove multiple leading slashes */ for (; *path && *(path+1) == '/'; path++) ; @@ -231,13 +247,32 @@ bool is_url(const char *str) return strstr(str, "://") != NULL; } +int addr_scheme(const char *address) +{ + uint8_t buf[sizeof(struct in6_addr)]; + int rc; + + rc = inet_pton(AF_INET, address , buf); + if (rc == 1) + return AF_INET; + rc = inet_pton(AF_INET6, address , buf); + if (rc == 1) + return AF_INET6; + + return 0; +} + char *pb_url_to_string(struct pb_url *url) { const struct pb_scheme_info *scheme = pb_url_scheme_info(url->scheme); assert(scheme); - return talloc_asprintf(url, "%s://%s%s", scheme->str, - scheme->has_host ? url->host : "", url->path); + if (scheme->has_host && addr_scheme(url->host) == AF_INET6) + return talloc_asprintf(url, "%s://[%s]%s", scheme->str, + url->host, url->path); + else + return talloc_asprintf(url, "%s://%s%s", scheme->str, + scheme->has_host ? url->host : "", url->path); } static void pb_url_update_full(struct pb_url *url) diff --git a/lib/url/url.h b/lib/url/url.h index 9043615..49dff4a 100644 --- a/lib/url/url.h +++ b/lib/url/url.h @@ -19,6 +19,7 @@ #if !defined(_PB_URL_PARSER_H) #define _PB_URL_PARSER_H +#include #include /** @@ -61,6 +62,7 @@ struct pb_url { }; bool is_url(const char *str); +int addr_scheme(const char *address); struct pb_url *pb_url_parse(void *ctx, const char *url_str); struct pb_url *pb_url_copy(void *ctx, const struct pb_url *url); struct pb_url *pb_url_join(void *ctx, const struct pb_url *url, const char *s); diff --git a/test/urls/Makefile.am b/test/urls/Makefile.am index ad670b8..aab0f2b 100644 --- a/test/urls/Makefile.am +++ b/test/urls/Makefile.am @@ -20,6 +20,9 @@ test_urls_parse_url_LDADD = $(core_lib) url_TESTS = \ test/urls/data/double-slash.test \ test/urls/data/http-simple.test \ + test/urls/data/ipv6-full.test \ + test/urls/data/ipv6-multidirs.test \ + test/urls/data/ipv6-noport.test \ test/urls/data/join-full.test \ test/urls/data/join-absolute.test \ test/urls/data/join-relative.test \ diff --git a/test/urls/data/ipv6-full.test b/test/urls/data/ipv6-full.test new file mode 100644 index 0000000..b4943eb --- /dev/null +++ b/test/urls/data/ipv6-full.test @@ -0,0 +1,7 @@ +http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html +scheme http +host FEDC:BA98:7654:3210:FEDC:BA98:7654:3210 +port 80 +path /index.html +dir / +file index.html diff --git a/test/urls/data/ipv6-multidirs.test b/test/urls/data/ipv6-multidirs.test new file mode 100644 index 0000000..68b852a --- /dev/null +++ b/test/urls/data/ipv6-multidirs.test @@ -0,0 +1,7 @@ +tftp://[fd69:d65f:b8b5:61::1]/installers/ubuntu-18.04/vmlinux +scheme tftp +host fd69:d65f:b8b5:61::1 +port (null) +path /installers/ubuntu-18.04/vmlinux +dir /installers/ubuntu-18.04/ +file vmlinux diff --git a/test/urls/data/ipv6-noport.test b/test/urls/data/ipv6-noport.test new file mode 100644 index 0000000..bd3b008 --- /dev/null +++ b/test/urls/data/ipv6-noport.test @@ -0,0 +1,7 @@ +http://[1080:0:0:0:8:800:200C:417A]/index.html +scheme http +host 1080:0:0:0:8:800:200C:417A +port (null) +path /index.html +dir / +file index.html