1 /* Copyright (c) 1996 by Internet Software Consortium. 2 * 3 * Permission to use, copy, modify, and distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 8 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 9 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 10 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 11 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 12 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 13 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 14 * SOFTWARE. 15 */ 16 17 /* 18 * Portions copyright (c) 1999, 2000 19 * Intel Corporation. 20 * All rights reserved. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 33 * 3. All advertising materials mentioning features or use of this software 34 * must display the following acknowledgement: 35 * 36 * This product includes software developed by Intel Corporation and 37 * its contributors. 38 * 39 * 4. Neither the name of Intel Corporation or its contributors may be 40 * used to endorse or promote products derived from this software 41 * without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 44 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 47 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 51 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 52 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 53 * THE POSSIBILITY OF SUCH DAMAGE. 54 * 55 */ 56 57 #if defined(LIBC_SCCS) && !defined(lint) 58 static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2003/11/19 01:51:30 kyu3 Exp $"; 59 #endif /* LIBC_SCCS and not lint */ 60 61 #include <sys/param.h> 62 #include <sys/types.h> 63 #include <sys/socket.h> 64 #include <netinet/in.h> 65 #include <arpa/inet.h> 66 #include <arpa/nameser.h> 67 #include <string.h> 68 #include <errno.h> 69 70 /* 71 * WARNING: Don't even consider trying to compile this on a system where 72 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. 73 */ 74 75 static int inet_pton4 (const char *src, u_char *dst); 76 static int inet_pton6 (const char *src, u_char *dst); 77 78 /* int 79 * inet_pton(af, src, dst) 80 * convert from presentation format (which usually means ASCII printable) 81 * to network format (which is usually some kind of binary format). 82 * return: 83 * 1 if the address was valid for the specified address family 84 * 0 if the address wasn't valid (`dst' is untouched in this case) 85 * -1 if some other error occurred (`dst' is untouched in this case, too) 86 * author: 87 * Paul Vixie, 1996. 88 */ 89 int 90 inet_pton( 91 int af, 92 const char *src, 93 void *dst 94 ) 95 { 96 switch (af) { 97 case AF_INET: 98 return (inet_pton4(src, dst)); 99 case AF_INET6: 100 return (inet_pton6(src, dst)); 101 default: 102 errno = EAFNOSUPPORT; 103 return (-1); 104 } 105 /* NOTREACHED */ 106 } 107 108 /* int 109 * inet_pton4(src, dst) 110 * like inet_aton() but without all the hexadecimal and shorthand. 111 * return: 112 * 1 if `src' is a valid dotted quad, else 0. 113 * notice: 114 * does not touch `dst' unless it's returning 1. 115 * author: 116 * Paul Vixie, 1996. 117 */ 118 static int 119 inet_pton4( 120 const char *src, 121 u_char *dst 122 ) 123 { 124 static const char digits[] = "0123456789"; 125 int saw_digit, octets, ch; 126 u_char tmp[NS_INADDRSZ], *tp; 127 128 saw_digit = 0; 129 octets = 0; 130 *(tp = tmp) = 0; 131 while ((ch = *src++) != '\0') { 132 const char *pch; 133 134 if ((pch = strchr(digits, ch)) != NULL) { 135 u_int new = *tp * 10 + (u_int)(pch - digits); 136 137 if (new > 255) 138 return (0); 139 *tp = (u_char)new; 140 if (! saw_digit) { 141 if (++octets > 4) 142 return (0); 143 saw_digit = 1; 144 } 145 } else if (ch == '.' && saw_digit) { 146 if (octets == 4) 147 return (0); 148 *++tp = 0; 149 saw_digit = 0; 150 } else 151 return (0); 152 } 153 if (octets < 4) 154 return (0); 155 156 memcpy(dst, tmp, NS_INADDRSZ); 157 return (1); 158 } 159 160 /* int 161 * inet_pton6(src, dst) 162 * convert presentation level address to network order binary form. 163 * return: 164 * 1 if `src' is a valid [RFC1884 2.2] address, else 0. 165 * notice: 166 * (1) does not touch `dst' unless it's returning 1. 167 * (2) :: in a full address is silently ignored. 168 * credit: 169 * inspired by Mark Andrews. 170 * author: 171 * Paul Vixie, 1996. 172 */ 173 static int 174 inet_pton6( 175 const char *src, 176 u_char *dst 177 ) 178 { 179 static const char xdigits_l[] = "0123456789abcdef", 180 xdigits_u[] = "0123456789ABCDEF"; 181 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; 182 const char *xdigits, *curtok; 183 int ch, saw_xdigit; 184 u_int val; 185 186 memset((tp = tmp), '\0', NS_IN6ADDRSZ); 187 endp = tp + NS_IN6ADDRSZ; 188 colonp = NULL; 189 /* Leading :: requires some special handling. */ 190 if (*src == ':') 191 if (*++src != ':') 192 return (0); 193 curtok = src; 194 saw_xdigit = 0; 195 val = 0; 196 while ((ch = *src++) != '\0') { 197 const char *pch; 198 199 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) 200 pch = strchr((xdigits = xdigits_u), ch); 201 if (pch != NULL) { 202 val <<= 4; 203 val |= (pch - xdigits); 204 if (val > 0xffff) 205 return (0); 206 saw_xdigit = 1; 207 continue; 208 } 209 if (ch == ':') { 210 curtok = src; 211 if (!saw_xdigit) { 212 if (colonp) 213 return (0); 214 colonp = tp; 215 continue; 216 } 217 if (tp + NS_INT16SZ > endp) 218 return (0); 219 *tp++ = (u_char) (val >> 8) & 0xff; 220 *tp++ = (u_char) val & 0xff; 221 saw_xdigit = 0; 222 val = 0; 223 continue; 224 } 225 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && 226 inet_pton4(curtok, tp) > 0) { 227 tp += NS_INADDRSZ; 228 saw_xdigit = 0; 229 break; /* '\0' was seen by inet_pton4(). */ 230 } 231 return (0); 232 } 233 if (saw_xdigit) { 234 if (tp + NS_INT16SZ > endp) 235 return (0); 236 *tp++ = (u_char) (val >> 8) & 0xff; 237 *tp++ = (u_char) val & 0xff; 238 } 239 if (colonp != NULL) { 240 /* 241 * Since some memmove()'s erroneously fail to handle 242 * overlapping regions, we'll do the shift by hand. 243 */ 244 const int n = (int)(tp - colonp); 245 int i; 246 247 for (i = 1; i <= n; i++) { 248 endp[- i] = colonp[n - i]; 249 colonp[n - i] = 0; 250 } 251 tp = endp; 252 } 253 if (tp != endp) 254 return (0); 255 memcpy(dst, tmp, NS_IN6ADDRSZ); 256 return (1); 257 } 258