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 HEAD vs 15 Lines: 73.5 % 275 202 73 202
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 7 7 7
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 73.5 % 275 202 73 202
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 7 7 7

 Age         Owner                  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
 1330 tgl                        62 CBC        2348 : pg_inet_net_pton(int af, const char *src, void *dst, size_t size)
                                 63                 : {
 8954 bruce                      64            2348 :     switch (af)
                                 65                 :     {
 7229                            66            1900 :         case PGSQL_AF_INET:
                                 67                 :             return size == -1 ?
 7836                            68            2455 :                 inet_net_pton_ipv4(src, dst) :
                                 69             555 :                 inet_cidr_pton_ipv4(src, dst, size);
 7229                            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);
 8954 bruce                      74 UBC           0 :         default:
                                 75               0 :             errno = EAFNOSUPPORT;
 2061 peter_e                    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
 8935 bruce                      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,
 6641 tgl                       103             555 :                 tmp = 0,
                                104                 :                 dirty,
                                105                 :                 bits;
 8954 bruce                     106             555 :     const u_char *odst = dst;
                                107                 : 
                                108             555 :     ch = *src++;
                                109             555 :     if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
 8162 tgl                       110 UBC           0 :         && isxdigit((unsigned char) src[1]))
                                111                 :     {
                                112                 :         /* Hexadecimal: Eat nybble string. */
 6641                           113               0 :         if (size <= 0U)
 8954 bruce                     114               0 :             goto emsgsize;
 8945                           115               0 :         dirty = 0;
 8720                           116               0 :         src++;                  /* skip x or X. */
 8162 tgl                       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);
 8954 bruce                     121               0 :             n = strchr(xdigits, ch) - xdigits;
                                122               0 :             assert(n >= 0 && n <= 15);
 8940                           123               0 :             if (dirty == 0)
                                124               0 :                 tmp = n;
                                125                 :             else
                                126               0 :                 tmp = (tmp << 4) | n;
 8720                           127               0 :             if (++dirty == 2)
                                128                 :             {
 6641 tgl                       129               0 :                 if (size-- <= 0U)
 8945 bruce                     130               0 :                     goto emsgsize;
                                131               0 :                 *dst++ = (u_char) tmp;
 8940                           132               0 :                 dirty = 0;
                                133                 :             }
                                134                 :         }
 8720                           135               0 :         if (dirty)
                                136                 :         {                       /* Odd trailing nybble? */
 6641 tgl                       137               0 :             if (size-- <= 0U)
 8954 bruce                     138               0 :                 goto emsgsize;
 8940                           139               0 :             *dst++ = (u_char) (tmp << 4);
                                140                 :         }
                                141                 :     }
 8162 tgl                       142 CBC         555 :     else if (isdigit((unsigned char) ch))
                                143                 :     {
                                144                 :         /* Decimal: eat dotted digit string. */
                                145                 :         for (;;)
                                146                 :         {
 8954 bruce                     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' &&
 8162 tgl                       157            3234 :                      isdigit((unsigned char) ch));
 6641                           158            1809 :             if (size-- <= 0U)
 8954 bruce                     159 UBC           0 :                 goto emsgsize;
 8954 bruce                     160 CBC        1809 :             *dst++ = (u_char) tmp;
                                161            1809 :             if (ch == '\0' || ch == '/')
                                162                 :                 break;
                                163            1260 :             if (ch != '.')
 8954 bruce                     164 UBC           0 :                 goto enoent;
 8954 bruce                     165 CBC        1260 :             ch = *src++;
 8162 tgl                       166            1260 :             if (!isdigit((unsigned char) ch))
 8954 bruce                     167 UBC           0 :                 goto enoent;
                                168                 :         }
                                169                 :     }
                                170                 :     else
                                171               0 :         goto enoent;
                                172                 : 
 8954 bruce                     173 CBC         549 :     bits = -1;
 8162 tgl                       174             549 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                175                 :     {
                                176                 :         /* CIDR width specifier.  Nothing can follow it. */
 8954 bruce                     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;
 8162 tgl                       185             523 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 8954 bruce                     186             299 :         if (ch != '\0')
 8954 bruce                     187 UBC           0 :             goto enoent;
 8954 bruce                     188 CBC         299 :         if (bits > 32)
 8954 bruce                     189 UBC           0 :             goto emsgsize;
                                190                 :     }
                                191                 : 
                                192                 :     /* Fiery death and destruction unless we prefetched EOS. */
 8954 bruce                     193 CBC         549 :     if (ch != '\0')
 8954 bruce                     194 UBC           0 :         goto enoent;
                                195                 : 
                                196                 :     /* If nothing was written to the destination, we found no address. */
 8954 bruce                     197 CBC         549 :     if (dst == odst)
 8954 bruce                     198 UBC           0 :         goto enoent;
                                199                 :     /* If no CIDR spec was given, infer width from net class. */
 8954 bruce                     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 */
 6641 tgl                       205 UBC           0 :             bits = 8;
 8954 bruce                     206 CBC         154 :         else if (*odst >= 192)   /* Class C */
                                207              15 :             bits = 24;
                                208             139 :         else if (*odst >= 128)   /* Class B */
 8954 bruce                     209 UBC           0 :             bits = 16;
                                210                 :         else
                                211                 :             /* Class A */
 8954 bruce                     212 CBC         139 :             bits = 8;
                                213                 :         /* If imputed mask is narrower than specified octets, widen. */
 6641 tgl                       214             250 :         if (bits < ((dst - odst) * 8))
 8954 bruce                     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                 :          */
 6641 tgl                       221             250 :         if (bits == 8 && *odst == 224)
 6641 tgl                       222 UBC           0 :             bits = 4;
                                223                 :     }
                                224                 :     /* Extend network to cover the actual mask. */
 8954 bruce                     225 CBC         573 :     while (bits > ((dst - odst) * 8))
                                226                 :     {
 6641 tgl                       227              24 :         if (size-- <= 0U)
 8954 bruce                     228 UBC           0 :             goto emsgsize;
 8954 bruce                     229 CBC          24 :         *dst++ = '\0';
                                230                 :     }
 2061 peter_e                   231             549 :     return bits;
                                232                 : 
 8954 bruce                     233               6 : enoent:
                                234               6 :     errno = ENOENT;
 2061 peter_e                   235               6 :     return -1;
                                236                 : 
 8954 bruce                     237 UBC           0 : emsgsize:
                                238               0 :     errno = EMSGSIZE;
 2061 peter_e                   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
 8935 bruce                     260 CBC        1345 : inet_net_pton_ipv4(const char *src, u_char *dst)
                                261                 : {
                                262                 :     static const char digits[] = "0123456789";
                                263            1345 :     const u_char *odst = dst;
                                264                 :     int         n,
                                265                 :                 ch,
                                266                 :                 tmp,
                                267                 :                 bits;
 8720                           268            1345 :     size_t      size = 4;
                                269                 : 
                                270                 :     /* Get the mantissa. */
 8162 tgl                       271            5182 :     while (ch = *src++, isdigit((unsigned char) ch))
                                272                 :     {
 8935 bruce                     273            5182 :         tmp = 0;
                                274                 :         do
                                275                 :         {
                                276           11731 :             n = strchr(digits, ch) - digits;
                                277           11731 :             assert(n >= 0 && n <= 9);
                                278           11731 :             tmp *= 10;
                                279           11731 :             tmp += n;
                                280           11731 :             if (tmp > 255)
                                281               6 :                 goto enoent;
 8162 tgl                       282           11725 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 8935 bruce                     283            5176 :         if (size-- == 0)
 8935 bruce                     284 UBC           0 :             goto emsgsize;
 8935 bruce                     285 CBC        5176 :         *dst++ = (u_char) tmp;
                                286            5176 :         if (ch == '\0' || ch == '/')
                                287                 :             break;
                                288            3837 :         if (ch != '.')
 8935 bruce                     289 UBC           0 :             goto enoent;
                                290                 :     }
                                291                 : 
                                292                 :     /* Get the prefix length if any. */
 8935 bruce                     293 CBC        1339 :     bits = -1;
 8162 tgl                       294            1339 :     if (ch == '/' && isdigit((unsigned char) src[0]) && dst > odst)
                                295                 :     {
                                296                 :         /* CIDR width specifier.  Nothing can follow it. */
 8720 bruce                     297             469 :         ch = *src++;            /* Skip over the /. */
 8935                           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;
 8162 tgl                       305             750 :         } while ((ch = *src++) != '\0' && isdigit((unsigned char) ch));
 8935 bruce                     306             469 :         if (ch != '\0')
 8935 bruce                     307 UBC           0 :             goto enoent;
 8935 bruce                     308 CBC         469 :         if (bits > 32)
 8935 bruce                     309 UBC           0 :             goto emsgsize;
                                310                 :     }
                                311                 : 
                                312                 :     /* Fiery death and destruction unless we prefetched EOS. */
 8935 bruce                     313 CBC        1339 :     if (ch != '\0')
 8935 bruce                     314 UBC           0 :         goto enoent;
                                315                 : 
                                316                 :     /* Prefix length can default to /32 only if all four octets spec'd. */
 8935 bruce                     317 CBC        1339 :     if (bits == -1)
                                318                 :     {
                                319             870 :         if (dst - odst == 4)
                                320             870 :             bits = 32;
                                321                 :         else
 8935 bruce                     322 UBC           0 :             goto enoent;
                                323                 :     }
                                324                 : 
                                325                 :     /* If nothing was written to the destination, we found no address. */
 8935 bruce                     326 CBC        1339 :     if (dst == odst)
 8935 bruce                     327 UBC           0 :         goto enoent;
                                328                 : 
                                329                 :     /* If prefix length overspecifies mantissa, life is bad. */
 8935 bruce                     330 CBC        1339 :     if ((bits / 8) > (dst - odst))
 8935 bruce                     331 UBC           0 :         goto enoent;
                                332                 : 
                                333                 :     /* Extend address to four octets. */
 8935 bruce                     334 CBC        1519 :     while (size-- > 0)
                                335             180 :         *dst++ = 0;
                                336                 : 
                                337            1339 :     return bits;
                                338                 : 
 8720                           339               6 : enoent:
 8935                           340               6 :     errno = ENOENT;
 2061 peter_e                   341               6 :     return -1;
                                342                 : 
 8720 bruce                     343 UBC           0 : emsgsize:
 8935                           344               0 :     errno = EMSGSIZE;
 2061 peter_e                   345               0 :     return -1;
                                346                 : }
                                347                 : 
                                348                 : static int
 7188 bruce                     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                 : 
 7229                           356             238 :     val = 0;
                                357             238 :     n = 0;
 7188                           358             712 :     while ((ch = *src++) != '\0')
                                359                 :     {
                                360                 :         const char *pch;
                                361                 : 
 7229                           362             474 :         pch = strchr(digits, ch);
 7188                           363             474 :         if (pch != NULL)
                                364                 :         {
 7229                           365             474 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2061 peter_e                   366 UBC           0 :                 return 0;
 7229 bruce                     367 CBC         474 :             val *= 10;
                                368             474 :             val += (pch - digits);
 7188                           369             474 :             if (val > 128)       /* range */
 2061 peter_e                   370 UBC           0 :                 return 0;
 7229 bruce                     371 CBC         474 :             continue;
                                372                 :         }
 2061 peter_e                   373 UBC           0 :         return 0;
                                374                 :     }
 7229 bruce                     375 CBC         238 :     if (n == 0)
 2061 peter_e                   376 UBC           0 :         return 0;
 7229 bruce                     377 CBC         238 :     *bitsp = val;
 2061 peter_e                   378             238 :     return 1;
                                379                 : }
                                380                 : 
                                381                 : static int
 7188 bruce                     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                 : 
 7229                           390               9 :     val = 0;
                                391               9 :     n = 0;
 7188                           392              72 :     while ((ch = *src++) != '\0')
                                393                 :     {
                                394                 :         const char *pch;
                                395                 : 
 7229                           396              69 :         pch = strchr(digits, ch);
 7188                           397              69 :         if (pch != NULL)
                                398                 :         {
 7229                           399              36 :             if (n++ != 0 && val == 0)   /* no leading zeros */
 2061 peter_e                   400 UBC           0 :                 return 0;
 7229 bruce                     401 CBC          36 :             val *= 10;
                                402              36 :             val += (pch - digits);
 7188                           403              36 :             if (val > 255)       /* range */
 2061 peter_e                   404 UBC           0 :                 return 0;
 7229 bruce                     405 CBC          36 :             continue;
                                406                 :         }
 7188                           407              33 :         if (ch == '.' || ch == '/')
                                408                 :         {
                                409              33 :             if (dst - odst > 3) /* too many octets? */
 2061 peter_e                   410 UBC           0 :                 return 0;
 7229 bruce                     411 CBC          33 :             *dst++ = val;
                                412              33 :             if (ch == '/')
 2061 peter_e                   413               6 :                 return getbits(src, bitsp);
 7229 bruce                     414              27 :             val = 0;
                                415              27 :             n = 0;
                                416              27 :             continue;
                                417                 :         }
 2061 peter_e                   418 UBC           0 :         return 0;
                                419                 :     }
 7229 bruce                     420 CBC           3 :     if (n == 0)
 2061 peter_e                   421 UBC           0 :         return 0;
 7188 bruce                     422 CBC           3 :     if (dst - odst > 3)          /* too many octets? */
 2061 peter_e                   423 UBC           0 :         return 0;
 7229 bruce                     424 CBC           3 :     *dst++ = val;
 2061 peter_e                   425               3 :     return 1;
                                426                 : }
                                427                 : 
                                428                 : static int
 7229 bruce                     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
 7188                           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                 : 
 7229                           455             448 :     if (size < NS_IN6ADDRSZ)
 7229 bruce                     456 UBC           0 :         goto emsgsize;
                                457                 : 
 7229 bruce                     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 != ':')
 7229 bruce                     464 UBC           0 :             goto enoent;
 7229 bruce                     465 CBC         448 :     curtok = src;
                                466             448 :     saw_xdigit = 0;
                                467             448 :     val = 0;
                                468             448 :     digits = 0;
                                469             448 :     bits = -1;
 7188                           470            9900 :     while ((ch = *src++) != '\0')
                                471                 :     {
                                472                 :         const char *pch;
                                473                 : 
 7229                           474            9696 :         if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
                                475            2276 :             pch = strchr((xdigits = xdigits_u), ch);
 7188                           476            9696 :         if (pch != NULL)
                                477                 :         {
 7229                           478            7420 :             val <<= 4;
                                479            7420 :             val |= (pch - xdigits);
                                480            7420 :             if (++digits > 4)
 7229 bruce                     481 UBC           0 :                 goto enoent;
 7229 bruce                     482 CBC        7420 :             saw_xdigit = 1;
                                483            7420 :             continue;
                                484                 :         }
 7188                           485            2276 :         if (ch == ':')
                                486                 :         {
 7229                           487            2035 :             curtok = src;
 7188                           488            2035 :             if (!saw_xdigit)
                                489                 :             {
 7229                           490             360 :                 if (colonp)
                                491               3 :                     goto enoent;
                                492             357 :                 colonp = tp;
                                493             357 :                 continue;
                                494                 :             }
 7188                           495            1675 :             else if (*src == '\0')
 7229 bruce                     496 UBC           0 :                 goto enoent;
 7229 bruce                     497 CBC        1675 :             if (tp + NS_INT16SZ > endp)
 2488 tgl                       498 UBC           0 :                 goto enoent;
 7229 bruce                     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) &&
 7188                           507               9 :             getv4(curtok, tp, &bits) > 0)
                                508                 :         {
 7229                           509               9 :             tp += NS_INADDRSZ;
                                510               9 :             saw_xdigit = 0;
 7188                           511               9 :             break;              /* '\0' was seen by inet_pton4(). */
                                512                 :         }
 7229                           513             232 :         if (ch == '/' && getbits(src, &bits) > 0)
                                514             232 :             break;
 7229 bruce                     515 UBC           0 :         goto enoent;
                                516                 :     }
 7188 bruce                     517 CBC         445 :     if (saw_xdigit)
                                518                 :     {
 7229                           519             376 :         if (tp + NS_INT16SZ > endp)
 7229 bruce                     520 UBC           0 :             goto enoent;
 7229 bruce                     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                 : 
 7188                           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                 : 
 7229                           538             354 :         if (tp == endp)
 7229 bruce                     539 UBC           0 :             goto enoent;
 7188 bruce                     540 CBC        2256 :         for (i = 1; i <= n; i++)
                                541                 :         {
                                542            1902 :             endp[-i] = colonp[n - i];
 7229                           543            1902 :             colonp[n - i] = 0;
                                544                 :         }
                                545             354 :         tp = endp;
                                546                 :     }
                                547             445 :     if (tp != endp)
 7229 bruce                     548 UBC           0 :         goto enoent;
                                549                 : 
                                550                 :     /*
                                551                 :      * Copy out the result.
                                552                 :      */
 7229 bruce                     553 CBC         445 :     memcpy(dst, tmp, NS_IN6ADDRSZ);
                                554                 : 
 2061 peter_e                   555             445 :     return bits;
                                556                 : 
 7188 bruce                     557               3 : enoent:
 7229                           558               3 :     errno = ENOENT;
 2061 peter_e                   559               3 :     return -1;
                                560                 : 
 7188 bruce                     561 UBC           0 : emsgsize:
 7229                           562               0 :     errno = EMSGSIZE;
 2061 peter_e                   563               0 :     return -1;
                                564                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a