LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - inet_net_pton.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 73.7 % 274 202 1 71 202 2
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 7 7 1 6
Baseline: lcov-20250906-005545-baseline Branches: 63.6 % 231 147 84 147
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 0.0 % 1 0 1
(360..) days: 74.0 % 273 202 71 202
Function coverage date bins:
(360..) days: 100.0 % 7 7 1 6
Branch coverage date bins:
(360..) days: 63.6 % 231 147 84 147

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
                                  3                 :                :  * Copyright (c) 1996,1999 by Internet Software Consortium.
                                  4                 :                :  *
                                  5                 :                :  * Permission to use, copy, modify, and distribute this software for any
                                  6                 :                :  * purpose with or without fee is hereby granted, provided that the above
                                  7                 :                :  * copyright notice and this permission notice appear in all copies.
                                  8                 :                :  *
                                  9                 :                :  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                                 10                 :                :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                                 11                 :                :  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                                 12                 :                :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                                 13                 :                :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                                 14                 :                :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                                 15                 :                :  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                                 16                 :                :  *
                                 17                 :                :  *    src/backend/utils/adt/inet_net_pton.c
                                 18                 :                :  */
                                 19                 :                : 
                                 20                 :                : #if defined(LIBC_SCCS) && !defined(lint)
                                 21                 :                : static const char rcsid[] = "Id: inet_net_pton.c,v 1.4.2.3 2004/03/17 00:40:11 marka Exp $";
                                 22                 :                : #endif
                                 23                 :                : 
                                 24                 :                : #include "postgres.h"
                                 25                 :                : 
                                 26                 :                : #include <sys/socket.h>
                                 27                 :                : #include <netinet/in.h>
                                 28                 :                : #include <arpa/inet.h>
                                 29                 :                : #include <assert.h>
                                 30                 :                : #include <ctype.h>
                                 31                 :                : 
                                 32                 :                : #include "utils/builtins.h"       /* needed on some platforms */
                                 33                 :                : #include "utils/inet.h"
                                 34                 :                : 
                                 35                 :                : 
                                 36                 :                : static int  inet_net_pton_ipv4(const char *src, u_char *dst);
                                 37                 :                : static int  inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size);
                                 38                 :                : static int  inet_net_pton_ipv6(const char *src, u_char *dst);
                                 39                 :                : static int  inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size);
                                 40                 :                : 
                                 41                 :                : 
                                 42                 :                : /*
                                 43                 :                :  * int
                                 44                 :                :  * pg_inet_net_pton(af, src, dst, size)
                                 45                 :                :  *  convert network number from presentation to network format.
                                 46                 :                :  *  accepts hex octets, hex strings, decimal octets, and /CIDR.
                                 47                 :                :  *  "size" is in bytes and describes "dst".
                                 48                 :                :  * return:
                                 49                 :                :  *  number of bits, either imputed classfully or specified with /CIDR,
                                 50                 :                :  *  or -1 if some failure occurred (check errno).  ENOENT means it was
                                 51                 :                :  *  not a valid network specification.
                                 52                 :                :  * author:
                                 53                 :                :  *  Paul Vixie (ISC), June 1996
                                 54                 :                :  *
                                 55                 :                :  * Changes:
                                 56                 :                :  *  I added the inet_cidr_pton function (also from Paul) and changed
                                 57                 :                :  *  the names to reflect their current use.
                                 58                 :                :  *
                                 59                 :                :  */
                                 60                 :                : int
 2211 tgl@sss.pgh.pa.us          61                 :CBC        3045 : pg_inet_net_pton(int af, const char *src, void *dst, size_t size)
                                 62                 :                : {
 9835 bruce@momjian.us           63      [ +  +  - ]:           3045 :     switch (af)
                                 64                 :                :     {
 8110                            65                 :           2482 :         case PGSQL_AF_INET:
                                 66                 :                :             return size == -1 ?
 8717                            67         [ +  + ]:           3194 :                 inet_net_pton_ipv4(src, dst) :
                                 68                 :            712 :                 inet_cidr_pton_ipv4(src, dst, size);
 8110                            69                 :            563 :         case PGSQL_AF_INET6:
                                 70                 :                :             return size == -1 ?
                                 71         [ +  + ]:            775 :                 inet_net_pton_ipv6(src, dst) :
                                 72                 :            212 :                 inet_cidr_pton_ipv6(src, dst, size);
 9835 bruce@momjian.us           73                 :UBC           0 :         default:
                                 74                 :              0 :             errno = EAFNOSUPPORT;
 2942 peter_e@gmx.net            75                 :              0 :             return -1;
                                 76                 :                :     }
                                 77                 :                : }
                                 78                 :                : 
                                 79                 :                : /*
                                 80                 :                :  * static int
                                 81                 :                :  * inet_cidr_pton_ipv4(src, dst, size)
                                 82                 :                :  *  convert IPv4 network number from presentation to network format.
                                 83                 :                :  *  accepts hex octets, hex strings, decimal octets, and /CIDR.
                                 84                 :                :  *  "size" is in bytes and describes "dst".
                                 85                 :                :  * return:
                                 86                 :                :  *  number of bits, either imputed classfully or specified with /CIDR,
                                 87                 :                :  *  or -1 if some failure occurred (check errno).  ENOENT means it was
                                 88                 :                :  *  not an IPv4 network specification.
                                 89                 :                :  * note:
                                 90                 :                :  *  network byte order assumed.  this means 192.5.5.240/28 has
                                 91                 :                :  *  0b11110000 in its fourth octet.
                                 92                 :                :  * author:
                                 93                 :                :  *  Paul Vixie (ISC), June 1996
                                 94                 :                :  */
                                 95                 :                : static int
 9816 bruce@momjian.us           96                 :CBC         712 : inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size)
                                 97                 :                : {
                                 98                 :                :     static const char xdigits[] = "0123456789abcdef";
                                 99                 :                :     static const char digits[] = "0123456789";
                                100                 :                :     int         n,
                                101                 :                :                 ch,
 7522 tgl@sss.pgh.pa.us         102                 :            712 :                 tmp = 0,
                                103                 :                :                 dirty,
                                104                 :                :                 bits;
 9835 bruce@momjian.us          105                 :            712 :     const u_char *odst = dst;
                                106                 :                : 
                                107                 :            712 :     ch = *src++;
                                108   [ +  +  +  -  :            712 :     if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
                                              -  + ]
 9043 tgl@sss.pgh.pa.us         109         [ #  # ]:UBC           0 :         && isxdigit((unsigned char) src[1]))
                                110                 :                :     {
                                111                 :                :         /* Hexadecimal: Eat nybble string. */
 7522                           112         [ #  # ]:              0 :         if (size <= 0U)
 9835 bruce@momjian.us          113                 :              0 :             goto emsgsize;
 9826                           114                 :              0 :         dirty = 0;
 9601                           115                 :              0 :         src++;                  /* skip x or X. */
 9043 tgl@sss.pgh.pa.us         116   [ #  #  #  # ]:              0 :         while ((ch = *src++) != '\0' && isxdigit((unsigned char) ch))
                                117                 :                :         {
   67 jdavis@postgresql.or      118                 :UNC           0 :             ch = pg_ascii_tolower((unsigned char) ch);
 9835 bruce@momjian.us          119                 :UBC           0 :             n = strchr(xdigits, ch) - xdigits;
                                120   [ #  #  #  # ]:              0 :             assert(n >= 0 && n <= 15);
 9821                           121         [ #  # ]:              0 :             if (dirty == 0)
                                122                 :              0 :                 tmp = n;
                                123                 :                :             else
                                124                 :              0 :                 tmp = (tmp << 4) | n;
 9601                           125         [ #  # ]:              0 :             if (++dirty == 2)
                                126                 :                :             {
 7522 tgl@sss.pgh.pa.us         127         [ #  # ]:              0 :                 if (size-- <= 0U)
 9826 bruce@momjian.us          128                 :              0 :                     goto emsgsize;
                                129                 :              0 :                 *dst++ = (u_char) tmp;
 9821                           130                 :              0 :                 dirty = 0;
                                131                 :                :             }
                                132                 :                :         }
 9601                           133         [ #  # ]:              0 :         if (dirty)
                                134                 :                :         {                       /* Odd trailing nybble? */
 7522 tgl@sss.pgh.pa.us         135         [ #  # ]:              0 :             if (size-- <= 0U)
 9835 bruce@momjian.us          136                 :              0 :                 goto emsgsize;
 9821                           137                 :              0 :             *dst++ = (u_char) (tmp << 4);
                                138                 :                :         }
                                139                 :                :     }
 9043 tgl@sss.pgh.pa.us         140         [ +  - ]:CBC         712 :     else if (isdigit((unsigned char) ch))
                                141                 :                :     {
                                142                 :                :         /* Decimal: eat dotted digit string. */
                                143                 :                :         for (;;)
                                144                 :                :         {
 9835 bruce@momjian.us          145                 :           2443 :             tmp = 0;
                                146                 :                :             do
                                147                 :                :             {
                                148                 :           4450 :                 n = strchr(digits, ch) - digits;
                                149   [ +  -  +  - ]:           4450 :                 assert(n >= 0 && n <= 9);
                                150                 :           4450 :                 tmp *= 10;
                                151                 :           4450 :                 tmp += n;
                                152         [ +  + ]:           4450 :                 if (tmp > 255)
                                153                 :              6 :                     goto enoent;
                                154         [ +  + ]:           4444 :             } while ((ch = *src++) != '\0' &&
 9043 tgl@sss.pgh.pa.us         155         [ +  + ]:           4194 :                      isdigit((unsigned char) ch));
 7522                           156         [ -  + ]:           2437 :             if (size-- <= 0U)
 9835 bruce@momjian.us          157                 :UBC           0 :                 goto emsgsize;
 9835 bruce@momjian.us          158                 :CBC        2437 :             *dst++ = (u_char) tmp;
                                159   [ +  +  +  + ]:           2437 :             if (ch == '\0' || ch == '/')
                                160                 :                :                 break;
                                161         [ -  + ]:           1731 :             if (ch != '.')
 9835 bruce@momjian.us          162                 :UBC           0 :                 goto enoent;
 9835 bruce@momjian.us          163                 :CBC        1731 :             ch = *src++;
 9043 tgl@sss.pgh.pa.us         164         [ -  + ]:           1731 :             if (!isdigit((unsigned char) ch))
 9835 bruce@momjian.us          165                 :UBC           0 :                 goto enoent;
                                166                 :                :         }
                                167                 :                :     }
                                168                 :                :     else
                                169                 :              0 :         goto enoent;
                                170                 :                : 
 9835 bruce@momjian.us          171                 :CBC         706 :     bits = -1;
 9043 tgl@sss.pgh.pa.us         172   [ +  +  +  -  :            706 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                              +  - ]
                                173                 :                :     {
                                174                 :                :         /* CIDR width specifier.  Nothing can follow it. */
 9835 bruce@momjian.us          175                 :            456 :         ch = *src++;            /* Skip over the /. */
                                176                 :            456 :         bits = 0;
                                177                 :                :         do
                                178                 :                :         {
                                179                 :            813 :             n = strchr(digits, ch) - digits;
                                180   [ +  -  +  - ]:            813 :             assert(n >= 0 && n <= 9);
                                181                 :            813 :             bits *= 10;
                                182                 :            813 :             bits += n;
 9043 tgl@sss.pgh.pa.us         183   [ +  +  +  - ]:            813 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9835 bruce@momjian.us          184         [ -  + ]:            456 :         if (ch != '\0')
 9835 bruce@momjian.us          185                 :UBC           0 :             goto enoent;
 9835 bruce@momjian.us          186         [ -  + ]:CBC         456 :         if (bits > 32)
 9835 bruce@momjian.us          187                 :UBC           0 :             goto emsgsize;
                                188                 :                :     }
                                189                 :                : 
                                190                 :                :     /* Fiery death and destruction unless we prefetched EOS. */
 9835 bruce@momjian.us          191         [ -  + ]:CBC         706 :     if (ch != '\0')
 9835 bruce@momjian.us          192                 :UBC           0 :         goto enoent;
                                193                 :                : 
                                194                 :                :     /* If nothing was written to the destination, we found no address. */
 9835 bruce@momjian.us          195         [ -  + ]:CBC         706 :     if (dst == odst)
 9835 bruce@momjian.us          196                 :UBC           0 :         goto enoent;
                                197                 :                :     /* If no CIDR spec was given, infer width from net class. */
 9835 bruce@momjian.us          198         [ +  + ]:CBC         706 :     if (bits == -1)
                                199                 :                :     {
                                200         [ +  + ]:            250 :         if (*odst >= 240)        /* Class E */
                                201                 :             96 :             bits = 32;
                                202         [ -  + ]:            154 :         else if (*odst >= 224)   /* Class D */
 7522 tgl@sss.pgh.pa.us         203                 :UBC           0 :             bits = 8;
 9835 bruce@momjian.us          204         [ +  + ]:CBC         154 :         else if (*odst >= 192)   /* Class C */
                                205                 :             15 :             bits = 24;
                                206         [ -  + ]:            139 :         else if (*odst >= 128)   /* Class B */
 9835 bruce@momjian.us          207                 :UBC           0 :             bits = 16;
                                208                 :                :         else
                                209                 :                :             /* Class A */
 9835 bruce@momjian.us          210                 :CBC         139 :             bits = 8;
                                211                 :                :         /* If imputed mask is narrower than specified octets, widen. */
 7522 tgl@sss.pgh.pa.us         212         [ +  + ]:            250 :         if (bits < ((dst - odst) * 8))
 9835 bruce@momjian.us          213                 :            124 :             bits = (dst - odst) * 8;
                                214                 :                : 
                                215                 :                :         /*
                                216                 :                :          * If there are no additional bits specified for a class D address
                                217                 :                :          * adjust bits to 4.
                                218                 :                :          */
 7522 tgl@sss.pgh.pa.us         219   [ +  +  -  + ]:            250 :         if (bits == 8 && *odst == 224)
 7522 tgl@sss.pgh.pa.us         220                 :UBC           0 :             bits = 4;
                                221                 :                :     }
                                222                 :                :     /* Extend network to cover the actual mask. */
 9835 bruce@momjian.us          223         [ +  + ]:CBC         730 :     while (bits > ((dst - odst) * 8))
                                224                 :                :     {
 7522 tgl@sss.pgh.pa.us         225         [ -  + ]:             24 :         if (size-- <= 0U)
 9835 bruce@momjian.us          226                 :UBC           0 :             goto emsgsize;
 9835 bruce@momjian.us          227                 :CBC          24 :         *dst++ = '\0';
                                228                 :                :     }
 2942 peter_e@gmx.net           229                 :            706 :     return bits;
                                230                 :                : 
 9835 bruce@momjian.us          231                 :              6 : enoent:
                                232                 :              6 :     errno = ENOENT;
 2942 peter_e@gmx.net           233                 :              6 :     return -1;
                                234                 :                : 
 9835 bruce@momjian.us          235                 :UBC           0 : emsgsize:
                                236                 :              0 :     errno = EMSGSIZE;
 2942 peter_e@gmx.net           237                 :              0 :     return -1;
                                238                 :                : }
                                239                 :                : 
                                240                 :                : /*
                                241                 :                :  * int
                                242                 :                :  * inet_net_pton_ipv4(af, src, dst, *bits)
                                243                 :                :  *  convert network address from presentation to network format.
                                244                 :                :  *  accepts inet_pton()'s input for this "af" plus trailing "/CIDR".
                                245                 :                :  *  "dst" is assumed large enough for its "af".  "bits" is set to the
                                246                 :                :  *  /CIDR prefix length, which can have defaults (like /32 for IPv4).
                                247                 :                :  * return:
                                248                 :                :  *  -1 if an error occurred (inspect errno; ENOENT means bad format).
                                249                 :                :  *  0 if successful conversion occurred.
                                250                 :                :  * note:
                                251                 :                :  *  192.5.5.1/28 has a nonzero host part, which means it isn't a network
                                252                 :                :  *  as called for by inet_cidr_pton() but it can be a host address with
                                253                 :                :  *  an included netmask.
                                254                 :                :  * author:
                                255                 :                :  *  Paul Vixie (ISC), October 1998
                                256                 :                :  */
                                257                 :                : static int
 9816 bruce@momjian.us          258                 :CBC        1770 : inet_net_pton_ipv4(const char *src, u_char *dst)
                                259                 :                : {
                                260                 :                :     static const char digits[] = "0123456789";
                                261                 :           1770 :     const u_char *odst = dst;
                                262                 :                :     int         n,
                                263                 :                :                 ch,
                                264                 :                :                 tmp,
                                265                 :                :                 bits;
 9601                           266                 :           1770 :     size_t      size = 4;
                                267                 :                : 
                                268                 :                :     /* Get the mantissa. */
 9043 tgl@sss.pgh.pa.us         269         [ +  - ]:           6882 :     while (ch = *src++, isdigit((unsigned char) ch))
                                270                 :                :     {
 9816 bruce@momjian.us          271                 :           6882 :         tmp = 0;
                                272                 :                :         do
                                273                 :                :         {
                                274                 :          14562 :             n = strchr(digits, ch) - digits;
                                275   [ +  -  +  - ]:          14562 :             assert(n >= 0 && n <= 9);
                                276                 :          14562 :             tmp *= 10;
                                277                 :          14562 :             tmp += n;
                                278         [ +  + ]:          14562 :             if (tmp > 255)
                                279                 :              6 :                 goto enoent;
 9043 tgl@sss.pgh.pa.us         280   [ +  +  +  + ]:          14556 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9816 bruce@momjian.us          281         [ -  + ]:           6876 :         if (size-- == 0)
 9816 bruce@momjian.us          282                 :UBC           0 :             goto emsgsize;
 9816 bruce@momjian.us          283                 :CBC        6876 :         *dst++ = (u_char) tmp;
                                284   [ +  +  +  + ]:           6876 :         if (ch == '\0' || ch == '/')
                                285                 :                :             break;
                                286         [ -  + ]:           5112 :         if (ch != '.')
 9816 bruce@momjian.us          287                 :UBC           0 :             goto enoent;
                                288                 :                :     }
                                289                 :                : 
                                290                 :                :     /* Get the prefix length if any. */
 9816 bruce@momjian.us          291                 :CBC        1764 :     bits = -1;
 9043 tgl@sss.pgh.pa.us         292   [ +  +  +  -  :           1764 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                              +  - ]
                                293                 :                :     {
                                294                 :                :         /* CIDR width specifier.  Nothing can follow it. */
 9601 bruce@momjian.us          295                 :            670 :         ch = *src++;            /* Skip over the /. */
 9816                           296                 :            670 :         bits = 0;
                                297                 :                :         do
                                298                 :                :         {
                                299                 :           1137 :             n = strchr(digits, ch) - digits;
                                300   [ +  -  +  - ]:           1137 :             assert(n >= 0 && n <= 9);
                                301                 :           1137 :             bits *= 10;
                                302                 :           1137 :             bits += n;
 9043 tgl@sss.pgh.pa.us         303   [ +  +  +  - ]:           1137 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9816 bruce@momjian.us          304         [ -  + ]:            670 :         if (ch != '\0')
 9816 bruce@momjian.us          305                 :UBC           0 :             goto enoent;
 9816 bruce@momjian.us          306         [ -  + ]:CBC         670 :         if (bits > 32)
 9816 bruce@momjian.us          307                 :UBC           0 :             goto emsgsize;
                                308                 :                :     }
                                309                 :                : 
                                310                 :                :     /* Fiery death and destruction unless we prefetched EOS. */
 9816 bruce@momjian.us          311         [ -  + ]:CBC        1764 :     if (ch != '\0')
 9816 bruce@momjian.us          312                 :UBC           0 :         goto enoent;
                                313                 :                : 
                                314                 :                :     /* Prefix length can default to /32 only if all four octets spec'd. */
 9816 bruce@momjian.us          315         [ +  + ]:CBC        1764 :     if (bits == -1)
                                316                 :                :     {
                                317         [ +  - ]:           1094 :         if (dst - odst == 4)
                                318                 :           1094 :             bits = 32;
                                319                 :                :         else
 9816 bruce@momjian.us          320                 :UBC           0 :             goto enoent;
                                321                 :                :     }
                                322                 :                : 
                                323                 :                :     /* If nothing was written to the destination, we found no address. */
 9816 bruce@momjian.us          324         [ -  + ]:CBC        1764 :     if (dst == odst)
 9816 bruce@momjian.us          325                 :UBC           0 :         goto enoent;
                                326                 :                : 
                                327                 :                :     /* If prefix length overspecifies mantissa, life is bad. */
 9816 bruce@momjian.us          328         [ -  + ]:CBC        1764 :     if ((bits / 8) > (dst - odst))
 9816 bruce@momjian.us          329                 :UBC           0 :         goto enoent;
                                330                 :                : 
                                331                 :                :     /* Extend address to four octets. */
 9816 bruce@momjian.us          332         [ +  + ]:CBC        1944 :     while (size-- > 0)
                                333                 :            180 :         *dst++ = 0;
                                334                 :                : 
                                335                 :           1764 :     return bits;
                                336                 :                : 
 9601                           337                 :              6 : enoent:
 9816                           338                 :              6 :     errno = ENOENT;
 2942 peter_e@gmx.net           339                 :              6 :     return -1;
                                340                 :                : 
 9601 bruce@momjian.us          341                 :UBC           0 : emsgsize:
 9816                           342                 :              0 :     errno = EMSGSIZE;
 2942 peter_e@gmx.net           343                 :              0 :     return -1;
                                344                 :                : }
                                345                 :                : 
                                346                 :                : static int
 8069 bruce@momjian.us          347                 :CBC         315 : getbits(const char *src, int *bitsp)
                                348                 :                : {
                                349                 :                :     static const char digits[] = "0123456789";
                                350                 :                :     int         n;
                                351                 :                :     int         val;
                                352                 :                :     char        ch;
                                353                 :                : 
 8110                           354                 :            315 :     val = 0;
                                355                 :            315 :     n = 0;
 8069                           356         [ +  + ]:           1014 :     while ((ch = *src++) != '\0')
                                357                 :                :     {
                                358                 :                :         const char *pch;
                                359                 :                : 
 8110                           360                 :            699 :         pch = strchr(digits, ch);
 8069                           361         [ +  - ]:            699 :         if (pch != NULL)
                                362                 :                :         {
 8110                           363   [ +  +  -  + ]:            699 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2942 peter_e@gmx.net           364                 :UBC           0 :                 return 0;
 8110 bruce@momjian.us          365                 :CBC         699 :             val *= 10;
                                366                 :            699 :             val += (pch - digits);
 8069                           367         [ -  + ]:            699 :             if (val > 128)       /* range */
 2942 peter_e@gmx.net           368                 :UBC           0 :                 return 0;
 8110 bruce@momjian.us          369                 :CBC         699 :             continue;
                                370                 :                :         }
 2942 peter_e@gmx.net           371                 :UBC           0 :         return 0;
                                372                 :                :     }
 8110 bruce@momjian.us          373         [ -  + ]:CBC         315 :     if (n == 0)
 2942 peter_e@gmx.net           374                 :UBC           0 :         return 0;
 8110 bruce@momjian.us          375                 :CBC         315 :     *bitsp = val;
 2942 peter_e@gmx.net           376                 :            315 :     return 1;
                                377                 :                : }
                                378                 :                : 
                                379                 :                : static int
 8069 bruce@momjian.us          380                 :             18 : getv4(const char *src, u_char *dst, int *bitsp)
                                381                 :                : {
                                382                 :                :     static const char digits[] = "0123456789";
                                383                 :             18 :     u_char     *odst = dst;
                                384                 :                :     int         n;
                                385                 :                :     u_int       val;
                                386                 :                :     char        ch;
                                387                 :                : 
 8110                           388                 :             18 :     val = 0;
                                389                 :             18 :     n = 0;
 8069                           390         [ +  + ]:            144 :     while ((ch = *src++) != '\0')
                                391                 :                :     {
                                392                 :                :         const char *pch;
                                393                 :                : 
 8110                           394                 :            141 :         pch = strchr(digits, ch);
 8069                           395         [ +  + ]:            141 :         if (pch != NULL)
                                396                 :                :         {
 8110                           397   [ -  +  -  - ]:             72 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2942 peter_e@gmx.net           398                 :UBC           0 :                 return 0;
 8110 bruce@momjian.us          399                 :CBC          72 :             val *= 10;
                                400                 :             72 :             val += (pch - digits);
 8069                           401         [ -  + ]:             72 :             if (val > 255)       /* range */
 2942 peter_e@gmx.net           402                 :UBC           0 :                 return 0;
 8110 bruce@momjian.us          403                 :CBC          72 :             continue;
                                404                 :                :         }
 8069                           405   [ +  +  +  - ]:             69 :         if (ch == '.' || ch == '/')
                                406                 :                :         {
                                407         [ -  + ]:             69 :             if (dst - odst > 3) /* too many octets? */
 2942 peter_e@gmx.net           408                 :UBC           0 :                 return 0;
 8110 bruce@momjian.us          409                 :CBC          69 :             *dst++ = val;
                                410         [ +  + ]:             69 :             if (ch == '/')
 2942 peter_e@gmx.net           411                 :             15 :                 return getbits(src, bitsp);
 8110 bruce@momjian.us          412                 :             54 :             val = 0;
                                413                 :             54 :             n = 0;
                                414                 :             54 :             continue;
                                415                 :                :         }
 2942 peter_e@gmx.net           416                 :UBC           0 :         return 0;
                                417                 :                :     }
 8110 bruce@momjian.us          418         [ -  + ]:CBC           3 :     if (n == 0)
 2942 peter_e@gmx.net           419                 :UBC           0 :         return 0;
 8069 bruce@momjian.us          420         [ -  + ]:CBC           3 :     if (dst - odst > 3)          /* too many octets? */
 2942 peter_e@gmx.net           421                 :UBC           0 :         return 0;
 8110 bruce@momjian.us          422                 :CBC           3 :     *dst++ = val;
 2942 peter_e@gmx.net           423                 :              3 :     return 1;
                                424                 :                : }
                                425                 :                : 
                                426                 :                : static int
 8110 bruce@momjian.us          427                 :            351 : inet_net_pton_ipv6(const char *src, u_char *dst)
                                428                 :                : {
                                429                 :            351 :     return inet_cidr_pton_ipv6(src, dst, 16);
                                430                 :                : }
                                431                 :                : 
                                432                 :                : #define NS_IN6ADDRSZ 16
                                433                 :                : #define NS_INT16SZ 2
                                434                 :                : #define NS_INADDRSZ 4
                                435                 :                : 
                                436                 :                : static int
 8069                           437                 :            563 : inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size)
                                438                 :                : {
                                439                 :                :     static const char xdigits_l[] = "0123456789abcdef",
                                440                 :                :                 xdigits_u[] = "0123456789ABCDEF";
                                441                 :                :     u_char      tmp[NS_IN6ADDRSZ],
                                442                 :                :                *tp,
                                443                 :                :                *endp,
                                444                 :                :                *colonp;
                                445                 :                :     const char *xdigits,
                                446                 :                :                *curtok;
                                447                 :                :     int         ch,
                                448                 :                :                 saw_xdigit;
                                449                 :                :     u_int       val;
                                450                 :                :     int         digits;
                                451                 :                :     int         bits;
                                452                 :                : 
 8110                           453         [ -  + ]:            563 :     if (size < NS_IN6ADDRSZ)
 8110 bruce@momjian.us          454                 :UBC           0 :         goto emsgsize;
                                455                 :                : 
 8110 bruce@momjian.us          456                 :CBC         563 :     memset((tp = tmp), '\0', NS_IN6ADDRSZ);
                                457                 :            563 :     endp = tp + NS_IN6ADDRSZ;
                                458                 :            563 :     colonp = NULL;
                                459                 :                :     /* Leading :: requires some special handling. */
                                460         [ +  + ]:            563 :     if (*src == ':')
                                461         [ -  + ]:             33 :         if (*++src != ':')
 8110 bruce@momjian.us          462                 :UBC           0 :             goto enoent;
 8110 bruce@momjian.us          463                 :CBC         563 :     curtok = src;
                                464                 :            563 :     saw_xdigit = 0;
                                465                 :            563 :     val = 0;
                                466                 :            563 :     digits = 0;
                                467                 :            563 :     bits = -1;
 8069                           468         [ +  + ]:          12355 :     while ((ch = *src++) != '\0')
                                469                 :                :     {
                                470                 :                :         const char *pch;
                                471                 :                : 
 8110                           472         [ +  + ]:          12113 :         if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
                                473                 :           2862 :             pch = strchr((xdigits = xdigits_u), ch);
 8069                           474         [ +  + ]:          12113 :         if (pch != NULL)
                                475                 :                :         {
 8110                           476                 :           9251 :             val <<= 4;
                                477                 :           9251 :             val |= (pch - xdigits);
                                478         [ -  + ]:           9251 :             if (++digits > 4)
 8110 bruce@momjian.us          479                 :UBC           0 :                 goto enoent;
 8110 bruce@momjian.us          480                 :CBC        9251 :             saw_xdigit = 1;
                                481                 :           9251 :             continue;
                                482                 :                :         }
 8069                           483         [ +  + ]:           2862 :         if (ch == ':')
                                484                 :                :         {
 8110                           485                 :           2544 :             curtok = src;
 8069                           486         [ +  + ]:           2544 :             if (!saw_xdigit)
                                487                 :                :             {
 8110                           488         [ +  + ]:            475 :                 if (colonp)
                                489                 :              3 :                     goto enoent;
                                490                 :            472 :                 colonp = tp;
                                491                 :            472 :                 continue;
                                492                 :                :             }
 8069                           493         [ -  + ]:           2069 :             else if (*src == '\0')
 8110 bruce@momjian.us          494                 :UBC           0 :                 goto enoent;
 8110 bruce@momjian.us          495         [ -  + ]:CBC        2069 :             if (tp + NS_INT16SZ > endp)
 3369 tgl@sss.pgh.pa.us         496                 :UBC           0 :                 goto enoent;
 8110 bruce@momjian.us          497                 :CBC        2069 :             *tp++ = (u_char) (val >> 8) & 0xff;
                                498                 :           2069 :             *tp++ = (u_char) val & 0xff;
                                499                 :           2069 :             saw_xdigit = 0;
                                500                 :           2069 :             digits = 0;
                                501                 :           2069 :             val = 0;
                                502                 :           2069 :             continue;
                                503                 :                :         }
                                504   [ +  +  +  -  :            336 :         if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
                                              +  - ]
 8069                           505                 :             18 :             getv4(curtok, tp, &bits) > 0)
                                506                 :                :         {
 8110                           507                 :             18 :             tp += NS_INADDRSZ;
                                508                 :             18 :             saw_xdigit = 0;
 8069                           509                 :             18 :             break;              /* '\0' was seen by inet_pton4(). */
                                510                 :                :         }
 8110                           511   [ +  -  +  - ]:            300 :         if (ch == '/' && getbits(src, &bits) > 0)
                                512                 :            300 :             break;
 8110 bruce@momjian.us          513                 :UBC           0 :         goto enoent;
                                514                 :                :     }
 8069 bruce@momjian.us          515         [ +  + ]:CBC         560 :     if (saw_xdigit)
                                516                 :                :     {
 8110                           517         [ -  + ]:            482 :         if (tp + NS_INT16SZ > endp)
 8110 bruce@momjian.us          518                 :UBC           0 :             goto enoent;
 8110 bruce@momjian.us          519                 :CBC         482 :         *tp++ = (u_char) (val >> 8) & 0xff;
                                520                 :            482 :         *tp++ = (u_char) val & 0xff;
                                521                 :                :     }
                                522         [ +  + ]:            560 :     if (bits == -1)
                                523                 :            245 :         bits = 128;
                                524                 :                : 
 8069                           525                 :            560 :     endp = tmp + 16;
                                526                 :                : 
                                527         [ +  + ]:            560 :     if (colonp != NULL)
                                528                 :                :     {
                                529                 :                :         /*
                                530                 :                :          * Since some memmove()'s erroneously fail to handle overlapping
                                531                 :                :          * regions, we'll do the shift by hand.
                                532                 :                :          */
                                533                 :            469 :         const int   n = tp - colonp;
                                534                 :                :         int         i;
                                535                 :                : 
 8110                           536         [ -  + ]:            469 :         if (tp == endp)
 8110 bruce@momjian.us          537                 :UBC           0 :             goto enoent;
 8069 bruce@momjian.us          538         [ +  + ]:CBC        3159 :         for (i = 1; i <= n; i++)
                                539                 :                :         {
                                540                 :           2690 :             endp[-i] = colonp[n - i];
 8110                           541                 :           2690 :             colonp[n - i] = 0;
                                542                 :                :         }
                                543                 :            469 :         tp = endp;
                                544                 :                :     }
                                545         [ -  + ]:            560 :     if (tp != endp)
 8110 bruce@momjian.us          546                 :UBC           0 :         goto enoent;
                                547                 :                : 
                                548                 :                :     /*
                                549                 :                :      * Copy out the result.
                                550                 :                :      */
 8110 bruce@momjian.us          551                 :CBC         560 :     memcpy(dst, tmp, NS_IN6ADDRSZ);
                                552                 :                : 
 2942 peter_e@gmx.net           553                 :            560 :     return bits;
                                554                 :                : 
 8069 bruce@momjian.us          555                 :              3 : enoent:
 8110                           556                 :              3 :     errno = ENOENT;
 2942 peter_e@gmx.net           557                 :              3 :     return -1;
                                558                 :                : 
 8069 bruce@momjian.us          559                 :UBC           0 : emsgsize:
 8110                           560                 :              0 :     errno = EMSGSIZE;
 2942 peter_e@gmx.net           561                 :              0 :     return -1;
                                562                 :                : }
        

Generated by: LCOV version 2.4-beta