inet_ntop.c revision 72445
1255736Sdavidch/* 2265797Sdavidcs * Copyright (c) 1999 Kungliga Tekniska H�gskolan 3255736Sdavidch * (Royal Institute of Technology, Stockholm, Sweden). 4255736Sdavidch * All rights reserved. 5255736Sdavidch * 6255736Sdavidch * Redistribution and use in source and binary forms, with or without 7255736Sdavidch * modification, are permitted provided that the following conditions 8255736Sdavidch * are met: 9255736Sdavidch * 10255736Sdavidch * 1. Redistributions of source code must retain the above copyright 11255736Sdavidch * notice, this list of conditions and the following disclaimer. 12255736Sdavidch * 13255736Sdavidch * 2. Redistributions in binary form must reproduce the above copyright 14255736Sdavidch * notice, this list of conditions and the following disclaimer in the 15255736Sdavidch * documentation and/or other materials provided with the distribution. 16255736Sdavidch * 17255736Sdavidch * 3. Neither the name of the Institute nor the names of its contributors 18255736Sdavidch * may be used to endorse or promote products derived from this software 19255736Sdavidch * without specific prior written permission. 20255736Sdavidch * 21255736Sdavidch * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22255736Sdavidch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23255736Sdavidch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24255736Sdavidch * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25255736Sdavidch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26255736Sdavidch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27255736Sdavidch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28255736Sdavidch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29255736Sdavidch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30333431Sdavidcs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31255736Sdavidch * SUCH DAMAGE. 32255736Sdavidch */ 33255736Sdavidch 34255736Sdavidch#ifdef HAVE_CONFIG_H 35255736Sdavidch#include <config.h> 36255736SdavidchRCSID("$Id: inet_ntop.c,v 1.4 2000/07/27 16:24:00 assar Exp $"); 37255736Sdavidch#endif 38255736Sdavidch 39255736Sdavidch#include <roken.h> 40255736Sdavidch 41255736Sdavidch/* 42255736Sdavidch * 43255736Sdavidch */ 44255736Sdavidch 45255736Sdavidchstatic const char * 46255736Sdavidchinet_ntop_v4 (const void *src, char *dst, size_t size) 47255736Sdavidch{ 48255736Sdavidch const char digits[] = "0123456789"; 49255736Sdavidch int i; 50255736Sdavidch struct in_addr *addr = (struct in_addr *)src; 51255736Sdavidch u_long a = ntohl(addr->s_addr); 52255736Sdavidch const char *orig_dst = dst; 53255736Sdavidch 54255736Sdavidch if (size < INET_ADDRSTRLEN) { 55255736Sdavidch errno = ENOSPC; 56255736Sdavidch return NULL; 57255736Sdavidch } 58255736Sdavidch for (i = 0; i < 4; ++i) { 59255736Sdavidch int n = (a >> (24 - i * 8)) & 0xFF; 60255736Sdavidch int non_zerop = 0; 61255736Sdavidch 62255736Sdavidch if (non_zerop || n / 100 > 0) { 63255736Sdavidch *dst++ = digits[n / 100]; 64255736Sdavidch n %= 100; 65255736Sdavidch non_zerop = 1; 66255736Sdavidch } 67255736Sdavidch if (non_zerop || n / 10 > 0) { 68255736Sdavidch *dst++ = digits[n / 10]; 69255736Sdavidch n %= 10; 70255736Sdavidch non_zerop = 1; 71255736Sdavidch } 72255736Sdavidch *dst++ = digits[n]; 73255736Sdavidch if (i != 3) 74255736Sdavidch *dst++ = '.'; 75255736Sdavidch } 76255736Sdavidch *dst++ = '\0'; 77255736Sdavidch return orig_dst; 78255736Sdavidch} 79255736Sdavidch 80255736Sdavidch#ifdef HAVE_IPV6 81255736Sdavidchstatic const char * 82255736Sdavidchinet_ntop_v6 (const void *src, char *dst, size_t size) 83255736Sdavidch{ 84255736Sdavidch const char xdigits[] = "0123456789abcdef"; 85255736Sdavidch int i; 86255736Sdavidch const struct in6_addr *addr = (struct in6_addr *)src; 87255736Sdavidch const u_char *ptr = addr->s6_addr; 88255736Sdavidch const char *orig_dst = dst; 89255736Sdavidch 90255736Sdavidch if (size < INET6_ADDRSTRLEN) { 91255736Sdavidch errno = ENOSPC; 92255736Sdavidch return NULL; 93255736Sdavidch } 94255736Sdavidch for (i = 0; i < 8; ++i) { 95255736Sdavidch int non_zerop = 1; 96255736Sdavidch 97255736Sdavidch if (non_zerop || (ptr[0] >> 4)) { 98255736Sdavidch *dst++ = xdigits[ptr[0] >> 4]; 99255736Sdavidch non_zerop = 1; 100255736Sdavidch } 101265917Sdavidcs if (non_zerop || (ptr[0] & 0x0F)) { 102255736Sdavidch *dst++ = xdigits[ptr[0] & 0x0F]; 103255736Sdavidch non_zerop = 1; 104255736Sdavidch } 105255736Sdavidch if (non_zerop || (ptr[1] >> 4)) { 106255736Sdavidch *dst++ = xdigits[ptr[1] >> 4]; 107265917Sdavidcs non_zerop = 1; 108255736Sdavidch } 109255736Sdavidch if (non_zerop || (ptr[1] & 0x0F)) { 110255736Sdavidch *dst++ = xdigits[ptr[1] & 0x0F]; 111255736Sdavidch non_zerop = 1; 112255736Sdavidch } 113265917Sdavidcs if (i != 7) 114255736Sdavidch *dst++ = ':'; 115255736Sdavidch ptr += 2; 116255736Sdavidch } 117255736Sdavidch *dst++ = '\0'; 118255736Sdavidch return orig_dst; 119265917Sdavidcs} 120255736Sdavidch#endif /* HAVE_IPV6 */ 121255736Sdavidch 122255736Sdavidchconst char * 123255736Sdavidchinet_ntop(int af, const void *src, char *dst, size_t size) 124255736Sdavidch{ 125265917Sdavidcs switch (af) { 126255736Sdavidch case AF_INET : 127255736Sdavidch return inet_ntop_v4 (src, dst, size); 128255736Sdavidch#ifdef HAVE_IPV6 129255736Sdavidch case AF_INET6 : 130255736Sdavidch return inet_ntop_v6 (src, dst, size); 131265917Sdavidcs#endif 132255736Sdavidch default : 133255736Sdavidch errno = EAFNOSUPPORT; 134255736Sdavidch return NULL; 135255736Sdavidch } 136255736Sdavidch} 137265917Sdavidcs