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