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