1/* -*- buffer-read-only: t -*- vi: set ro: */ 2/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ 3#line 1 4/* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form 5 6 Copyright (C) 2005-2006, 2008-2010 Free Software Foundation, Inc. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software Foundation, 20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22/* 23 * Copyright (c) 1996-1999 by Internet Software Consortium. 24 * 25 * Permission to use, copy, modify, and distribute this software for any 26 * purpose with or without fee is hereby granted, provided that the above 27 * copyright notice and this permission notice appear in all copies. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 30 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 31 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 32 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 33 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 34 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 35 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 36 * SOFTWARE. 37 */ 38 39#include <config.h> 40 41/* Specification. */ 42#include <arpa/inet.h> 43 44#include <stdio.h> 45#include <string.h> 46#include <errno.h> 47 48#define NS_IN6ADDRSZ 16 49#define NS_INT16SZ 2 50 51/* 52 * WARNING: Don't even consider trying to compile this on a system where 53 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. 54 */ 55typedef int verify_int_size[2 * sizeof (int) - 7]; 56 57static const char *inet_ntop4 (const unsigned char *src, char *dst, socklen_t size); 58#if HAVE_IPV6 59static const char *inet_ntop6 (const unsigned char *src, char *dst, socklen_t size); 60#endif 61 62 63/* char * 64 * inet_ntop(af, src, dst, size) 65 * convert a network format address to presentation format. 66 * return: 67 * pointer to presentation format address (`dst'), or NULL (see errno). 68 * author: 69 * Paul Vixie, 1996. 70 */ 71const char * 72inet_ntop (int af, const void *restrict src, 73 char *restrict dst, socklen_t cnt) 74{ 75 switch (af) 76 { 77#if HAVE_IPV4 78 case AF_INET: 79 return (inet_ntop4 (src, dst, cnt)); 80#endif 81 82#if HAVE_IPV6 83 case AF_INET6: 84 return (inet_ntop6 (src, dst, cnt)); 85#endif 86 87 default: 88 errno = EAFNOSUPPORT; 89 return (NULL); 90 } 91 /* NOTREACHED */ 92} 93 94/* const char * 95 * inet_ntop4(src, dst, size) 96 * format an IPv4 address 97 * return: 98 * `dst' (as a const) 99 * notes: 100 * (1) uses no statics 101 * (2) takes a u_char* not an in_addr as input 102 * author: 103 * Paul Vixie, 1996. 104 */ 105static const char * 106inet_ntop4 (const unsigned char *src, char *dst, socklen_t size) 107{ 108 char tmp[sizeof "255.255.255.255"]; 109 int len; 110 111 len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); 112 if (len < 0) 113 return NULL; 114 115 if (len > size) 116 { 117 errno = ENOSPC; 118 return NULL; 119 } 120 121 return strcpy (dst, tmp); 122} 123 124#if HAVE_IPV6 125 126/* const char * 127 * inet_ntop6(src, dst, size) 128 * convert IPv6 binary address into presentation (printable) format 129 * author: 130 * Paul Vixie, 1996. 131 */ 132static const char * 133inet_ntop6 (const unsigned char *src, char *dst, socklen_t size) 134{ 135 /* 136 * Note that int32_t and int16_t need only be "at least" large enough 137 * to contain a value of the specified size. On some systems, like 138 * Crays, there is no such thing as an integer variable with 16 bits. 139 * Keep this in mind if you think this function should have been coded 140 * to use pointer overlays. All the world's not a VAX. 141 */ 142 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 143 struct 144 { 145 int base, len; 146 } best, cur; 147 unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; 148 int i; 149 150 /* 151 * Preprocess: 152 * Copy the input (bytewise) array into a wordwise array. 153 * Find the longest run of 0x00's in src[] for :: shorthanding. 154 */ 155 memset (words, '\0', sizeof words); 156 for (i = 0; i < NS_IN6ADDRSZ; i += 2) 157 words[i / 2] = (src[i] << 8) | src[i + 1]; 158 best.base = -1; 159 cur.base = -1; 160 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) 161 { 162 if (words[i] == 0) 163 { 164 if (cur.base == -1) 165 cur.base = i, cur.len = 1; 166 else 167 cur.len++; 168 } 169 else 170 { 171 if (cur.base != -1) 172 { 173 if (best.base == -1 || cur.len > best.len) 174 best = cur; 175 cur.base = -1; 176 } 177 } 178 } 179 if (cur.base != -1) 180 { 181 if (best.base == -1 || cur.len > best.len) 182 best = cur; 183 } 184 if (best.base != -1 && best.len < 2) 185 best.base = -1; 186 187 /* 188 * Format the result. 189 */ 190 tp = tmp; 191 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) 192 { 193 /* Are we inside the best run of 0x00's? */ 194 if (best.base != -1 && i >= best.base && i < (best.base + best.len)) 195 { 196 if (i == best.base) 197 *tp++ = ':'; 198 continue; 199 } 200 /* Are we following an initial run of 0x00s or any real hex? */ 201 if (i != 0) 202 *tp++ = ':'; 203 /* Is this address an encapsulated IPv4? */ 204 if (i == 6 && best.base == 0 && 205 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) 206 { 207 if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp))) 208 return (NULL); 209 tp += strlen (tp); 210 break; 211 } 212 { 213 int len = sprintf (tp, "%x", words[i]); 214 if (len < 0) 215 return NULL; 216 tp += len; 217 } 218 } 219 /* Was it a trailing run of 0x00's? */ 220 if (best.base != -1 && (best.base + best.len) == 221 (NS_IN6ADDRSZ / NS_INT16SZ)) 222 *tp++ = ':'; 223 *tp++ = '\0'; 224 225 /* 226 * Check for overflow, copy, and we're done. 227 */ 228 if ((socklen_t) (tp - tmp) > size) 229 { 230 errno = ENOSPC; 231 return NULL; 232 } 233 234 return strcpy (dst, tmp); 235} 236 237#endif 238