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