]> git.saurik.com Git - apple/xnu.git/blob - bsd/libkern/inet_ntop.c
a41cd2ba9e12d42bd129c8d5d2ba389970779f26
[apple/xnu.git] / bsd / libkern / inet_ntop.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Copyright 1994, 1995 Massachusetts Institute of Technology
26 *
27 * Permission to use, copy, modify, and distribute this software and
28 * its documentation for any purpose and without fee is hereby
29 * granted, provided that both the above copyright notice and this
30 * permission notice appear in all copies, that both the above
31 * copyright notice and this permission notice appear in all
32 * supporting documentation, and that the name of M.I.T. not be used
33 * in advertising or publicity pertaining to distribution of the
34 * software without specific, written prior permission. M.I.T. makes
35 * no representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied
37 * warranty.
38 *
39 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
40 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
43 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 */
52
53 #include <sys/param.h>
54 #include <sys/systm.h>
55
56 #include <netinet/in.h>
57
58 static const char *hexchars = "0123456789abcdef";
59
60 static const char *
61 inet_ntop4(const struct in_addr *addr, char *buf, size_t len)
62 {
63 const u_int8_t *ap = (const u_int8_t *)&addr->s_addr;
64 char tmp[MAX_IPv4_STR_LEN]; /* max length of ipv4 addr string */
65 int fulllen;
66
67 /*
68 * snprintf returns number of bytes printed (not including NULL) or
69 * number of bytes that would have been printed if more than would
70 * fit
71 */
72 fulllen = snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
73 ap[0], ap[1], ap[2], ap[3]);
74 if (fulllen >= (int)len) {
75 return NULL;
76 }
77
78 bcopy(tmp, buf, fulllen + 1);
79
80 return buf;
81 }
82
83 static const char *
84 inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
85 {
86 char hexa[8][5], tmp[MAX_IPv6_STR_LEN];
87 int zr[8];
88 size_t len;
89 int32_t i, j, k, skip;
90 uint8_t x8, hx8;
91 uint16_t x16;
92 struct in_addr a4;
93
94 if (addr == NULL) return NULL;
95
96 bzero(tmp, sizeof(tmp));
97
98 /* check for mapped or compat addresses */
99 i = IN6_IS_ADDR_V4MAPPED(addr);
100 j = IN6_IS_ADDR_V4COMPAT(addr);
101 if ((i != 0) || (j != 0))
102 {
103 char tmp2[16]; /* max length of ipv4 addr string */
104 a4.s_addr = addr->__u6_addr.__u6_addr32[3];
105 len = snprintf(tmp, sizeof(tmp), "::%s%s", (i != 0) ? "ffff:" : "",
106 inet_ntop4(&a4, tmp2, sizeof(tmp2)));
107 if (len >= size) return NULL;
108 bcopy(tmp, dst, len + 1);
109 return dst;
110 }
111
112 k = 0;
113 for (i = 0; i < 16; i += 2)
114 {
115 j = 0;
116 skip = 1;
117
118 bzero(hexa[k], 5);
119
120 x8 = addr->__u6_addr.__u6_addr8[i];
121
122 hx8 = x8 >> 4;
123 if (hx8 != 0)
124 {
125 skip = 0;
126 hexa[k][j++] = hexchars[hx8];
127 }
128
129 hx8 = x8 & 0x0f;
130 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
131 {
132 skip = 0;
133 hexa[k][j++] = hexchars[hx8];
134 }
135
136 x8 = addr->__u6_addr.__u6_addr8[i + 1];
137
138 hx8 = x8 >> 4;
139 if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
140 {
141 hexa[k][j++] = hexchars[hx8];
142 }
143
144 hx8 = x8 & 0x0f;
145 hexa[k][j++] = hexchars[hx8];
146
147 k++;
148 }
149
150 /* find runs of zeros for :: convention */
151 j = 0;
152 for (i = 7; i >= 0; i--)
153 {
154 zr[i] = j;
155 x16 = addr->__u6_addr.__u6_addr16[i];
156 if (x16 == 0) j++;
157 else j = 0;
158 zr[i] = j;
159 }
160
161 /* find longest run of zeros */
162 k = -1;
163 j = 0;
164 for(i = 0; i < 8; i++)
165 {
166 if (zr[i] > j)
167 {
168 k = i;
169 j = zr[i];
170 }
171 }
172
173 for(i = 0; i < 8; i++)
174 {
175 if (i != k) zr[i] = 0;
176 }
177
178 len = 0;
179 for (i = 0; i < 8; i++)
180 {
181 if (zr[i] != 0)
182 {
183 /* check for leading zero */
184 if (i == 0) tmp[len++] = ':';
185 tmp[len++] = ':';
186 i += (zr[i] - 1);
187 continue;
188 }
189 for (j = 0; hexa[i][j] != '\0'; j++) tmp[len++] = hexa[i][j];
190 if (i != 7) tmp[len++] = ':';
191 }
192
193 /* trailing NULL */
194 len++;
195
196 if (len > size) return NULL;
197 bcopy(tmp, dst, len);
198 return dst;
199 }
200
201 const char *
202 inet_ntop(int af, const void *addr, char *buf, size_t len)
203 {
204 if(af==AF_INET6)
205 return inet_ntop6(addr, buf, len);
206 if(af==AF_INET)
207 return inet_ntop4(addr, buf, len);
208 return NULL;
209 }