1 /* 2 * Copyright (c) 1999 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 RCSID("$Id: inet_ntop.c,v 1.3 1999/12/02 16:58:47 joda Exp $"); 37 #endif 38 39 #include <errno.h> 40 #ifdef HAVE_SYS_TYPES_H 41 #include <sys/types.h> 42 #endif 43 #ifdef HAVE_SYS_SOCKET_H 44 #include <sys/socket.h> 45 #endif 46 #ifdef HAVE_NETINET_IN_H 47 #include <netinet/in.h> 48 #endif 49 #ifdef HAVE_NETINET_IN6_H 50 #include <netinet/in6.h> 51 #endif 52 #ifdef HAVE_NETINET6_IN6_H 53 #include <netinet6/in6.h> 54 #endif 55 56 #include <roken.h> 57 58 /* 59 * 60 */ 61 62 static const char * 63 inet_ntop_v4 (const void *src, char *dst, size_t size) 64 { 65 const char digits[] = "0123456789"; 66 int i; 67 struct in_addr *addr = (struct in_addr *)src; 68 u_long a = ntohl(addr->s_addr); 69 const char *orig_dst = dst; 70 71 if (size < INET_ADDRSTRLEN) { 72 errno = ENOSPC; 73 return NULL; 74 } 75 for (i = 0; i < 4; ++i) { 76 int n = (a >> (24 - i * 8)) & 0xFF; 77 int non_zerop = 0; 78 79 if (non_zerop || n / 100 > 0) { 80 *dst++ = digits[n / 100]; 81 n %= 100; 82 non_zerop = 1; 83 } 84 if (non_zerop || n / 10 > 0) { 85 *dst++ = digits[n / 10]; 86 n %= 10; 87 non_zerop = 1; 88 } 89 *dst++ = digits[n]; 90 if (i != 3) 91 *dst++ = '.'; 92 } 93 *dst++ = '\0'; 94 return orig_dst; 95 } 96 97 #ifdef HAVE_IPV6 98 static const char * 99 inet_ntop_v6 (const void *src, char *dst, size_t size) 100 { 101 const char xdigits[] = "0123456789abcdef"; 102 int i; 103 const struct in6_addr *addr = (struct in6_addr *)src; 104 const u_char *ptr = addr->s6_addr; 105 const char *orig_dst = dst; 106 107 if (size < INET6_ADDRSTRLEN) { 108 errno = ENOSPC; 109 return NULL; 110 } 111 for (i = 0; i < 8; ++i) { 112 int non_zerop = 1; 113 114 if (non_zerop || (ptr[0] >> 4)) { 115 *dst++ = xdigits[ptr[0] >> 4]; 116 non_zerop = 1; 117 } 118 if (non_zerop || (ptr[0] & 0x0F)) { 119 *dst++ = xdigits[ptr[0] & 0x0F]; 120 non_zerop = 1; 121 } 122 if (non_zerop || (ptr[1] >> 4)) { 123 *dst++ = xdigits[ptr[1] >> 4]; 124 non_zerop = 1; 125 } 126 if (non_zerop || (ptr[1] & 0x0F)) { 127 *dst++ = xdigits[ptr[1] & 0x0F]; 128 non_zerop = 1; 129 } 130 if (i != 7) 131 *dst++ = ':'; 132 ptr += 2; 133 } 134 *dst++ = '\0'; 135 return orig_dst; 136 } 137 #endif /* HAVE_IPV6 */ 138 139 const char * 140 inet_ntop(int af, const void *src, char *dst, size_t size) 141 { 142 switch (af) { 143 case AF_INET : 144 return inet_ntop_v4 (src, dst, size); 145 #ifdef HAVE_IPV6 146 case AF_INET6 : 147 return inet_ntop_v6 (src, dst, size); 148 #endif 149 default : 150 errno = EAFNOSUPPORT; 151 return NULL; 152 } 153 } 154