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