(linenum→info "unix/slp.c:2238")

glibc/2.7/resolv/inet_pton.c

    1: /*
    2:  * Copyright (c) 1996,1999 by Internet Software Consortium.
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
    9:  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
   10:  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
   11:  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
   12:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
   13:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
   14:  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   15:  * SOFTWARE.
   16:  */
   17: 
   18: #if defined(LIBC_SCCS) && !defined(lint)
   19: static const char rcsid[] = "$BINDId: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $";
   20: #endif /* LIBC_SCCS and not lint */
   21: 
   22: #include <sys/param.h>
   23: #include <sys/types.h>
   24: #include <sys/socket.h>
   25: #include <netinet/in.h>
   26: #include <arpa/inet.h>
   27: #include <arpa/nameser.h>
   28: #include <ctype.h>
   29: #include <string.h>
   30: #include <errno.h>
   31: 
   32: /*
   33:  * WARNING: Don't even consider trying to compile this on a system where
   34:  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
   35:  */
   36: 
   37: static int inet_pton4 (const char *src, u_char *dst) internal_function;
   38: static int inet_pton6 (const char *src, u_char *dst) internal_function;
   39: 
   40: /* int
   41:  * inet_pton(af, src, dst)
   42:  *      convert from presentation format (which usually means ASCII printable)
   43:  *      to network format (which is usually some kind of binary format).
   44:  * return:
   45:  *      1 if the address was valid for the specified address family
   46:  *      0 if the address wasn't valid (`dst' is untouched in this case)
   47:  *      -1 if some other error occurred (`dst' is untouched in this case, too)
   48:  * author:
   49:  *      Paul Vixie, 1996.
   50:  */
   51: int
   52: inet_pton(af, src, dst)
   53:         int af;
   54:         const char *src;
   55:         void *dst;
   56: {
   57:         switch (af) {
   58:         case AF_INET:
   59:                 return (inet_pton4(src, dst));
   60:         case AF_INET6:
   61:                 return (inet_pton6(src, dst));
   62:         default:
   63:                 __set_errno (EAFNOSUPPORT);
   64:                 return (-1);
   65:         }
   66:         /* NOTREACHED */
   67: }
   68: libc_hidden_def (inet_pton)
   69: 
   70: /* int
   71:  * inet_pton4(src, dst)
   72:  *      like inet_aton() but without all the hexadecimal, octal (with the
   73:  *      exception of 0) and shorthand.
   74:  * return:
   75:  *      1 if `src' is a valid dotted quad, else 0.
   76:  * notice:
   77:  *      does not touch `dst' unless it's returning 1.
   78:  * author:
   79:  *      Paul Vixie, 1996.
   80:  */
   81: static int
   82: internal_function
   83: inet_pton4(src, dst)
   84:         const char *src;
   85:         u_char *dst;
   86: {
   87:         int saw_digit, octets, ch;
   88:         u_char tmp[NS_INADDRSZ], *tp;
   89: 
   90:         saw_digit = 0;
   91:         octets = 0;
   92:         *(tp = tmp) = 0;
   93:         while ((ch = *src++) != '\0') {
   94: 
   95:                 if (ch >= '0' && ch <= '9') {
   96:                         u_int new = *tp * 10 + (ch - '0');
   97: 
   98:                         if (saw_digit && *tp == 0)
   99:                                 return (0);
  100:                         if (new > 255)
  101:                                 return (0);
  102:                         *tp = new;
  103:                         if (! saw_digit) {
  104:                                 if (++octets > 4)
  105:                                         return (0);
  106:                                 saw_digit = 1;
  107:                         }
  108:                 } else if (ch == '.' && saw_digit) {
  109:                         if (octets == 4)
  110:                                 return (0);
  111:                         *++tp = 0;
  112:                         saw_digit = 0;
  113:                 } else
  114:                         return (0);
  115:         }
  116:         if (octets < 4)
  117:                 return (0);
  118:         memcpy(dst, tmp, NS_INADDRSZ);
  119:         return (1);
  120: }
  121: 
  122: /* int
  123:  * inet_pton6(src, dst)
  124:  *      convert presentation level address to network order binary form.
  125:  * return:
  126:  *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
  127:  * notice:
  128:  *      (1) does not touch `dst' unless it's returning 1.
  129:  *      (2) :: in a full address is silently ignored.
  130:  * credit:
  131:  *      inspired by Mark Andrews.
  132:  * author:
  133:  *      Paul Vixie, 1996.
  134:  */
  135: static int
  136: internal_function
  137: inet_pton6(src, dst)
  138:         const char *src;
  139:         u_char *dst;
  140: {
  141:         static const char xdigits[] = "0123456789abcdef";
  142:         u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
  143:         const char *curtok;
  144:         int ch, saw_xdigit;
  145:         u_int val;
  146: 
  147:         tp = memset(tmp, '\0', NS_IN6ADDRSZ);
  148:         endp = tp + NS_IN6ADDRSZ;
  149:         colonp = NULL;
  150:         /* Leading :: requires some special handling. */
  151:         if (*src == ':')
  152:                 if (*++src != ':')
  153:                         return (0);
  154:         curtok = src;
  155:         saw_xdigit = 0;
  156:         val = 0;
  157:         while ((ch = tolower (*src++)) != '\0') {
  158:                 const char *pch;
  159: 
  160:                 pch = strchr(xdigits, ch);
  161:                 if (pch != NULL) {
  162:                         val <<= 4;
  163:                         val |= (pch - xdigits);
  164:                         if (val > 0xffff)
  165:                                 return (0);
  166:                         saw_xdigit = 1;
  167:                         continue;
  168:                 }
  169:                 if (ch == ':') {
  170:                         curtok = src;
  171:                         if (!saw_xdigit) {
  172:                                 if (colonp)
  173:                                         return (0);
  174:                                 colonp = tp;
  175:                                 continue;
  176:                         } else if (*src == '\0') {
  177:                                 return (0);
  178:                         }
  179:                         if (tp + NS_INT16SZ > endp)
  180:                                 return (0);
  181:                         *tp++ = (u_char) (val >> 8) & 0xff;
  182:                         *tp++ = (u_char) val & 0xff;
  183:                         saw_xdigit = 0;
  184:                         val = 0;
  185:                         continue;
  186:                 }
  187:                 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
  188:                     inet_pton4(curtok, tp) > 0) {
  189:                         tp += NS_INADDRSZ;
  190:                         saw_xdigit = 0;
  191:                         break;       /* '\0' was seen by inet_pton4(). */
  192:                 }
  193:                 return (0);
  194:         }
  195:         if (saw_xdigit) {
  196:                 if (tp + NS_INT16SZ > endp)
  197:                         return (0);
  198:                 *tp++ = (u_char) (val >> 8) & 0xff;
  199:                 *tp++ = (u_char) val & 0xff;
  200:         }
  201:         if (colonp != NULL) {
  202:                 /*
  203:                  * Since some memmove()'s erroneously fail to handle
  204:                  * overlapping regions, we'll do the shift by hand.
  205:                  */
  206:                 const int n = tp - colonp;
  207:                 int i;
  208: 
  209:                 if (tp == endp)
  210:                         return (0);
  211:                 for (i = 1; i <= n; i++) {
  212:                         endp[- i] = colonp[n - i];
  213:                         colonp[n - i] = 0;
  214:                 }
  215:                 tp = endp;
  216:         }
  217:         if (tp != endp)
  218:                 return (0);
  219:         memcpy(dst, tmp, NS_IN6ADDRSZ);
  220:         return (1);
  221: }
Syntax (Markdown)