(root)/
glibc-2.38/
resolv/
ns_name_pton.c
       1  /* Convert a DNS domain name from presentation to wire format.
       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  
      18  #include <arpa/nameser.h>
      19  #include <errno.h>
      20  #include <shlib-compat.h>
      21  
      22  /* Converts an ASCII string into an encoded domain name as per
      23     RFC1035.  Returns -1 if it fails, 1 if string was fully qualified,
      24     0 is string was not fully qualified.  Enforces label and domain
      25     length limits.  */
      26  int
      27  ___ns_name_pton (const char *src, unsigned char *dst, size_t dstsiz)
      28  {
      29    unsigned char *label, *bp, *eom;
      30    int c, n, escaped;
      31  
      32    escaped = 0;
      33    bp = dst;
      34    eom = dst + dstsiz;
      35    label = bp++;
      36  
      37    while ((c = *src++) != 0)
      38      {
      39        if (escaped)
      40          {
      41            if ('0' <= c && c <= '9')
      42              {
      43                n = (c - '0') * 100;
      44                if ((c = *src++) == 0 || c < '0' || c > '9')
      45                  {
      46                    __set_errno (EMSGSIZE);
      47                    return -1;
      48                  }
      49                n += (c - '0') * 10;
      50                if ((c = *src++) == 0 || c < '0' || c > '9')
      51                  {
      52                    __set_errno (EMSGSIZE);
      53                    return -1;
      54                  }
      55                n += c - '0';
      56                if (n > 255)
      57                  {
      58                    __set_errno (EMSGSIZE);
      59                    return -1;
      60                  }
      61                c = n;
      62              }
      63            escaped = 0;
      64          }
      65        else if (c == '\\')
      66          {
      67            escaped = 1;
      68            continue;
      69          }
      70        else if (c == '.')
      71          {
      72            c = (bp - label - 1);
      73            if ((c & NS_CMPRSFLGS) != 0) /* Label too big.  */
      74              {
      75                __set_errno (EMSGSIZE);
      76                return -1;
      77              }
      78            if (label >= eom)
      79              {
      80                __set_errno (EMSGSIZE);
      81                return -1;
      82              }
      83            *label = c;
      84            /* Fully qualified ? */
      85            if (*src == '\0')
      86              {
      87                if (c != 0)
      88                  {
      89                    if (bp >= eom)
      90                      {
      91                        __set_errno (EMSGSIZE);
      92                        return -1;
      93                      }
      94                    *bp++ = '\0';
      95                  }
      96                if ((bp - dst) > MAXCDNAME)
      97                  {
      98                    __set_errno (EMSGSIZE);
      99                    return -1;
     100                  }
     101                return 1;
     102              }
     103            if (c == 0 || *src == '.')
     104              {
     105                __set_errno (EMSGSIZE);
     106                return -1;
     107              }
     108            label = bp++;
     109            continue;
     110          }
     111        if (bp >= eom)
     112          {
     113            __set_errno (EMSGSIZE);
     114            return -1;
     115          }
     116        *bp++ = (unsigned char) c;
     117      }
     118    if (escaped)                  /* Trailing backslash.  */
     119      {
     120        __set_errno (EMSGSIZE);
     121        return -1;
     122      }
     123    c = (bp - label - 1);
     124    if ((c & NS_CMPRSFLGS) != 0)  /* Label too big.  */
     125      {
     126        __set_errno (EMSGSIZE);
     127        return -1;
     128      }
     129    if (label >= eom)
     130      {
     131        __set_errno (EMSGSIZE);
     132        return -1;
     133      }
     134    *label = c;
     135    if (c != 0)
     136      {
     137        if (bp >= eom)
     138          {
     139            __set_errno (EMSGSIZE);
     140            return -1;
     141          }
     142        *bp++ = 0;
     143      }
     144    if ((bp - dst) > MAXCDNAME)   /* src too big.  */
     145      {
     146        __set_errno (EMSGSIZE);
     147        return -1;
     148      }
     149    return 0;
     150  }
     151  versioned_symbol (libc, ___ns_name_pton, ns_name_pton, GLIBC_2_34);
     152  versioned_symbol (libc, ___ns_name_pton, __ns_name_pton, GLIBC_PRIVATE);
     153  libc_hidden_ver (___ns_name_pton, __ns_name_pton)
     154  
     155  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_9, GLIBC_2_34)
     156  compat_symbol (libresolv, ___ns_name_pton, ns_name_pton, GLIBC_2_9);
     157  #endif