gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/arpa_inet/inet_pton.cbare sourcepermlink (0.02 seconds)

Search this content:

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