165e96449SHajimu UMEMOTO /* 265e96449SHajimu UMEMOTO * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 365e96449SHajimu UMEMOTO * Copyright (c) 1996,1999 by Internet Software Consortium. 465e96449SHajimu UMEMOTO * 565e96449SHajimu UMEMOTO * Permission to use, copy, modify, and distribute this software for any 665e96449SHajimu UMEMOTO * purpose with or without fee is hereby granted, provided that the above 765e96449SHajimu UMEMOTO * copyright notice and this permission notice appear in all copies. 865e96449SHajimu UMEMOTO * 965e96449SHajimu UMEMOTO * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1065e96449SHajimu UMEMOTO * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1165e96449SHajimu UMEMOTO * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1265e96449SHajimu UMEMOTO * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1365e96449SHajimu UMEMOTO * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1465e96449SHajimu UMEMOTO * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1565e96449SHajimu UMEMOTO * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1665e96449SHajimu UMEMOTO */ 1765e96449SHajimu UMEMOTO 1865e96449SHajimu UMEMOTO #if defined(LIBC_SCCS) && !defined(lint) 1965e96449SHajimu UMEMOTO static const char rcsid[] = "$Id: inet_net_pton.c,v 1.4.2.1.8.2 2004/03/17 00:29:47 marka Exp $"; 2065e96449SHajimu UMEMOTO #endif 2165e96449SHajimu UMEMOTO 2265e96449SHajimu UMEMOTO #include "port_before.h" 2365e96449SHajimu UMEMOTO 2465e96449SHajimu UMEMOTO #include <sys/types.h> 2565e96449SHajimu UMEMOTO #include <sys/socket.h> 2665e96449SHajimu UMEMOTO #include <netinet/in.h> 2765e96449SHajimu UMEMOTO #include <arpa/nameser.h> 2865e96449SHajimu UMEMOTO #include <arpa/inet.h> 2965e96449SHajimu UMEMOTO 3065e96449SHajimu UMEMOTO #include <isc/assertions.h> 3165e96449SHajimu UMEMOTO #include <ctype.h> 3265e96449SHajimu UMEMOTO #include <errno.h> 3365e96449SHajimu UMEMOTO #include <stdio.h> 3465e96449SHajimu UMEMOTO #include <string.h> 3565e96449SHajimu UMEMOTO #include <stdlib.h> 3665e96449SHajimu UMEMOTO 3765e96449SHajimu UMEMOTO #include "port_after.h" 3865e96449SHajimu UMEMOTO 3965e96449SHajimu UMEMOTO #ifdef SPRINTF_CHAR 4065e96449SHajimu UMEMOTO # define SPRINTF(x) strlen(sprintf/**/x) 4165e96449SHajimu UMEMOTO #else 4265e96449SHajimu UMEMOTO # define SPRINTF(x) ((size_t)sprintf x) 4365e96449SHajimu UMEMOTO #endif 4465e96449SHajimu UMEMOTO 4565e96449SHajimu UMEMOTO /* 4665e96449SHajimu UMEMOTO * static int 4765e96449SHajimu UMEMOTO * inet_net_pton_ipv4(src, dst, size) 4865e96449SHajimu UMEMOTO * convert IPv4 network number from presentation to network format. 4965e96449SHajimu UMEMOTO * accepts hex octets, hex strings, decimal octets, and /CIDR. 5065e96449SHajimu UMEMOTO * "size" is in bytes and describes "dst". 5165e96449SHajimu UMEMOTO * return: 5265e96449SHajimu UMEMOTO * number of bits, either imputed classfully or specified with /CIDR, 5365e96449SHajimu UMEMOTO * or -1 if some failure occurred (check errno). ENOENT means it was 5465e96449SHajimu UMEMOTO * not an IPv4 network specification. 5565e96449SHajimu UMEMOTO * note: 5665e96449SHajimu UMEMOTO * network byte order assumed. this means 192.5.5.240/28 has 5765e96449SHajimu UMEMOTO * 0b11110000 in its fourth octet. 5865e96449SHajimu UMEMOTO * author: 5965e96449SHajimu UMEMOTO * Paul Vixie (ISC), June 1996 6065e96449SHajimu UMEMOTO */ 6165e96449SHajimu UMEMOTO static int 6265e96449SHajimu UMEMOTO inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { 6365e96449SHajimu UMEMOTO static const char xdigits[] = "0123456789abcdef"; 6465e96449SHajimu UMEMOTO static const char digits[] = "0123456789"; 6565e96449SHajimu UMEMOTO int n, ch, tmp = 0, dirty, bits; 6665e96449SHajimu UMEMOTO const u_char *odst = dst; 6765e96449SHajimu UMEMOTO 6865e96449SHajimu UMEMOTO ch = *src++; 6965e96449SHajimu UMEMOTO if (ch == '0' && (src[0] == 'x' || src[0] == 'X') 7065e96449SHajimu UMEMOTO && isascii((unsigned char)(src[1])) 7165e96449SHajimu UMEMOTO && isxdigit((unsigned char)(src[1]))) { 7265e96449SHajimu UMEMOTO /* Hexadecimal: Eat nybble string. */ 7365e96449SHajimu UMEMOTO if (size <= 0U) 7465e96449SHajimu UMEMOTO goto emsgsize; 7565e96449SHajimu UMEMOTO dirty = 0; 7665e96449SHajimu UMEMOTO src++; /* skip x or X. */ 7765e96449SHajimu UMEMOTO while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { 7865e96449SHajimu UMEMOTO if (isupper(ch)) 7965e96449SHajimu UMEMOTO ch = tolower(ch); 8065e96449SHajimu UMEMOTO n = strchr(xdigits, ch) - xdigits; 8165e96449SHajimu UMEMOTO INSIST(n >= 0 && n <= 15); 8265e96449SHajimu UMEMOTO if (dirty == 0) 8365e96449SHajimu UMEMOTO tmp = n; 8465e96449SHajimu UMEMOTO else 8565e96449SHajimu UMEMOTO tmp = (tmp << 4) | n; 8665e96449SHajimu UMEMOTO if (++dirty == 2) { 8765e96449SHajimu UMEMOTO if (size-- <= 0U) 8865e96449SHajimu UMEMOTO goto emsgsize; 8965e96449SHajimu UMEMOTO *dst++ = (u_char) tmp; 9065e96449SHajimu UMEMOTO dirty = 0; 9165e96449SHajimu UMEMOTO } 9265e96449SHajimu UMEMOTO } 9365e96449SHajimu UMEMOTO if (dirty) { /* Odd trailing nybble? */ 9465e96449SHajimu UMEMOTO if (size-- <= 0U) 9565e96449SHajimu UMEMOTO goto emsgsize; 9665e96449SHajimu UMEMOTO *dst++ = (u_char) (tmp << 4); 9765e96449SHajimu UMEMOTO } 9865e96449SHajimu UMEMOTO } else if (isascii(ch) && isdigit(ch)) { 9965e96449SHajimu UMEMOTO /* Decimal: eat dotted digit string. */ 10065e96449SHajimu UMEMOTO for (;;) { 10165e96449SHajimu UMEMOTO tmp = 0; 10265e96449SHajimu UMEMOTO do { 10365e96449SHajimu UMEMOTO n = strchr(digits, ch) - digits; 10465e96449SHajimu UMEMOTO INSIST(n >= 0 && n <= 9); 10565e96449SHajimu UMEMOTO tmp *= 10; 10665e96449SHajimu UMEMOTO tmp += n; 10765e96449SHajimu UMEMOTO if (tmp > 255) 10865e96449SHajimu UMEMOTO goto enoent; 10965e96449SHajimu UMEMOTO } while ((ch = *src++) != '\0' && 11065e96449SHajimu UMEMOTO isascii(ch) && isdigit(ch)); 11165e96449SHajimu UMEMOTO if (size-- <= 0U) 11265e96449SHajimu UMEMOTO goto emsgsize; 11365e96449SHajimu UMEMOTO *dst++ = (u_char) tmp; 11465e96449SHajimu UMEMOTO if (ch == '\0' || ch == '/') 11565e96449SHajimu UMEMOTO break; 11665e96449SHajimu UMEMOTO if (ch != '.') 11765e96449SHajimu UMEMOTO goto enoent; 11865e96449SHajimu UMEMOTO ch = *src++; 11965e96449SHajimu UMEMOTO if (!isascii(ch) || !isdigit(ch)) 12065e96449SHajimu UMEMOTO goto enoent; 12165e96449SHajimu UMEMOTO } 12265e96449SHajimu UMEMOTO } else 12365e96449SHajimu UMEMOTO goto enoent; 12465e96449SHajimu UMEMOTO 12565e96449SHajimu UMEMOTO bits = -1; 12665e96449SHajimu UMEMOTO if (ch == '/' && isascii((unsigned char)(src[0])) && 12765e96449SHajimu UMEMOTO isdigit((unsigned char)(src[0])) && dst > odst) { 12865e96449SHajimu UMEMOTO /* CIDR width specifier. Nothing can follow it. */ 12965e96449SHajimu UMEMOTO ch = *src++; /* Skip over the /. */ 13065e96449SHajimu UMEMOTO bits = 0; 13165e96449SHajimu UMEMOTO do { 13265e96449SHajimu UMEMOTO n = strchr(digits, ch) - digits; 13365e96449SHajimu UMEMOTO INSIST(n >= 0 && n <= 9); 13465e96449SHajimu UMEMOTO bits *= 10; 13565e96449SHajimu UMEMOTO bits += n; 13665e96449SHajimu UMEMOTO } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); 13765e96449SHajimu UMEMOTO if (ch != '\0') 13865e96449SHajimu UMEMOTO goto enoent; 13965e96449SHajimu UMEMOTO if (bits > 32) 14065e96449SHajimu UMEMOTO goto emsgsize; 14165e96449SHajimu UMEMOTO } 14265e96449SHajimu UMEMOTO 14365e96449SHajimu UMEMOTO /* Firey death and destruction unless we prefetched EOS. */ 14465e96449SHajimu UMEMOTO if (ch != '\0') 14565e96449SHajimu UMEMOTO goto enoent; 14665e96449SHajimu UMEMOTO 14765e96449SHajimu UMEMOTO /* If nothing was written to the destination, we found no address. */ 14865e96449SHajimu UMEMOTO if (dst == odst) 14965e96449SHajimu UMEMOTO goto enoent; 15065e96449SHajimu UMEMOTO /* If no CIDR spec was given, infer width from net class. */ 15165e96449SHajimu UMEMOTO if (bits == -1) { 15265e96449SHajimu UMEMOTO if (*odst >= 240) /* Class E */ 15365e96449SHajimu UMEMOTO bits = 32; 15465e96449SHajimu UMEMOTO else if (*odst >= 224) /* Class D */ 15565e96449SHajimu UMEMOTO bits = 8; 15665e96449SHajimu UMEMOTO else if (*odst >= 192) /* Class C */ 15765e96449SHajimu UMEMOTO bits = 24; 15865e96449SHajimu UMEMOTO else if (*odst >= 128) /* Class B */ 15965e96449SHajimu UMEMOTO bits = 16; 16065e96449SHajimu UMEMOTO else /* Class A */ 16165e96449SHajimu UMEMOTO bits = 8; 16265e96449SHajimu UMEMOTO /* If imputed mask is narrower than specified octets, widen. */ 16365e96449SHajimu UMEMOTO if (bits < ((dst - odst) * 8)) 16465e96449SHajimu UMEMOTO bits = (dst - odst) * 8; 16565e96449SHajimu UMEMOTO /* 16665e96449SHajimu UMEMOTO * If there are no additional bits specified for a class D 16765e96449SHajimu UMEMOTO * address adjust bits to 4. 16865e96449SHajimu UMEMOTO */ 16965e96449SHajimu UMEMOTO if (bits == 8 && *odst == 224) 17065e96449SHajimu UMEMOTO bits = 4; 17165e96449SHajimu UMEMOTO } 17265e96449SHajimu UMEMOTO /* Extend network to cover the actual mask. */ 17365e96449SHajimu UMEMOTO while (bits > ((dst - odst) * 8)) { 17465e96449SHajimu UMEMOTO if (size-- <= 0U) 17565e96449SHajimu UMEMOTO goto emsgsize; 17665e96449SHajimu UMEMOTO *dst++ = '\0'; 17765e96449SHajimu UMEMOTO } 17865e96449SHajimu UMEMOTO return (bits); 17965e96449SHajimu UMEMOTO 18065e96449SHajimu UMEMOTO enoent: 18165e96449SHajimu UMEMOTO errno = ENOENT; 18265e96449SHajimu UMEMOTO return (-1); 18365e96449SHajimu UMEMOTO 18465e96449SHajimu UMEMOTO emsgsize: 18565e96449SHajimu UMEMOTO errno = EMSGSIZE; 18665e96449SHajimu UMEMOTO return (-1); 18765e96449SHajimu UMEMOTO } 18865e96449SHajimu UMEMOTO 18965e96449SHajimu UMEMOTO static int 19065e96449SHajimu UMEMOTO getbits(const char *src, int *bitsp) { 19165e96449SHajimu UMEMOTO static const char digits[] = "0123456789"; 19265e96449SHajimu UMEMOTO int n; 19365e96449SHajimu UMEMOTO int val; 19465e96449SHajimu UMEMOTO char ch; 19565e96449SHajimu UMEMOTO 19665e96449SHajimu UMEMOTO val = 0; 19765e96449SHajimu UMEMOTO n = 0; 19865e96449SHajimu UMEMOTO while ((ch = *src++) != '\0') { 19965e96449SHajimu UMEMOTO const char *pch; 20065e96449SHajimu UMEMOTO 20165e96449SHajimu UMEMOTO pch = strchr(digits, ch); 20265e96449SHajimu UMEMOTO if (pch != NULL) { 20365e96449SHajimu UMEMOTO if (n++ != 0 && val == 0) /* no leading zeros */ 20465e96449SHajimu UMEMOTO return (0); 20565e96449SHajimu UMEMOTO val *= 10; 20665e96449SHajimu UMEMOTO val += (pch - digits); 20765e96449SHajimu UMEMOTO if (val > 128) /* range */ 20865e96449SHajimu UMEMOTO return (0); 20965e96449SHajimu UMEMOTO continue; 21065e96449SHajimu UMEMOTO } 21165e96449SHajimu UMEMOTO return (0); 21265e96449SHajimu UMEMOTO } 21365e96449SHajimu UMEMOTO if (n == 0) 21465e96449SHajimu UMEMOTO return (0); 21565e96449SHajimu UMEMOTO *bitsp = val; 21665e96449SHajimu UMEMOTO return (1); 21765e96449SHajimu UMEMOTO } 21865e96449SHajimu UMEMOTO 21965e96449SHajimu UMEMOTO static int 22065e96449SHajimu UMEMOTO getv4(const char *src, u_char *dst, int *bitsp) { 22165e96449SHajimu UMEMOTO static const char digits[] = "0123456789"; 22265e96449SHajimu UMEMOTO u_char *odst = dst; 22365e96449SHajimu UMEMOTO int n; 22465e96449SHajimu UMEMOTO u_int val; 22565e96449SHajimu UMEMOTO char ch; 22665e96449SHajimu UMEMOTO 22765e96449SHajimu UMEMOTO val = 0; 22865e96449SHajimu UMEMOTO n = 0; 22965e96449SHajimu UMEMOTO while ((ch = *src++) != '\0') { 23065e96449SHajimu UMEMOTO const char *pch; 23165e96449SHajimu UMEMOTO 23265e96449SHajimu UMEMOTO pch = strchr(digits, ch); 23365e96449SHajimu UMEMOTO if (pch != NULL) { 23465e96449SHajimu UMEMOTO if (n++ != 0 && val == 0) /* no leading zeros */ 23565e96449SHajimu UMEMOTO return (0); 23665e96449SHajimu UMEMOTO val *= 10; 23765e96449SHajimu UMEMOTO val += (pch - digits); 23865e96449SHajimu UMEMOTO if (val > 255) /* range */ 23965e96449SHajimu UMEMOTO return (0); 24065e96449SHajimu UMEMOTO continue; 24165e96449SHajimu UMEMOTO } 24265e96449SHajimu UMEMOTO if (ch == '.' || ch == '/') { 24365e96449SHajimu UMEMOTO if (dst - odst > 3) /* too many octets? */ 24465e96449SHajimu UMEMOTO return (0); 24565e96449SHajimu UMEMOTO *dst++ = val; 24665e96449SHajimu UMEMOTO if (ch == '/') 24765e96449SHajimu UMEMOTO return (getbits(src, bitsp)); 24865e96449SHajimu UMEMOTO val = 0; 24965e96449SHajimu UMEMOTO n = 0; 25065e96449SHajimu UMEMOTO continue; 25165e96449SHajimu UMEMOTO } 25265e96449SHajimu UMEMOTO return (0); 25365e96449SHajimu UMEMOTO } 25465e96449SHajimu UMEMOTO if (n == 0) 25565e96449SHajimu UMEMOTO return (0); 25665e96449SHajimu UMEMOTO if (dst - odst > 3) /* too many octets? */ 25765e96449SHajimu UMEMOTO return (0); 25865e96449SHajimu UMEMOTO *dst++ = val; 25965e96449SHajimu UMEMOTO return (1); 26065e96449SHajimu UMEMOTO } 26165e96449SHajimu UMEMOTO 26265e96449SHajimu UMEMOTO static int 26365e96449SHajimu UMEMOTO inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) { 26465e96449SHajimu UMEMOTO static const char xdigits_l[] = "0123456789abcdef", 26565e96449SHajimu UMEMOTO xdigits_u[] = "0123456789ABCDEF"; 26665e96449SHajimu UMEMOTO u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; 26765e96449SHajimu UMEMOTO const char *xdigits, *curtok; 26865e96449SHajimu UMEMOTO int ch, saw_xdigit; 26965e96449SHajimu UMEMOTO u_int val; 27065e96449SHajimu UMEMOTO int digits; 27165e96449SHajimu UMEMOTO int bits; 27265e96449SHajimu UMEMOTO size_t bytes; 27365e96449SHajimu UMEMOTO int words; 27465e96449SHajimu UMEMOTO int ipv4; 27565e96449SHajimu UMEMOTO 27665e96449SHajimu UMEMOTO memset((tp = tmp), '\0', NS_IN6ADDRSZ); 27765e96449SHajimu UMEMOTO endp = tp + NS_IN6ADDRSZ; 27865e96449SHajimu UMEMOTO colonp = NULL; 27965e96449SHajimu UMEMOTO /* Leading :: requires some special handling. */ 28065e96449SHajimu UMEMOTO if (*src == ':') 28165e96449SHajimu UMEMOTO if (*++src != ':') 28265e96449SHajimu UMEMOTO goto enoent; 28365e96449SHajimu UMEMOTO curtok = src; 28465e96449SHajimu UMEMOTO saw_xdigit = 0; 28565e96449SHajimu UMEMOTO val = 0; 28665e96449SHajimu UMEMOTO digits = 0; 28765e96449SHajimu UMEMOTO bits = -1; 28865e96449SHajimu UMEMOTO ipv4 = 0; 28965e96449SHajimu UMEMOTO while ((ch = *src++) != '\0') { 29065e96449SHajimu UMEMOTO const char *pch; 29165e96449SHajimu UMEMOTO 29265e96449SHajimu UMEMOTO if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) 29365e96449SHajimu UMEMOTO pch = strchr((xdigits = xdigits_u), ch); 29465e96449SHajimu UMEMOTO if (pch != NULL) { 29565e96449SHajimu UMEMOTO val <<= 4; 29665e96449SHajimu UMEMOTO val |= (pch - xdigits); 29765e96449SHajimu UMEMOTO if (++digits > 4) 29865e96449SHajimu UMEMOTO goto enoent; 29965e96449SHajimu UMEMOTO saw_xdigit = 1; 30065e96449SHajimu UMEMOTO continue; 30165e96449SHajimu UMEMOTO } 30265e96449SHajimu UMEMOTO if (ch == ':') { 30365e96449SHajimu UMEMOTO curtok = src; 30465e96449SHajimu UMEMOTO if (!saw_xdigit) { 30565e96449SHajimu UMEMOTO if (colonp) 30665e96449SHajimu UMEMOTO goto enoent; 30765e96449SHajimu UMEMOTO colonp = tp; 30865e96449SHajimu UMEMOTO continue; 30965e96449SHajimu UMEMOTO } else if (*src == '\0') 31065e96449SHajimu UMEMOTO goto enoent; 31165e96449SHajimu UMEMOTO if (tp + NS_INT16SZ > endp) 31265e96449SHajimu UMEMOTO return (0); 31365e96449SHajimu UMEMOTO *tp++ = (u_char) (val >> 8) & 0xff; 31465e96449SHajimu UMEMOTO *tp++ = (u_char) val & 0xff; 31565e96449SHajimu UMEMOTO saw_xdigit = 0; 31665e96449SHajimu UMEMOTO digits = 0; 31765e96449SHajimu UMEMOTO val = 0; 31865e96449SHajimu UMEMOTO continue; 31965e96449SHajimu UMEMOTO } 32065e96449SHajimu UMEMOTO if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && 32165e96449SHajimu UMEMOTO getv4(curtok, tp, &bits) > 0) { 32265e96449SHajimu UMEMOTO tp += NS_INADDRSZ; 32365e96449SHajimu UMEMOTO saw_xdigit = 0; 32465e96449SHajimu UMEMOTO ipv4 = 1; 32565e96449SHajimu UMEMOTO break; /* '\0' was seen by inet_pton4(). */ 32665e96449SHajimu UMEMOTO } 32765e96449SHajimu UMEMOTO if (ch == '/' && getbits(src, &bits) > 0) 32865e96449SHajimu UMEMOTO break; 32965e96449SHajimu UMEMOTO goto enoent; 33065e96449SHajimu UMEMOTO } 33165e96449SHajimu UMEMOTO if (saw_xdigit) { 33265e96449SHajimu UMEMOTO if (tp + NS_INT16SZ > endp) 33365e96449SHajimu UMEMOTO goto enoent; 33465e96449SHajimu UMEMOTO *tp++ = (u_char) (val >> 8) & 0xff; 33565e96449SHajimu UMEMOTO *tp++ = (u_char) val & 0xff; 33665e96449SHajimu UMEMOTO } 33765e96449SHajimu UMEMOTO if (bits == -1) 33865e96449SHajimu UMEMOTO bits = 128; 33965e96449SHajimu UMEMOTO 34065e96449SHajimu UMEMOTO words = (bits + 15) / 16; 34165e96449SHajimu UMEMOTO if (words < 2) 34265e96449SHajimu UMEMOTO words = 2; 34365e96449SHajimu UMEMOTO if (ipv4) 34465e96449SHajimu UMEMOTO words = 8; 34565e96449SHajimu UMEMOTO endp = tmp + 2 * words; 34665e96449SHajimu UMEMOTO 34765e96449SHajimu UMEMOTO if (colonp != NULL) { 34865e96449SHajimu UMEMOTO /* 34965e96449SHajimu UMEMOTO * Since some memmove()'s erroneously fail to handle 35065e96449SHajimu UMEMOTO * overlapping regions, we'll do the shift by hand. 35165e96449SHajimu UMEMOTO */ 35265e96449SHajimu UMEMOTO const int n = tp - colonp; 35365e96449SHajimu UMEMOTO int i; 35465e96449SHajimu UMEMOTO 35565e96449SHajimu UMEMOTO if (tp == endp) 35665e96449SHajimu UMEMOTO goto enoent; 35765e96449SHajimu UMEMOTO for (i = 1; i <= n; i++) { 35865e96449SHajimu UMEMOTO endp[- i] = colonp[n - i]; 35965e96449SHajimu UMEMOTO colonp[n - i] = 0; 36065e96449SHajimu UMEMOTO } 36165e96449SHajimu UMEMOTO tp = endp; 36265e96449SHajimu UMEMOTO } 36365e96449SHajimu UMEMOTO if (tp != endp) 36465e96449SHajimu UMEMOTO goto enoent; 36565e96449SHajimu UMEMOTO 36665e96449SHajimu UMEMOTO bytes = (bits + 7) / 8; 36765e96449SHajimu UMEMOTO if (bytes > size) 36865e96449SHajimu UMEMOTO goto emsgsize; 36965e96449SHajimu UMEMOTO memcpy(dst, tmp, bytes); 37065e96449SHajimu UMEMOTO return (bits); 37165e96449SHajimu UMEMOTO 37265e96449SHajimu UMEMOTO enoent: 37365e96449SHajimu UMEMOTO errno = ENOENT; 37465e96449SHajimu UMEMOTO return (-1); 37565e96449SHajimu UMEMOTO 37665e96449SHajimu UMEMOTO emsgsize: 37765e96449SHajimu UMEMOTO errno = EMSGSIZE; 37865e96449SHajimu UMEMOTO return (-1); 37965e96449SHajimu UMEMOTO } 38065e96449SHajimu UMEMOTO 38165e96449SHajimu UMEMOTO /* 38265e96449SHajimu UMEMOTO * int 38365e96449SHajimu UMEMOTO * inet_net_pton(af, src, dst, size) 38465e96449SHajimu UMEMOTO * convert network number from presentation to network format. 38565e96449SHajimu UMEMOTO * accepts hex octets, hex strings, decimal octets, and /CIDR. 38665e96449SHajimu UMEMOTO * "size" is in bytes and describes "dst". 38765e96449SHajimu UMEMOTO * return: 38865e96449SHajimu UMEMOTO * number of bits, either imputed classfully or specified with /CIDR, 38965e96449SHajimu UMEMOTO * or -1 if some failure occurred (check errno). ENOENT means it was 39065e96449SHajimu UMEMOTO * not a valid network specification. 39165e96449SHajimu UMEMOTO * author: 39265e96449SHajimu UMEMOTO * Paul Vixie (ISC), June 1996 39365e96449SHajimu UMEMOTO */ 39465e96449SHajimu UMEMOTO int 39565e96449SHajimu UMEMOTO inet_net_pton(int af, const char *src, void *dst, size_t size) { 39665e96449SHajimu UMEMOTO switch (af) { 39765e96449SHajimu UMEMOTO case AF_INET: 39865e96449SHajimu UMEMOTO return (inet_net_pton_ipv4(src, dst, size)); 39965e96449SHajimu UMEMOTO case AF_INET6: 40065e96449SHajimu UMEMOTO return (inet_net_pton_ipv6(src, dst, size)); 40165e96449SHajimu UMEMOTO default: 40265e96449SHajimu UMEMOTO errno = EAFNOSUPPORT; 40365e96449SHajimu UMEMOTO return (-1); 40465e96449SHajimu UMEMOTO } 40565e96449SHajimu UMEMOTO } 406