Annotation of embedaddon/rsync/lib/inet_pton.c, revision 1.1.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>