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