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