Annotation of embedaddon/sudo/compat/inet_pton.c, revision 1.1
1.1 ! misho 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 <config.h>
! 20:
! 21: #if !defined(HAVE_INET_PTON)
! 22:
! 23: #include <sys/param.h>
! 24: #include <sys/types.h>
! 25: #include <sys/socket.h>
! 26: #include <netinet/in.h>
! 27: #include <arpa/inet.h>
! 28: #include <arpa/nameser.h>
! 29: #ifdef HAVE_STRING_H
! 30: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
! 31: # include <memory.h>
! 32: # endif
! 33: # include <string.h>
! 34: #endif /* HAVE_STRING_H */
! 35: #ifdef HAVE_STRINGS_H
! 36: # include <strings.h>
! 37: #endif /* HAVE_STRINGS_H */
! 38: #include <errno.h>
! 39:
! 40: #include "missing.h"
! 41:
! 42: #ifndef EAFNOSUPPORT
! 43: # define EAFNOSUPPORT EINVAL
! 44: #endif
! 45:
! 46: #ifndef NS_INADDRSZ
! 47: # ifdef INADDRSZ
! 48: # define NS_INADDRSZ INADDRSZ
! 49: # else
! 50: # define NS_INADDRSZ 4
! 51: # endif
! 52: #endif
! 53: #ifndef NS_IN6ADDRSZ
! 54: # ifdef IN6ADDRSZ
! 55: # define NS_IN6ADDRSZ IN6ADDRSZ
! 56: # else
! 57: # define NS_IN6ADDRSZ 16
! 58: # endif
! 59: #endif
! 60: #ifndef NS_INT16SZ
! 61: # ifdef INT16SZ
! 62: # define NS_INT16SZ INT16SZ
! 63: # else
! 64: # define NS_INT16SZ 2
! 65: # endif
! 66: #endif
! 67:
! 68: /*
! 69: * WARNING: Don't even consider trying to compile this on a system where
! 70: * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
! 71: */
! 72:
! 73: /* int
! 74: * inet_pton4(src, dst)
! 75: * like inet_aton() but without all the hexadecimal and shorthand.
! 76: * return:
! 77: * 1 if `src' is a valid dotted quad, else 0.
! 78: * notice:
! 79: * does not touch `dst' unless it's returning 1.
! 80: * author:
! 81: * Paul Vixie, 1996.
! 82: */
! 83: static int
! 84: inet_pton4(const char *src, u_char *dst)
! 85: {
! 86: const char digits[] = "0123456789";
! 87: int saw_digit, octets, ch;
! 88: u_char tmp[NS_INADDRSZ], *tp;
! 89:
! 90: saw_digit = 0;
! 91: octets = 0;
! 92: /* cppcheck-suppress uninitvar */
! 93: *(tp = tmp) = '\0';
! 94: while ((ch = (unsigned char)*src++) != '\0') {
! 95: const char *pch;
! 96:
! 97: if ((pch = strchr(digits, ch)) != NULL) {
! 98: u_int new = *tp * 10 + (pch - digits);
! 99:
! 100: if (new > 255)
! 101: return (0);
! 102: if (!saw_digit) {
! 103: if (++octets > 4)
! 104: return (0);
! 105: saw_digit = 1;
! 106: }
! 107: *tp = new;
! 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:
! 119: memcpy(dst, tmp, NS_INADDRSZ);
! 120: return (1);
! 121: }
! 122:
! 123: #ifdef HAVE_STRUCT_IN6_ADDR
! 124: /* int
! 125: * inet_pton6(src, dst)
! 126: * convert presentation level address to network order binary form.
! 127: * return:
! 128: * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
! 129: * notice:
! 130: * does not touch `dst' unless it's returning 1.
! 131: * credit:
! 132: * inspired by Mark Andrews.
! 133: * author:
! 134: * Paul Vixie, 1996.
! 135: */
! 136: static int
! 137: inet_pton6(const char *src, u_char *dst)
! 138: {
! 139: const char xdigits_l[] = "0123456789abcdef",
! 140: xdigits_u[] = "0123456789ABCDEF";
! 141: u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
! 142: const char *xdigits, *curtok;
! 143: int ch, saw_xdigit, count_xdigit;
! 144: u_int val;
! 145:
! 146: /* cppcheck-suppress uninitvar */
! 147: memset((tp = 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 = count_xdigit = 0;
! 156: val = 0;
! 157: while ((ch = (unsigned char)*src++) != '\0') {
! 158: const char *pch;
! 159:
! 160: if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
! 161: pch = strchr((xdigits = xdigits_u), ch);
! 162: if (pch != NULL) {
! 163: if (count_xdigit >= 4)
! 164: return (0);
! 165: val <<= 4;
! 166: val |= (pch - xdigits);
! 167: if (val > 0xffff)
! 168: return (0);
! 169: saw_xdigit = 1;
! 170: count_xdigit++;
! 171: continue;
! 172: }
! 173: if (ch == ':') {
! 174: curtok = src;
! 175: if (!saw_xdigit) {
! 176: if (colonp)
! 177: return (0);
! 178: colonp = tp;
! 179: continue;
! 180: } else if (*src == '\0') {
! 181: return (0);
! 182: }
! 183: if (tp + NS_INT16SZ > endp)
! 184: return (0);
! 185: *tp++ = (u_char) (val >> 8) & 0xff;
! 186: *tp++ = (u_char) val & 0xff;
! 187: saw_xdigit = 0;
! 188: count_xdigit = 0;
! 189: val = 0;
! 190: continue;
! 191: }
! 192: if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
! 193: inet_pton4(curtok, tp) > 0) {
! 194: tp += NS_INADDRSZ;
! 195: saw_xdigit = 0;
! 196: count_xdigit = 0;
! 197: break; /* '\0' was seen by inet_pton4(). */
! 198: }
! 199: return (0);
! 200: }
! 201: if (saw_xdigit) {
! 202: if (tp + NS_INT16SZ > endp)
! 203: return (0);
! 204: *tp++ = (u_char) (val >> 8) & 0xff;
! 205: *tp++ = (u_char) val & 0xff;
! 206: }
! 207: if (colonp != NULL) {
! 208: /*
! 209: * Since some memmove()'s erroneously fail to handle
! 210: * overlapping regions, we'll do the shift by hand.
! 211: */
! 212: const long n = tp - colonp;
! 213: long i;
! 214:
! 215: if (tp == endp)
! 216: return (0);
! 217: for (i = 1; i <= n; i++) {
! 218: endp[- i] = colonp[n - i];
! 219: colonp[n - i] = 0;
! 220: }
! 221: tp = endp;
! 222: }
! 223: if (tp != endp)
! 224: return (0);
! 225: memcpy(dst, tmp, NS_IN6ADDRSZ);
! 226: return (1);
! 227: }
! 228: #endif /* HAVE_STRUCT_IN6_ADDR */
! 229:
! 230: /* int
! 231: * inet_pton(af, src, dst)
! 232: * convert from presentation format (which usually means ASCII printable)
! 233: * to network format (which is usually some kind of binary format).
! 234: * return:
! 235: * 1 if the address was valid for the specified address family
! 236: * 0 if the address wasn't valid (`dst' is untouched in this case)
! 237: * -1 if some other error occurred (`dst' is untouched in this case, too)
! 238: * author:
! 239: * Paul Vixie, 1996.
! 240: */
! 241: int
! 242: inet_pton(int af, const char *src, void *dst)
! 243: {
! 244: switch (af) {
! 245: case AF_INET:
! 246: return (inet_pton4(src, dst));
! 247: #ifdef HAVE_STRUCT_IN6_ADDR
! 248: case AF_INET6:
! 249: return (inet_pton6(src, dst));
! 250: #endif /* HAVE_STRUCT_IN6_ADDR */
! 251: default:
! 252: errno = EAFNOSUPPORT;
! 253: return (-1);
! 254: }
! 255: /* NOTREACHED */
! 256: }
! 257:
! 258: #endif /* HAVE_INET_PTON */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>