]>
git.saurik.com Git - apple/libc.git/blob - net/inet_ntop.c
a5ad5c60f7c6f453c2f619bfbb2f7a9a842ce752
2 * Copyright (c) 2003,2005,2006,2011,2012 Apple, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
31 #include <sys/socket.h>
33 #define MAX_V4_ADDR_LEN 16
34 #define MAX_V6_ADDR_LEN 64
36 static const char *hexchars
= "0123456789abcdef";
38 const char * inet_ntop6(const struct in6_addr
*addr
, char *dst
, socklen_t size
);
39 const char * inet_ntop4(const struct in_addr
*addr
, char *dst
, socklen_t size
);
42 inet_ntop(int af
, const void *addr
, char *buf
, socklen_t len
)
44 if (af
== AF_INET6
) return inet_ntop6(addr
, buf
, len
);
45 if (af
== AF_INET
) return inet_ntop4(addr
, buf
, len
);
52 inet_ntop6(const struct in6_addr
*addr
, char *dst
, socklen_t size
)
54 char hexa
[8][5], tmp
[MAX_V6_ADDR_LEN
];
57 int32_t i
, j
, k
, skip
;
74 memset(tmp
, 0, MAX_V6_ADDR_LEN
);
76 /* check for mapped or compat addresses */
77 i
= IN6_IS_ADDR_V4MAPPED(addr
);
78 j
= IN6_IS_ADDR_V4COMPAT(addr
);
79 if ((i
!= 0) || (j
!= 0))
90 a4
.s_addr
= addr
->__u6_addr
.__u6_addr32
[3];
91 inet_ntop4(&a4
, tmp
, sizeof(tmp
));
92 len
= strlen(tmp
) + 1;
93 if (prefix_len
+ len
> size
)
99 memcpy(dst
, prefix
, prefix_len
);
100 memcpy(dst
+ prefix_len
, tmp
, len
);
105 for (i
= 0; i
< 16; i
+= 2)
110 memset(hexa
[k
], 0, 5);
112 x8
= addr
->__u6_addr
.__u6_addr8
[i
];
118 hexa
[k
][j
++] = hexchars
[hx8
];
122 if ((skip
== 0) || ((skip
== 1) && (hx8
!= 0)))
125 hexa
[k
][j
++] = hexchars
[hx8
];
128 x8
= addr
->__u6_addr
.__u6_addr8
[i
+ 1];
131 if ((skip
== 0) || ((skip
== 1) && (hx8
!= 0)))
133 hexa
[k
][j
++] = hexchars
[hx8
];
137 hexa
[k
][j
++] = hexchars
[hx8
];
142 /* find runs of zeros for :: convention */
144 for (i
= 7; i
>= 0; i
--)
147 x16
= addr
->__u6_addr
.__u6_addr16
[i
];
153 /* find longest run of zeros */
156 for(i
= 0; i
< 8; i
++)
165 for(i
= 0; i
< 8; i
++)
167 if (i
!= k
) zr
[i
] = 0;
171 for (i
= 0; i
< 8; i
++)
175 /* check for leading zero */
176 if (i
== 0) tmp
[len
++] = ':';
181 for (j
= 0; hexa
[i
][j
] != '\0'; j
++) tmp
[len
++] = hexa
[i
][j
];
182 if (i
!= 7) tmp
[len
++] = ':';
194 memcpy(dst
, tmp
, len
);
199 inet_ntop4(const struct in_addr
*addr
, char *dst
, socklen_t size
)
201 char tmp
[MAX_V4_ADDR_LEN
], *p
;
202 const u_int8_t
*ap
= (u_int8_t
*)&addr
->s_addr
;
207 errno
= EAFNOSUPPORT
;
217 memset(tmp
, 0, MAX_V4_ADDR_LEN
);
219 /* 3 dots, trailing nul */
224 for (i
= 0; i
< 4; i
++, ap
++)
226 snprintf(p
, 4, "%d", *ap
);
230 if (i
< 3) *p
++ = '.';
239 memcpy(dst
, tmp
, len
);