-/*\r
- * Copyright (c) 1996 by Internet Software Consortium.\r
- *\r
- * Permission to use, copy, modify, and distribute this software for any\r
- * purpose with or without fee is hereby granted, provided that the above\r
- * copyright notice and this permission notice appear in all copies.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
- * SOFTWARE.\r
- */\r
-\r
-/*\r
- * Portions copyright (c) 1999, 2000\r
- * Intel Corporation.\r
- * All rights reserved.\r
- * \r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * \r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * \r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * \r
- * 3. All advertising materials mentioning features or use of this software\r
- * must display the following acknowledgement:\r
- * \r
- * This product includes software developed by Intel Corporation and\r
- * its contributors.\r
- * \r
- * 4. Neither the name of Intel Corporation or its contributors may be\r
- * used to endorse or promote products derived from this software\r
- * without specific prior written permission.\r
- * \r
- * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
- * THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- */\r
-\r
-#if defined(LIBC_SCCS) && !defined(lint)\r
-static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";\r
-static const char rcsid[] = "$Id: inet_net_pton.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $";\r
-#endif\r
-\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-#include <netinet/in.h>\r
-#include <arpa/inet.h>\r
-\r
-#include <assert.h>\r
-#include <ctype.h>\r
-#include <errno.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#ifdef SPRINTF_CHAR\r
-# define SPRINTF(x) strlen(sprintf/**/x)\r
-#else\r
-# define SPRINTF(x) ((size_t)sprintf x)\r
-#endif\r
-\r
-static int inet_net_pton_ipv4 (const char *src, u_char *dst,\r
- size_t size);\r
-\r
-/*\r
- * static int\r
- * inet_net_pton(af, src, dst, size)\r
- * convert network number from presentation to network format.\r
- * accepts hex octets, hex strings, decimal octets, and /CIDR.\r
- * "size" is in bytes and describes "dst".\r
- * return:\r
- * number of bits, either imputed classfully or specified with /CIDR,\r
- * or -1 if some failure occurred (check errno). ENOENT means it was\r
- * not a valid network specification.\r
- * author:\r
- * Paul Vixie (ISC), June 1996\r
- */\r
-int\r
-inet_net_pton(\r
- int af,\r
- const char *src,\r
- void *dst,\r
- size_t size\r
- )\r
-{\r
- switch (af) {\r
- case AF_INET:\r
- return (inet_net_pton_ipv4(src, dst, size));\r
- default:\r
- errno = EAFNOSUPPORT;\r
- return (-1);\r
- }\r
-}\r
-\r
-/*\r
- * static int\r
- * inet_net_pton_ipv4(src, dst, size)\r
- * convert IPv4 network number from presentation to network format.\r
- * accepts hex octets, hex strings, decimal octets, and /CIDR.\r
- * "size" is in bytes and describes "dst".\r
- * return:\r
- * number of bits, either imputed classfully or specified with /CIDR,\r
- * or -1 if some failure occurred (check errno). ENOENT means it was\r
- * not an IPv4 network specification.\r
- * note:\r
- * network byte order assumed. this means 192.5.5.240/28 has\r
- * 0x11110000 in its fourth octet.\r
- * author:\r
- * Paul Vixie (ISC), June 1996\r
- */\r
-static int\r
-inet_net_pton_ipv4(\r
- const char *src,\r
- u_char *dst,\r
- size_t size\r
- )\r
-{\r
- static const char xdigits[] = "0123456789abcdef";\r
- static const char digits[] = "0123456789";\r
- int n;\r
- int ch;\r
- int tmp;\r
- int dirty;\r
- int bits;\r
- const u_char *odst = dst;\r
-\r
- ch = *src++;\r
- if (ch == '0' && (src[0] == 'x' || src[0] == 'X')\r
- && isascii(src[1]) && isxdigit(src[1])) {\r
- /* Hexadecimal: Eat nybble string. */\r
- if (size <= 0)\r
- goto emsgsize;\r
- *dst = 0, dirty = 0;\r
- src++; /* skip x or X. */\r
- while ((ch = *src++) != '\0' &&\r
- isascii(ch) && isxdigit(ch)) {\r
- if (isupper(ch))\r
- ch = tolower(ch);\r
- n = (int)(strchr(xdigits, ch) - xdigits);\r
- assert(n >= 0 && n <= 15);\r
- *dst |= n;\r
- if (!dirty++)\r
- *dst <<= 4;\r
- else if (size-- > 0)\r
- *++dst = 0, dirty = 0;\r
- else\r
- goto emsgsize;\r
- }\r
- if (dirty)\r
- size--;\r
- } else if (isascii(ch) && isdigit(ch)) {\r
- /* Decimal: eat dotted digit string. */\r
- for (;;) {\r
- tmp = 0;\r
- do {\r
- n = (int)(strchr(digits, ch) - digits);\r
- assert(n >= 0 && n <= 9);\r
- tmp *= 10;\r
- tmp += n;\r
- if (tmp > 255)\r
- goto enoent;\r
- } while ((ch = *src++) != '\0' &&\r
- isascii(ch) && isdigit(ch));\r
- if (size-- <= 0)\r
- goto emsgsize;\r
- *dst++ = (u_char) tmp;\r
- if (ch == '\0' || ch == '/')\r
- break;\r
- if (ch != '.')\r
- goto enoent;\r
- ch = *src++;\r
- if (!isascii(ch) || !isdigit(ch))\r
- goto enoent;\r
- }\r
- } else\r
- goto enoent;\r
-\r
- bits = -1;\r
- if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {\r
- /* CIDR width specifier. Nothing can follow it. */\r
- ch = *src++; /* Skip over the /. */\r
- bits = 0;\r
- do {\r
- n = (int)(strchr(digits, ch) - digits);\r
- assert(n >= 0 && n <= 9);\r
- bits *= 10;\r
- bits += n;\r
- } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));\r
- if (ch != '\0')\r
- goto enoent;\r
- if (bits > 32)\r
- goto emsgsize;\r
- }\r
-\r
- /* Firey death and destruction unless we prefetched EOS. */\r
- if (ch != '\0')\r
- goto enoent;\r
-\r
- /* If nothing was written to the destination, we found no address. */\r
- if (dst == odst)\r
- goto enoent;\r
- /* If no CIDR spec was given, infer width from net class. */\r
- if (bits == -1) {\r
- if (*odst >= 240) /* Class E */\r
- bits = 32;\r
- else if (*odst >= 224) /* Class D */\r
- bits = 4;\r
- else if (*odst >= 192) /* Class C */\r
- bits = 24;\r
- else if (*odst >= 128) /* Class B */\r
- bits = 16;\r
- else /* Class A */\r
- bits = 8;\r
- /* If imputed mask is narrower than specified octets, widen. */\r
- if (bits >= 8 && bits < ((dst - odst) * 8))\r
- bits = (int)(dst - odst) * 8;\r
- }\r
- /* Extend network to cover the actual mask. */\r
- while (bits > ((dst - odst) * 8)) {\r
- if (size-- <= 0)\r
- goto emsgsize;\r
- *dst++ = '\0';\r
- }\r
- return (bits);\r
-\r
- enoent:\r
- errno = ENOENT;\r
- return (-1);\r
-\r
- emsgsize:\r
- errno = EMSGSIZE;\r
- return (-1);\r
-}\r