From patchwork Tue Jan 17 10:56:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Job Snijders X-Patchwork-Id: 63267 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 13FA83858C60 for ; Tue, 17 Jan 2023 10:56:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 13FA83858C60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1673952992; bh=arsAVQHWE9KzavoluzdC013qZ9/5ZX7jlU41hCTbPNo=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=V7HM0B8DqrDDt+lN79Xjt2/X3zeinXbTjpCgety66cuI21ZmzZdnGMcNmUVlyvvU2 KhPZaWjPwOb+xBQwzFNfKS58rD9iL68sxhEEsxrY5n12OGRzcYkH6OufCagIpC8ELo AKnXSp6UZxxHRFPhpX8DeuGx2N/f1yN5wgU/3poo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id 0B58C3858D28 for ; Tue, 17 Jan 2023 10:56:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0B58C3858D28 Received: by mail-ej1-x62d.google.com with SMTP id u19so74355478ejm.8 for ; Tue, 17 Jan 2023 02:56:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=arsAVQHWE9KzavoluzdC013qZ9/5ZX7jlU41hCTbPNo=; b=W6sxzjaSMWQ60TuCyOaHd0CdjJsErmOTcJacQ0Adi2P4dw7xABTWgDjuG9o0+BN2R7 KnZFlSmnsW1Tnn+RYfkg88VYGsFx8v8OWLlw2lHz1qIwOFM34KCt23GUiAAWKUSISSR9 JZOEfyznPHAL69ZSqJ1sRWTO7UXaOJI7+55NmimeRBgw4eG/3ZrvDo50MuIrXw0qwmOG YQQRARqeGpsIeNDzWUbT3j3Sq4hSYGro4q5nWqUQHzlcQoUKKJpG6wtvwwXls6yJkHMY Svs+5u68+m5cHl2ticu/31C8FUMzn9ZRhzDJ15Ri3oaJ369A2qhP4/7nYBqoZ9RXzbzW bP7g== X-Gm-Message-State: AFqh2koZBsCIV8UPYuecvg3PqOGnm26lbJUDwh5nmewphwbUYcdeAeTz jL+shrFpmJgUpgw9i/nsY1EVZMZX+5dkLQ3q6HIfO4l89kRTEa0tJiS3z2/P5wcVMcm1Oy09+d6 MFO7jDDnTXHqWLb3RuEFMn/E412ecGsaWgLrBtQ004OG24WoAo0pw0THU/E/VlGvmvs5gog== X-Google-Smtp-Source: AMrXdXuF3Z3X6kHK9x9ssq/3WgWM6T9EZ/YVsmxzIjXY/UWNfixaVwc05K3QTKTGT7UG8lz5hQ66Kw== X-Received: by 2002:a17:907:6c16:b0:86f:5636:4712 with SMTP id rl22-20020a1709076c1600b0086f56364712mr2718758ejc.7.1673952965906; Tue, 17 Jan 2023 02:56:05 -0800 (PST) Received: from snel ([2a10:3781:276:1:16f6:d8ff:fe47:2eb7]) by smtp.gmail.com with ESMTPSA id gn19-20020a1709070d1300b00815835b4b5fsm12898710ejc.134.2023.01.17.02.56.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Jan 2023 02:56:05 -0800 (PST) Date: Tue, 17 Jan 2023 11:56:03 +0100 To: libc-alpha@sourceware.org Subject: [PATCH] resolv: add IPv6 support to inet_net_pton() Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Clacks-Overhead: GNU Terry Pratchett X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPAM_FROM, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Job Snijders via Libc-alpha From: Job Snijders Reply-To: Job Snijders Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Dear all, On Thu, Dec 22, 2022 at 06:54:58PM +0100, Job Snijders wrote: > This changeset adds support to inet_net_pton() to convert IPv6 network > numbers (IPv6 prefixes with CIDR notation) from presentation format to > network format. > > The starting point of this changeset was OpenBSD's > libc/net/inet_net_pton.c (r1.13) implementation of inet_net_pton_ipv6(). > https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/net/inet_net_pton.c?annotate=1.13 > The OpenBSD implementation was adapted to glibc as following: > > 1) Use strncpy() instead of strlcpy() > 2) Use strtol() instead of strtonum() > 3) Updated comments I'm resending the patch (no changes, other than a/ and b/ are now prefixed to the referenced paths), to hopefully trigger the build robot. Kind regards, Job Signed-off: Job Snijders --- resolv/inet_net_pton.c | 76 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c index aab9b7b582..163e76e1a5 100644 --- a/resolv/inet_net_pton.c +++ b/resolv/inet_net_pton.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 2022 Job Snijders + * Copyright (c) 2012 by Gilles Chehade * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -35,13 +37,16 @@ static int inet_net_pton_ipv4 (const char *src, u_char *dst, size_t size) __THROW; +static int inet_net_pton_ipv6 (const char *src, u_char *dst, + size_t size) __THROW; /* - * static int + * int * inet_net_pton(af, src, dst, size) - * convert network number from presentation to network format. - * accepts hex octets, hex strings, decimal octets, and /CIDR. - * "size" is in bytes and describes "dst". + * Convert network number from presentation format to network format. + * If "af" is set to AF_INET, accept various formats like hex octets, + * hex strings, or decimal octets. If "af" is set to AF_INET6, accept + * IPv6 addresses. "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was @@ -55,6 +60,8 @@ inet_net_pton (int af, const char *src, void *dst, size_t size) switch (af) { case AF_INET: return (inet_net_pton_ipv4(src, dst, size)); + case AF_INET6: + return (inet_net_pton_ipv6(src, dst, size)); default: __set_errno (EAFNOSUPPORT); return (-1); @@ -196,3 +203,64 @@ inet_net_pton_ipv4 (const char *src, u_char *dst, size_t size) __set_errno (EMSGSIZE); return (-1); } + + +/* + * Convert an IPv6 prefix from presentation format to network format. + * Return the number of bits specified, or -1 as error (check errno). + */ +static int +inet_net_pton_ipv6 (const char *src, u_char *dst, size_t size) +{ + struct in6_addr in6; + int bits; + long lbits; + size_t bytes; + char buf[INET6_ADDRSTRLEN + sizeof("/128")]; + char *ep, *sep; + + strncpy(buf, src, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + + sep = strchr(buf, '/'); + if (sep != NULL) + *sep++ = '\0'; + + if (inet_pton(AF_INET6, buf, &in6) != 1) { + __set_errno (ENOENT); + return (-1); + } + + if (sep == NULL) { + bits = 128; + goto out; + } + + if (sep[0] == '\0' || !isascii(sep[0]) || !isdigit(sep[0])) { + __set_errno (ENOENT); + return (-1); + } + + errno = 0; + lbits = strtol(sep, &ep, 10); + if (sep[0] == '\0' || *ep != '\0') { + __set_errno (ENOENT); + return (-1); + } + if ((errno == ERANGE && (lbits == LONG_MAX || lbits == LONG_MIN)) + || (lbits > 128 || lbits < 0)) { + __set_errno (EMSGSIZE); + return (-1); + } + bits = lbits; + + out: + bytes = (bits + 7) / 8; + if (bytes > size) { + __set_errno (EMSGSIZE); + return (-1); + } + + memcpy(dst, &in6.s6_addr, bytes); + return (bits); +}