15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Copyright (C) 1996-2001 Internet Software Consortium. 35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Permission to use, copy, modify, and distribute this software for any 55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * purpose with or without fee is hereby granted, provided that the above 65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copyright notice and this permission notice appear in all copies. 75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 85ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM 95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Original code by Paul Vixie. "curlified" by Gisle Vanem. 195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifndef HAVE_INET_NTOP 245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_SYS_PARAM_H 265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <sys/param.h> 275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_NETINET_IN_H 295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <netinet/in.h> 305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_ARPA_INET_H 325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <arpa/inet.h> 335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "inet_ntop.h" 368f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo#include "curl_printf.h" 375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define IN6ADDRSZ 16 395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define INADDRSZ 4 405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define INT16SZ 2 415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Format an IPv4 address, more or less like inet_ntoa(). 445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns `dst' (as a const) 465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Note: 475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * - uses no statics 485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * - takes a unsigned char* not an in_addr as input 495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) 515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char tmp[sizeof "255.255.255.255"]; 535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen size_t len; 545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen DEBUGASSERT(size >= 16); 565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tmp[0] = '\0'; 585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", 598f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo ((int)((unsigned char)src[0])) & 0xff, 608f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo ((int)((unsigned char)src[1])) & 0xff, 618f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo ((int)((unsigned char)src[2])) & 0xff, 628f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo ((int)((unsigned char)src[3])) & 0xff); 635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen len = strlen(tmp); 65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(len == 0 || len >= size) { 6682be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes errno = ENOSPC; 675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return (NULL); 685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen strcpy(dst, tmp); 705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return dst; 715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6 745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Convert IPv6 binary address into presentation (printable) format. 765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) 785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* 805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Note that int32_t and int16_t need only be "at least" large enough 815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * to contain a value of the specified size. On some systems, like 825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Crays, there is no such thing as an integer variable with 16 bits. 835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Keep this in mind if you think this function should have been coded 845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * to use pointer overlays. All the world's not a VAX. 855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; 875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *tp; 885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen struct { 895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen long base; 905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen long len; 915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } best, cur; 925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen unsigned long words[IN6ADDRSZ / INT16SZ]; 935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int i; 945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Preprocess: 965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Copy the input (bytewise) array into a wordwise array. 975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Find the longest run of 0x00's in src[] for :: shorthanding. 985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen memset(words, '\0', sizeof(words)); 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < IN6ADDRSZ; i++) 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); 1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen best.base = -1; 1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cur.base = -1; 1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen best.len = 0; 1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cur.len = 0; 1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { 109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(words[i] == 0) { 1105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(cur.base == -1) 1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cur.base = i, cur.len = 1; 1125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 1135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cur.len++; 1145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else if(cur.base != -1) { 1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(best.base == -1 || cur.len > best.len) 117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET best = cur; 1185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cur.base = -1; 1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) 122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET best = cur; 1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(best.base != -1 && best.len < 2) 124e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET best.base = -1; 125e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Format the result. */ 1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tp = tmp; 127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { 128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Are we inside the best run of 0x00's? */ 129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { 1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(i == best.base) 131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *tp++ = ':'; 1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen continue; 1335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Are we following an initial run of 0x00s or any real hex? 1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(i != 0) 138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *tp++ = ':'; 1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Is this address an encapsulated IPv4? 1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(i == 6 && best.base == 0 && 143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 144486467e11b5904b3e04adc2f5fdb96fcfe65da84Alex Deymo if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) { 14582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes errno = ENOSPC; 1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return (NULL); 1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tp += strlen(tp); 1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tp += snprintf(tp, 5, "%lx", words[i]); 1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Was it a trailing run of 0x00's? 1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) 1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *tp++ = ':'; 1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *tp++ = '\0'; 1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Check for overflow, copy, and we're done. 1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((size_t)(tp - tmp) > size) { 16382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes errno = ENOSPC; 1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return (NULL); 1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen strcpy(dst, tmp); 1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return dst; 1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* ENABLE_IPV6 */ 1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Convert a network format address to presentation format. 1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns pointer to presentation format address (`buf'). 1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns NULL on error and errno set with the specific 1765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * error, EAFNOSUPPORT or ENOSPC. 1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * On Windows we store the error in the thread errno, not 179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * in the winsock error code. This is to avoid losing the 18082be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * actual last winsock error. So when this function returns 18182be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes * NULL, check errno not SOCKERRNO. 1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenchar *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) 1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 18582be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes switch(af) { 1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case AF_INET: 187cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes return inet_ntop4((const unsigned char *)src, buf, size); 1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef ENABLE_IPV6 1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case AF_INET6: 190cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes return inet_ntop6((const unsigned char *)src, buf, size); 1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen default: 19382be86df6ec7baa34d6169c053fd1dfe56fa858eElliott Hughes errno = EAFNOSUPPORT; 1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return NULL; 1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* HAVE_INET_NTOP */ 198