From patchwork Thu Dec 22 17:54:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Job Snijders X-Patchwork-Id: 62285 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 9D064385B505 for ; Thu, 22 Dec 2022 17:55:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9D064385B505 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1671731727; bh=loavl9a2Aqkqn77xtVHYJboANT4guERkw1iKJeSk/Cs=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=e73vwETQ/t7AYS6y/v7Hf25sYXwzyy/y38XXQNEHg4BTMFF0Rwqf+EbULC7LXCtVj VyBT6UB1Y3JXE2IcGar4D/mCy8GL4zBurw3RHcrLjraY3Fi5Lm8bAneesQNoVWB+jx WvpL62z8f8uPLrdskyGytNsmOG+JinuJr7/HXtyk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 3E8793858D1E for ; Thu, 22 Dec 2022 17:55:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3E8793858D1E Received: by mail-ej1-x62e.google.com with SMTP id t17so6707121eju.1 for ; Thu, 22 Dec 2022 09:55:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=loavl9a2Aqkqn77xtVHYJboANT4guERkw1iKJeSk/Cs=; b=5UCR6rvlU3+UmPPxp+eqx0IhU9kLL1zQVgS6DRtFES00yunbGrN1IZSKHFzb44u2ON Nq7GdgxX279YHbuwp1EL6StLOcJaJVsWPqsNx6EGUGMCyI39RbQ1vj9A8bOSzBYR/LBu keUmvzw8HQlKMNgvO2cqN6nOMbHf7tmUZut4WimMbQnMWK/7L68P+OgMr3FZEwNeFjEC ehTW+sc9pRCoPL5HBh7+wefB7yhUnsJCkSpQ9O3eAJ3D7Abq7G/ImZnCCzJkGmBLFwma tWYjbR5oZYLEPnCHlyzH2FlAt28afvmSNFT+nxSsKnDXAcAc8XqrUxmdZitsdx5OKds/ JPog== X-Gm-Message-State: AFqh2kpwcNWBS5g9qXCAg0nkmWy22/go90rDax+9KjnLzBUGQ+g8l5ft euMZ/5h6yr5J9bixd3Q++yxZdZUG8UFwu1qHTezIP6AAvTzgw7FWXzXVf9aMokf37kSN6S+iua6 +P1Er8qeWelDI0FJ31+RN9jWg4G2X9EEgPP5iybDhbkzjyvU5/UgKXF1bujsQHpsV+kLNI6ky X-Google-Smtp-Source: AMrXdXu+Hh1RaF1ZL+uCXl8WUINM+NXVDkbAUbTJCQgYTkKnysFdDT9Sb5uRVso55fhl+N5g52Itiw== X-Received: by 2002:a17:906:99d1:b0:7c1:12ef:bf52 with SMTP id s17-20020a17090699d100b007c112efbf52mr4881682ejn.3.1671731700895; Thu, 22 Dec 2022 09:55:00 -0800 (PST) Received: from snel ([2a10:3781:276:1:16f6:d8ff:fe47:2eb7]) by smtp.gmail.com with ESMTPSA id w9-20020a1709062f8900b007c0baedc9d0sm482160eji.95.2022.12.22.09.54.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Dec 2022 09:55:00 -0800 (PST) Date: Thu, 22 Dec 2022 18:54:58 +0100 To: libc-alpha@sourceware.org Subject: [PATCH] resolv: add IPv6 support to inet_net_pton() Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett X-Spam-Status: No, score=-4.1 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 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, 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've tested the changeset on Debian Bookworm. Kind regards, Job Signed-off-by: Job Snijders diff --git resolv/inet_net_pton.c resolv/inet_net_pton.c index aab9b7b582..163e76e1a5 100644 --- resolv/inet_net_pton.c +++ 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); +}