155682Smarkm/* 278527Sassar * Copyright (c) 1999 - 2001 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#ifdef HAVE_CONFIG_H 3555682Smarkm#include <config.h> 36178825SdfrRCSID("$Id: inet_ntop.c 21005 2007-06-08 01:54:35Z lha $"); 3755682Smarkm#endif 3855682Smarkm 39178825Sdfr#include "roken.h" 4055682Smarkm 4155682Smarkm/* 4255682Smarkm * 4355682Smarkm */ 4455682Smarkm 4555682Smarkmstatic const char * 4655682Smarkminet_ntop_v4 (const void *src, char *dst, size_t size) 4755682Smarkm{ 4855682Smarkm const char digits[] = "0123456789"; 4955682Smarkm int i; 5055682Smarkm struct in_addr *addr = (struct in_addr *)src; 5155682Smarkm u_long a = ntohl(addr->s_addr); 5255682Smarkm const char *orig_dst = dst; 5355682Smarkm 5455682Smarkm if (size < INET_ADDRSTRLEN) { 5555682Smarkm errno = ENOSPC; 5655682Smarkm return NULL; 5755682Smarkm } 5855682Smarkm for (i = 0; i < 4; ++i) { 5955682Smarkm int n = (a >> (24 - i * 8)) & 0xFF; 6055682Smarkm int non_zerop = 0; 6155682Smarkm 6255682Smarkm if (non_zerop || n / 100 > 0) { 6355682Smarkm *dst++ = digits[n / 100]; 6455682Smarkm n %= 100; 6555682Smarkm non_zerop = 1; 6655682Smarkm } 6755682Smarkm if (non_zerop || n / 10 > 0) { 6855682Smarkm *dst++ = digits[n / 10]; 6955682Smarkm n %= 10; 7055682Smarkm non_zerop = 1; 7155682Smarkm } 7255682Smarkm *dst++ = digits[n]; 7355682Smarkm if (i != 3) 7455682Smarkm *dst++ = '.'; 7555682Smarkm } 7655682Smarkm *dst++ = '\0'; 7755682Smarkm return orig_dst; 7855682Smarkm} 7955682Smarkm 8055682Smarkm#ifdef HAVE_IPV6 8155682Smarkmstatic const char * 8255682Smarkminet_ntop_v6 (const void *src, char *dst, size_t size) 8355682Smarkm{ 8455682Smarkm const char xdigits[] = "0123456789abcdef"; 8555682Smarkm int i; 8655682Smarkm const struct in6_addr *addr = (struct in6_addr *)src; 8755682Smarkm const u_char *ptr = addr->s6_addr; 8855682Smarkm const char *orig_dst = dst; 8955682Smarkm 9055682Smarkm if (size < INET6_ADDRSTRLEN) { 9155682Smarkm errno = ENOSPC; 9255682Smarkm return NULL; 9355682Smarkm } 9455682Smarkm for (i = 0; i < 8; ++i) { 9578527Sassar int non_zerop = 0; 9655682Smarkm 9755682Smarkm if (non_zerop || (ptr[0] >> 4)) { 9855682Smarkm *dst++ = xdigits[ptr[0] >> 4]; 9955682Smarkm non_zerop = 1; 10055682Smarkm } 10155682Smarkm if (non_zerop || (ptr[0] & 0x0F)) { 10255682Smarkm *dst++ = xdigits[ptr[0] & 0x0F]; 10355682Smarkm non_zerop = 1; 10455682Smarkm } 10555682Smarkm if (non_zerop || (ptr[1] >> 4)) { 10655682Smarkm *dst++ = xdigits[ptr[1] >> 4]; 10755682Smarkm non_zerop = 1; 10855682Smarkm } 10978527Sassar *dst++ = xdigits[ptr[1] & 0x0F]; 11055682Smarkm if (i != 7) 11155682Smarkm *dst++ = ':'; 11255682Smarkm ptr += 2; 11355682Smarkm } 11455682Smarkm *dst++ = '\0'; 11555682Smarkm return orig_dst; 11655682Smarkm} 11755682Smarkm#endif /* HAVE_IPV6 */ 11855682Smarkm 119178825Sdfrconst char * ROKEN_LIB_FUNCTION 12055682Smarkminet_ntop(int af, const void *src, char *dst, size_t size) 12155682Smarkm{ 12255682Smarkm switch (af) { 12355682Smarkm case AF_INET : 12455682Smarkm return inet_ntop_v4 (src, dst, size); 12555682Smarkm#ifdef HAVE_IPV6 12655682Smarkm case AF_INET6 : 12755682Smarkm return inet_ntop_v6 (src, dst, size); 12855682Smarkm#endif 12955682Smarkm default : 13055682Smarkm errno = EAFNOSUPPORT; 13155682Smarkm return NULL; 13255682Smarkm } 13355682Smarkm} 134