--- /dev/null
+/*\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