LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - inet_net_pton.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 73.5 % 275 202 73 202
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 7 7 7
Baseline: 16@8cea358b128 Branches: 63.1 % 233 147 86 147
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 73.5 % 275 202 73 202
Function coverage date bins:
(240..) days: 100.0 % 7 7 7
Branch coverage date bins:
(240..) days: 63.1 % 233 147 86 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" /* pgrminclude ignore */  /* needed on some
                                 33                 :                :                                                          * platforms */
                                 34                 :                : #include "utils/inet.h"
                                 35                 :                : 
                                 36                 :                : 
                                 37                 :                : static int  inet_net_pton_ipv4(const char *src, u_char *dst);
                                 38                 :                : static int  inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size);
                                 39                 :                : static int  inet_net_pton_ipv6(const char *src, u_char *dst);
                                 40                 :                : static int  inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size);
                                 41                 :                : 
                                 42                 :                : 
                                 43                 :                : /*
                                 44                 :                :  * int
                                 45                 :                :  * pg_inet_net_pton(af, src, dst, size)
                                 46                 :                :  *  convert network number from presentation to network format.
                                 47                 :                :  *  accepts hex octets, hex strings, decimal octets, and /CIDR.
                                 48                 :                :  *  "size" is in bytes and describes "dst".
                                 49                 :                :  * return:
                                 50                 :                :  *  number of bits, either imputed classfully or specified with /CIDR,
                                 51                 :                :  *  or -1 if some failure occurred (check errno).  ENOENT means it was
                                 52                 :                :  *  not a valid network specification.
                                 53                 :                :  * author:
                                 54                 :                :  *  Paul Vixie (ISC), June 1996
                                 55                 :                :  *
                                 56                 :                :  * Changes:
                                 57                 :                :  *  I added the inet_cidr_pton function (also from Paul) and changed
                                 58                 :                :  *  the names to reflect their current use.
                                 59                 :                :  *
                                 60                 :                :  */
                                 61                 :                : int
 1701 tgl@sss.pgh.pa.us          62                 :CBC        2874 : pg_inet_net_pton(int af, const char *src, void *dst, size_t size)
                                 63                 :                : {
 9325 bruce@momjian.us           64      [ +  +  - ]:           2874 :     switch (af)
                                 65                 :                :     {
 7600                            66                 :           2426 :         case PGSQL_AF_INET:
                                 67                 :                :             return size == -1 ?
 8207                            68         [ +  + ]:           2981 :                 inet_net_pton_ipv4(src, dst) :
                                 69                 :            555 :                 inet_cidr_pton_ipv4(src, dst, size);
 7600                            70                 :            448 :         case PGSQL_AF_INET6:
                                 71                 :                :             return size == -1 ?
                                 72         [ +  + ]:            592 :                 inet_net_pton_ipv6(src, dst) :
                                 73                 :            144 :                 inet_cidr_pton_ipv6(src, dst, size);
 9325 bruce@momjian.us           74                 :UBC           0 :         default:
                                 75                 :              0 :             errno = EAFNOSUPPORT;
 2432 peter_e@gmx.net            76                 :              0 :             return -1;
                                 77                 :                :     }
                                 78                 :                : }
                                 79                 :                : 
                                 80                 :                : /*
                                 81                 :                :  * static int
                                 82                 :                :  * inet_cidr_pton_ipv4(src, dst, size)
                                 83                 :                :  *  convert IPv4 network number from presentation to network format.
                                 84                 :                :  *  accepts hex octets, hex strings, decimal octets, and /CIDR.
                                 85                 :                :  *  "size" is in bytes and describes "dst".
                                 86                 :                :  * return:
                                 87                 :                :  *  number of bits, either imputed classfully or specified with /CIDR,
                                 88                 :                :  *  or -1 if some failure occurred (check errno).  ENOENT means it was
                                 89                 :                :  *  not an IPv4 network specification.
                                 90                 :                :  * note:
                                 91                 :                :  *  network byte order assumed.  this means 192.5.5.240/28 has
                                 92                 :                :  *  0b11110000 in its fourth octet.
                                 93                 :                :  * author:
                                 94                 :                :  *  Paul Vixie (ISC), June 1996
                                 95                 :                :  */
                                 96                 :                : static int
 9306 bruce@momjian.us           97                 :CBC         555 : inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size)
                                 98                 :                : {
                                 99                 :                :     static const char xdigits[] = "0123456789abcdef";
                                100                 :                :     static const char digits[] = "0123456789";
                                101                 :                :     int         n,
                                102                 :                :                 ch,
 7012 tgl@sss.pgh.pa.us         103                 :            555 :                 tmp = 0,
                                104                 :                :                 dirty,
                                105                 :                :                 bits;
 9325 bruce@momjian.us          106                 :            555 :     const u_char *odst = dst;
                                107                 :                : 
                                108                 :            555 :     ch = *src++;
                                109   [ +  +  +  -  :            555 :     if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
                                              -  + ]
 8533 tgl@sss.pgh.pa.us         110         [ #  # ]:UBC           0 :         && isxdigit((unsigned char) src[1]))
                                111                 :                :     {
                                112                 :                :         /* Hexadecimal: Eat nybble string. */
 7012                           113         [ #  # ]:              0 :         if (size <= 0U)
 9325 bruce@momjian.us          114                 :              0 :             goto emsgsize;
 9316                           115                 :              0 :         dirty = 0;
 9091                           116                 :              0 :         src++;                  /* skip x or X. */
 8533 tgl@sss.pgh.pa.us         117   [ #  #  #  # ]:              0 :         while ((ch = *src++) != '\0' && isxdigit((unsigned char) ch))
                                118                 :                :         {
                                119         [ #  # ]:              0 :             if (isupper((unsigned char) ch))
                                120                 :              0 :                 ch = tolower((unsigned char) ch);
 9325 bruce@momjian.us          121                 :              0 :             n = strchr(xdigits, ch) - xdigits;
                                122   [ #  #  #  # ]:              0 :             assert(n >= 0 && n <= 15);
 9311                           123         [ #  # ]:              0 :             if (dirty == 0)
                                124                 :              0 :                 tmp = n;
                                125                 :                :             else
                                126                 :              0 :                 tmp = (tmp << 4) | n;
 9091                           127         [ #  # ]:              0 :             if (++dirty == 2)
                                128                 :                :             {
 7012 tgl@sss.pgh.pa.us         129         [ #  # ]:              0 :                 if (size-- <= 0U)
 9316 bruce@momjian.us          130                 :              0 :                     goto emsgsize;
                                131                 :              0 :                 *dst++ = (u_char) tmp;
 9311                           132                 :              0 :                 dirty = 0;
                                133                 :                :             }
                                134                 :                :         }
 9091                           135         [ #  # ]:              0 :         if (dirty)
                                136                 :                :         {                       /* Odd trailing nybble? */
 7012 tgl@sss.pgh.pa.us         137         [ #  # ]:              0 :             if (size-- <= 0U)
 9325 bruce@momjian.us          138                 :              0 :                 goto emsgsize;
 9311                           139                 :              0 :             *dst++ = (u_char) (tmp << 4);
                                140                 :                :         }
                                141                 :                :     }
 8533 tgl@sss.pgh.pa.us         142         [ +  - ]:CBC         555 :     else if (isdigit((unsigned char) ch))
                                143                 :                :     {
                                144                 :                :         /* Decimal: eat dotted digit string. */
                                145                 :                :         for (;;)
                                146                 :                :         {
 9325 bruce@momjian.us          147                 :           1815 :             tmp = 0;
                                148                 :                :             do
                                149                 :                :             {
                                150                 :           3490 :                 n = strchr(digits, ch) - digits;
                                151   [ +  -  +  - ]:           3490 :                 assert(n >= 0 && n <= 9);
                                152                 :           3490 :                 tmp *= 10;
                                153                 :           3490 :                 tmp += n;
                                154         [ +  + ]:           3490 :                 if (tmp > 255)
                                155                 :              6 :                     goto enoent;
                                156         [ +  + ]:           3484 :             } while ((ch = *src++) != '\0' &&
 8533 tgl@sss.pgh.pa.us         157         [ +  + ]:           3234 :                      isdigit((unsigned char) ch));
 7012                           158         [ -  + ]:           1809 :             if (size-- <= 0U)
 9325 bruce@momjian.us          159                 :UBC           0 :                 goto emsgsize;
 9325 bruce@momjian.us          160                 :CBC        1809 :             *dst++ = (u_char) tmp;
                                161   [ +  +  +  + ]:           1809 :             if (ch == '\0' || ch == '/')
                                162                 :                :                 break;
                                163         [ -  + ]:           1260 :             if (ch != '.')
 9325 bruce@momjian.us          164                 :UBC           0 :                 goto enoent;
 9325 bruce@momjian.us          165                 :CBC        1260 :             ch = *src++;
 8533 tgl@sss.pgh.pa.us         166         [ -  + ]:           1260 :             if (!isdigit((unsigned char) ch))
 9325 bruce@momjian.us          167                 :UBC           0 :                 goto enoent;
                                168                 :                :         }
                                169                 :                :     }
                                170                 :                :     else
                                171                 :              0 :         goto enoent;
                                172                 :                : 
 9325 bruce@momjian.us          173                 :CBC         549 :     bits = -1;
 8533 tgl@sss.pgh.pa.us         174   [ +  +  +  -  :            549 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                              +  - ]
                                175                 :                :     {
                                176                 :                :         /* CIDR width specifier.  Nothing can follow it. */
 9325 bruce@momjian.us          177                 :            299 :         ch = *src++;            /* Skip over the /. */
                                178                 :            299 :         bits = 0;
                                179                 :                :         do
                                180                 :                :         {
                                181                 :            523 :             n = strchr(digits, ch) - digits;
                                182   [ +  -  +  - ]:            523 :             assert(n >= 0 && n <= 9);
                                183                 :            523 :             bits *= 10;
                                184                 :            523 :             bits += n;
 8533 tgl@sss.pgh.pa.us         185   [ +  +  +  - ]:            523 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9325 bruce@momjian.us          186         [ -  + ]:            299 :         if (ch != '\0')
 9325 bruce@momjian.us          187                 :UBC           0 :             goto enoent;
 9325 bruce@momjian.us          188         [ -  + ]:CBC         299 :         if (bits > 32)
 9325 bruce@momjian.us          189                 :UBC           0 :             goto emsgsize;
                                190                 :                :     }
                                191                 :                : 
                                192                 :                :     /* Fiery death and destruction unless we prefetched EOS. */
 9325 bruce@momjian.us          193         [ -  + ]:CBC         549 :     if (ch != '\0')
 9325 bruce@momjian.us          194                 :UBC           0 :         goto enoent;
                                195                 :                : 
                                196                 :                :     /* If nothing was written to the destination, we found no address. */
 9325 bruce@momjian.us          197         [ -  + ]:CBC         549 :     if (dst == odst)
 9325 bruce@momjian.us          198                 :UBC           0 :         goto enoent;
                                199                 :                :     /* If no CIDR spec was given, infer width from net class. */
 9325 bruce@momjian.us          200         [ +  + ]:CBC         549 :     if (bits == -1)
                                201                 :                :     {
                                202         [ +  + ]:            250 :         if (*odst >= 240)        /* Class E */
                                203                 :             96 :             bits = 32;
                                204         [ -  + ]:            154 :         else if (*odst >= 224)   /* Class D */
 7012 tgl@sss.pgh.pa.us         205                 :UBC           0 :             bits = 8;
 9325 bruce@momjian.us          206         [ +  + ]:CBC         154 :         else if (*odst >= 192)   /* Class C */
                                207                 :             15 :             bits = 24;
                                208         [ -  + ]:            139 :         else if (*odst >= 128)   /* Class B */
 9325 bruce@momjian.us          209                 :UBC           0 :             bits = 16;
                                210                 :                :         else
                                211                 :                :             /* Class A */
 9325 bruce@momjian.us          212                 :CBC         139 :             bits = 8;
                                213                 :                :         /* If imputed mask is narrower than specified octets, widen. */
 7012 tgl@sss.pgh.pa.us         214         [ +  + ]:            250 :         if (bits < ((dst - odst) * 8))
 9325 bruce@momjian.us          215                 :            124 :             bits = (dst - odst) * 8;
                                216                 :                : 
                                217                 :                :         /*
                                218                 :                :          * If there are no additional bits specified for a class D address
                                219                 :                :          * adjust bits to 4.
                                220                 :                :          */
 7012 tgl@sss.pgh.pa.us         221   [ +  +  -  + ]:            250 :         if (bits == 8 && *odst == 224)
 7012 tgl@sss.pgh.pa.us         222                 :UBC           0 :             bits = 4;
                                223                 :                :     }
                                224                 :                :     /* Extend network to cover the actual mask. */
 9325 bruce@momjian.us          225         [ +  + ]:CBC         573 :     while (bits > ((dst - odst) * 8))
                                226                 :                :     {
 7012 tgl@sss.pgh.pa.us         227         [ -  + ]:             24 :         if (size-- <= 0U)
 9325 bruce@momjian.us          228                 :UBC           0 :             goto emsgsize;
 9325 bruce@momjian.us          229                 :CBC          24 :         *dst++ = '\0';
                                230                 :                :     }
 2432 peter_e@gmx.net           231                 :            549 :     return bits;
                                232                 :                : 
 9325 bruce@momjian.us          233                 :              6 : enoent:
                                234                 :              6 :     errno = ENOENT;
 2432 peter_e@gmx.net           235                 :              6 :     return -1;
                                236                 :                : 
 9325 bruce@momjian.us          237                 :UBC           0 : emsgsize:
                                238                 :              0 :     errno = EMSGSIZE;
 2432 peter_e@gmx.net           239                 :              0 :     return -1;
                                240                 :                : }
                                241                 :                : 
                                242                 :                : /*
                                243                 :                :  * int
                                244                 :                :  * inet_net_pton_ipv4(af, src, dst, *bits)
                                245                 :                :  *  convert network address from presentation to network format.
                                246                 :                :  *  accepts inet_pton()'s input for this "af" plus trailing "/CIDR".
                                247                 :                :  *  "dst" is assumed large enough for its "af".  "bits" is set to the
                                248                 :                :  *  /CIDR prefix length, which can have defaults (like /32 for IPv4).
                                249                 :                :  * return:
                                250                 :                :  *  -1 if an error occurred (inspect errno; ENOENT means bad format).
                                251                 :                :  *  0 if successful conversion occurred.
                                252                 :                :  * note:
                                253                 :                :  *  192.5.5.1/28 has a nonzero host part, which means it isn't a network
                                254                 :                :  *  as called for by inet_cidr_pton() but it can be a host address with
                                255                 :                :  *  an included netmask.
                                256                 :                :  * author:
                                257                 :                :  *  Paul Vixie (ISC), October 1998
                                258                 :                :  */
                                259                 :                : static int
 9306 bruce@momjian.us          260                 :CBC        1871 : inet_net_pton_ipv4(const char *src, u_char *dst)
                                261                 :                : {
                                262                 :                :     static const char digits[] = "0123456789";
                                263                 :           1871 :     const u_char *odst = dst;
                                264                 :                :     int         n,
                                265                 :                :                 ch,
                                266                 :                :                 tmp,
                                267                 :                :                 bits;
 9091                           268                 :           1871 :     size_t      size = 4;
                                269                 :                : 
                                270                 :                :     /* Get the mantissa. */
 8533 tgl@sss.pgh.pa.us         271         [ +  - ]:           7286 :     while (ch = *src++, isdigit((unsigned char) ch))
                                272                 :                :     {
 9306 bruce@momjian.us          273                 :           7286 :         tmp = 0;
                                274                 :                :         do
                                275                 :                :         {
                                276                 :          14887 :             n = strchr(digits, ch) - digits;
                                277   [ +  -  +  - ]:          14887 :             assert(n >= 0 && n <= 9);
                                278                 :          14887 :             tmp *= 10;
                                279                 :          14887 :             tmp += n;
                                280         [ +  + ]:          14887 :             if (tmp > 255)
                                281                 :              6 :                 goto enoent;
 8533 tgl@sss.pgh.pa.us         282   [ +  +  +  + ]:          14881 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9306 bruce@momjian.us          283         [ -  + ]:           7280 :         if (size-- == 0)
 9306 bruce@momjian.us          284                 :UBC           0 :             goto emsgsize;
 9306 bruce@momjian.us          285                 :CBC        7280 :         *dst++ = (u_char) tmp;
                                286   [ +  +  +  + ]:           7280 :         if (ch == '\0' || ch == '/')
                                287                 :                :             break;
                                288         [ -  + ]:           5415 :         if (ch != '.')
 9306 bruce@momjian.us          289                 :UBC           0 :             goto enoent;
                                290                 :                :     }
                                291                 :                : 
                                292                 :                :     /* Get the prefix length if any. */
 9306 bruce@momjian.us          293                 :CBC        1865 :     bits = -1;
 8533 tgl@sss.pgh.pa.us         294   [ +  +  +  -  :           1865 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                              +  - ]
                                295                 :                :     {
                                296                 :                :         /* CIDR width specifier.  Nothing can follow it. */
 9091 bruce@momjian.us          297                 :            469 :         ch = *src++;            /* Skip over the /. */
 9306                           298                 :            469 :         bits = 0;
                                299                 :                :         do
                                300                 :                :         {
                                301                 :            750 :             n = strchr(digits, ch) - digits;
                                302   [ +  -  +  - ]:            750 :             assert(n >= 0 && n <= 9);
                                303                 :            750 :             bits *= 10;
                                304                 :            750 :             bits += n;
 8533 tgl@sss.pgh.pa.us         305   [ +  +  +  - ]:            750 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 9306 bruce@momjian.us          306         [ -  + ]:            469 :         if (ch != '\0')
 9306 bruce@momjian.us          307                 :UBC           0 :             goto enoent;
 9306 bruce@momjian.us          308         [ -  + ]:CBC         469 :         if (bits > 32)
 9306 bruce@momjian.us          309                 :UBC           0 :             goto emsgsize;
                                310                 :                :     }
                                311                 :                : 
                                312                 :                :     /* Fiery death and destruction unless we prefetched EOS. */
 9306 bruce@momjian.us          313         [ -  + ]:CBC        1865 :     if (ch != '\0')
 9306 bruce@momjian.us          314                 :UBC           0 :         goto enoent;
                                315                 :                : 
                                316                 :                :     /* Prefix length can default to /32 only if all four octets spec'd. */
 9306 bruce@momjian.us          317         [ +  + ]:CBC        1865 :     if (bits == -1)
                                318                 :                :     {
                                319         [ +  - ]:           1396 :         if (dst - odst == 4)
                                320                 :           1396 :             bits = 32;
                                321                 :                :         else
 9306 bruce@momjian.us          322                 :UBC           0 :             goto enoent;
                                323                 :                :     }
                                324                 :                : 
                                325                 :                :     /* If nothing was written to the destination, we found no address. */
 9306 bruce@momjian.us          326         [ -  + ]:CBC        1865 :     if (dst == odst)
 9306 bruce@momjian.us          327                 :UBC           0 :         goto enoent;
                                328                 :                : 
                                329                 :                :     /* If prefix length overspecifies mantissa, life is bad. */
 9306 bruce@momjian.us          330         [ -  + ]:CBC        1865 :     if ((bits / 8) > (dst - odst))
 9306 bruce@momjian.us          331                 :UBC           0 :         goto enoent;
                                332                 :                : 
                                333                 :                :     /* Extend address to four octets. */
 9306 bruce@momjian.us          334         [ +  + ]:CBC        2045 :     while (size-- > 0)
                                335                 :            180 :         *dst++ = 0;
                                336                 :                : 
                                337                 :           1865 :     return bits;
                                338                 :                : 
 9091                           339                 :              6 : enoent:
 9306                           340                 :              6 :     errno = ENOENT;
 2432 peter_e@gmx.net           341                 :              6 :     return -1;
                                342                 :                : 
 9091 bruce@momjian.us          343                 :UBC           0 : emsgsize:
 9306                           344                 :              0 :     errno = EMSGSIZE;
 2432 peter_e@gmx.net           345                 :              0 :     return -1;
                                346                 :                : }
                                347                 :                : 
                                348                 :                : static int
 7559 bruce@momjian.us          349                 :CBC         238 : getbits(const char *src, int *bitsp)
                                350                 :                : {
                                351                 :                :     static const char digits[] = "0123456789";
                                352                 :                :     int         n;
                                353                 :                :     int         val;
                                354                 :                :     char        ch;
                                355                 :                : 
 7600                           356                 :            238 :     val = 0;
                                357                 :            238 :     n = 0;
 7559                           358         [ +  + ]:            712 :     while ((ch = *src++) != '\0')
                                359                 :                :     {
                                360                 :                :         const char *pch;
                                361                 :                : 
 7600                           362                 :            474 :         pch = strchr(digits, ch);
 7559                           363         [ +  - ]:            474 :         if (pch != NULL)
                                364                 :                :         {
 7600                           365   [ +  +  -  + ]:            474 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2432 peter_e@gmx.net           366                 :UBC           0 :                 return 0;
 7600 bruce@momjian.us          367                 :CBC         474 :             val *= 10;
                                368                 :            474 :             val += (pch - digits);
 7559                           369         [ -  + ]:            474 :             if (val > 128)       /* range */
 2432 peter_e@gmx.net           370                 :UBC           0 :                 return 0;
 7600 bruce@momjian.us          371                 :CBC         474 :             continue;
                                372                 :                :         }
 2432 peter_e@gmx.net           373                 :UBC           0 :         return 0;
                                374                 :                :     }
 7600 bruce@momjian.us          375         [ -  + ]:CBC         238 :     if (n == 0)
 2432 peter_e@gmx.net           376                 :UBC           0 :         return 0;
 7600 bruce@momjian.us          377                 :CBC         238 :     *bitsp = val;
 2432 peter_e@gmx.net           378                 :            238 :     return 1;
                                379                 :                : }
                                380                 :                : 
                                381                 :                : static int
 7559 bruce@momjian.us          382                 :              9 : getv4(const char *src, u_char *dst, int *bitsp)
                                383                 :                : {
                                384                 :                :     static const char digits[] = "0123456789";
                                385                 :              9 :     u_char     *odst = dst;
                                386                 :                :     int         n;
                                387                 :                :     u_int       val;
                                388                 :                :     char        ch;
                                389                 :                : 
 7600                           390                 :              9 :     val = 0;
                                391                 :              9 :     n = 0;
 7559                           392         [ +  + ]:             72 :     while ((ch = *src++) != '\0')
                                393                 :                :     {
                                394                 :                :         const char *pch;
                                395                 :                : 
 7600                           396                 :             69 :         pch = strchr(digits, ch);
 7559                           397         [ +  + ]:             69 :         if (pch != NULL)
                                398                 :                :         {
 7600                           399   [ -  +  -  - ]:             36 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2432 peter_e@gmx.net           400                 :UBC           0 :                 return 0;
 7600 bruce@momjian.us          401                 :CBC          36 :             val *= 10;
                                402                 :             36 :             val += (pch - digits);
 7559                           403         [ -  + ]:             36 :             if (val > 255)       /* range */
 2432 peter_e@gmx.net           404                 :UBC           0 :                 return 0;
 7600 bruce@momjian.us          405                 :CBC          36 :             continue;
                                406                 :                :         }
 7559                           407   [ +  +  +  - ]:             33 :         if (ch == '.' || ch == '/')
                                408                 :                :         {
                                409         [ -  + ]:             33 :             if (dst - odst > 3) /* too many octets? */
 2432 peter_e@gmx.net           410                 :UBC           0 :                 return 0;
 7600 bruce@momjian.us          411                 :CBC          33 :             *dst++ = val;
                                412         [ +  + ]:             33 :             if (ch == '/')
 2432 peter_e@gmx.net           413                 :              6 :                 return getbits(src, bitsp);
 7600 bruce@momjian.us          414                 :             27 :             val = 0;
                                415                 :             27 :             n = 0;
                                416                 :             27 :             continue;
                                417                 :                :         }
 2432 peter_e@gmx.net           418                 :UBC           0 :         return 0;
                                419                 :                :     }
 7600 bruce@momjian.us          420         [ -  + ]:CBC           3 :     if (n == 0)
 2432 peter_e@gmx.net           421                 :UBC           0 :         return 0;
 7559 bruce@momjian.us          422         [ -  + ]:CBC           3 :     if (dst - odst > 3)          /* too many octets? */
 2432 peter_e@gmx.net           423                 :UBC           0 :         return 0;
 7600 bruce@momjian.us          424                 :CBC           3 :     *dst++ = val;
 2432 peter_e@gmx.net           425                 :              3 :     return 1;
                                426                 :                : }
                                427                 :                : 
                                428                 :                : static int
 7600 bruce@momjian.us          429                 :            304 : inet_net_pton_ipv6(const char *src, u_char *dst)
                                430                 :                : {
                                431                 :            304 :     return inet_cidr_pton_ipv6(src, dst, 16);
                                432                 :                : }
                                433                 :                : 
                                434                 :                : #define NS_IN6ADDRSZ 16
                                435                 :                : #define NS_INT16SZ 2
                                436                 :                : #define NS_INADDRSZ 4
                                437                 :                : 
                                438                 :                : static int
 7559                           439                 :            448 : inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size)
                                440                 :                : {
                                441                 :                :     static const char xdigits_l[] = "0123456789abcdef",
                                442                 :                :                 xdigits_u[] = "0123456789ABCDEF";
                                443                 :                :     u_char      tmp[NS_IN6ADDRSZ],
                                444                 :                :                *tp,
                                445                 :                :                *endp,
                                446                 :                :                *colonp;
                                447                 :                :     const char *xdigits,
                                448                 :                :                *curtok;
                                449                 :                :     int         ch,
                                450                 :                :                 saw_xdigit;
                                451                 :                :     u_int       val;
                                452                 :                :     int         digits;
                                453                 :                :     int         bits;
                                454                 :                : 
 7600                           455         [ -  + ]:            448 :     if (size < NS_IN6ADDRSZ)
 7600 bruce@momjian.us          456                 :UBC           0 :         goto emsgsize;
                                457                 :                : 
 7600 bruce@momjian.us          458                 :CBC         448 :     memset((tp = tmp), '\0', NS_IN6ADDRSZ);
                                459                 :            448 :     endp = tp + NS_IN6ADDRSZ;
                                460                 :            448 :     colonp = NULL;
                                461                 :                :     /* Leading :: requires some special handling. */
                                462         [ +  + ]:            448 :     if (*src == ':')
                                463         [ -  + ]:             24 :         if (*++src != ':')
 7600 bruce@momjian.us          464                 :UBC           0 :             goto enoent;
 7600 bruce@momjian.us          465                 :CBC         448 :     curtok = src;
                                466                 :            448 :     saw_xdigit = 0;
                                467                 :            448 :     val = 0;
                                468                 :            448 :     digits = 0;
                                469                 :            448 :     bits = -1;
 7559                           470         [ +  + ]:           9900 :     while ((ch = *src++) != '\0')
                                471                 :                :     {
                                472                 :                :         const char *pch;
                                473                 :                : 
 7600                           474         [ +  + ]:           9696 :         if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
                                475                 :           2276 :             pch = strchr((xdigits = xdigits_u), ch);
 7559                           476         [ +  + ]:           9696 :         if (pch != NULL)
                                477                 :                :         {
 7600                           478                 :           7420 :             val <<= 4;
                                479                 :           7420 :             val |= (pch - xdigits);
                                480         [ -  + ]:           7420 :             if (++digits > 4)
 7600 bruce@momjian.us          481                 :UBC           0 :                 goto enoent;
 7600 bruce@momjian.us          482                 :CBC        7420 :             saw_xdigit = 1;
                                483                 :           7420 :             continue;
                                484                 :                :         }
 7559                           485         [ +  + ]:           2276 :         if (ch == ':')
                                486                 :                :         {
 7600                           487                 :           2035 :             curtok = src;
 7559                           488         [ +  + ]:           2035 :             if (!saw_xdigit)
                                489                 :                :             {
 7600                           490         [ +  + ]:            360 :                 if (colonp)
                                491                 :              3 :                     goto enoent;
                                492                 :            357 :                 colonp = tp;
                                493                 :            357 :                 continue;
                                494                 :                :             }
 7559                           495         [ -  + ]:           1675 :             else if (*src == '\0')
 7600 bruce@momjian.us          496                 :UBC           0 :                 goto enoent;
 7600 bruce@momjian.us          497         [ -  + ]:CBC        1675 :             if (tp + NS_INT16SZ > endp)
 2859 tgl@sss.pgh.pa.us         498                 :UBC           0 :                 goto enoent;
 7600 bruce@momjian.us          499                 :CBC        1675 :             *tp++ = (u_char) (val >> 8) & 0xff;
                                500                 :           1675 :             *tp++ = (u_char) val & 0xff;
                                501                 :           1675 :             saw_xdigit = 0;
                                502                 :           1675 :             digits = 0;
                                503                 :           1675 :             val = 0;
                                504                 :           1675 :             continue;
                                505                 :                :         }
                                506   [ +  +  +  -  :            250 :         if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
                                              +  - ]
 7559                           507                 :              9 :             getv4(curtok, tp, &bits) > 0)
                                508                 :                :         {
 7600                           509                 :              9 :             tp += NS_INADDRSZ;
                                510                 :              9 :             saw_xdigit = 0;
 7559                           511                 :              9 :             break;              /* '\0' was seen by inet_pton4(). */
                                512                 :                :         }
 7600                           513   [ +  -  +  - ]:            232 :         if (ch == '/' && getbits(src, &bits) > 0)
                                514                 :            232 :             break;
 7600 bruce@momjian.us          515                 :UBC           0 :         goto enoent;
                                516                 :                :     }
 7559 bruce@momjian.us          517         [ +  + ]:CBC         445 :     if (saw_xdigit)
                                518                 :                :     {
 7600                           519         [ -  + ]:            376 :         if (tp + NS_INT16SZ > endp)
 7600 bruce@momjian.us          520                 :UBC           0 :             goto enoent;
 7600 bruce@momjian.us          521                 :CBC         376 :         *tp++ = (u_char) (val >> 8) & 0xff;
                                522                 :            376 :         *tp++ = (u_char) val & 0xff;
                                523                 :                :     }
                                524         [ +  + ]:            445 :     if (bits == -1)
                                525                 :            207 :         bits = 128;
                                526                 :                : 
 7559                           527                 :            445 :     endp = tmp + 16;
                                528                 :                : 
                                529         [ +  + ]:            445 :     if (colonp != NULL)
                                530                 :                :     {
                                531                 :                :         /*
                                532                 :                :          * Since some memmove()'s erroneously fail to handle overlapping
                                533                 :                :          * regions, we'll do the shift by hand.
                                534                 :                :          */
                                535                 :            354 :         const int   n = tp - colonp;
                                536                 :                :         int         i;
                                537                 :                : 
 7600                           538         [ -  + ]:            354 :         if (tp == endp)
 7600 bruce@momjian.us          539                 :UBC           0 :             goto enoent;
 7559 bruce@momjian.us          540         [ +  + ]:CBC        2256 :         for (i = 1; i <= n; i++)
                                541                 :                :         {
                                542                 :           1902 :             endp[-i] = colonp[n - i];
 7600                           543                 :           1902 :             colonp[n - i] = 0;
                                544                 :                :         }
                                545                 :            354 :         tp = endp;
                                546                 :                :     }
                                547         [ -  + ]:            445 :     if (tp != endp)
 7600 bruce@momjian.us          548                 :UBC           0 :         goto enoent;
                                549                 :                : 
                                550                 :                :     /*
                                551                 :                :      * Copy out the result.
                                552                 :                :      */
 7600 bruce@momjian.us          553                 :CBC         445 :     memcpy(dst, tmp, NS_IN6ADDRSZ);
                                554                 :                : 
 2432 peter_e@gmx.net           555                 :            445 :     return bits;
                                556                 :                : 
 7559 bruce@momjian.us          557                 :              3 : enoent:
 7600                           558                 :              3 :     errno = ENOENT;
 2432 peter_e@gmx.net           559                 :              3 :     return -1;
                                560                 :                : 
 7559 bruce@momjian.us          561                 :UBC           0 : emsgsize:
 7600                           562                 :              0 :     errno = EMSGSIZE;
 2432 peter_e@gmx.net           563                 :              0 :     return -1;
                                564                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622