1 /* $NetBSD: sockaddr_snprintf.c,v 1.10 2013/06/07 17:23:26 christos Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 #if defined(LIBC_SCCS) && !defined(lint)
33 __RCSID("$NetBSD: sockaddr_snprintf.c,v 1.10 2013/06/07 17:23:26 christos Exp $");
34 #endif /* LIBC_SCCS and not lint */
36 #include <sys/types.h>
37 #include <sys/socket.h>
40 #include <netinet/in.h>
42 #include <netatalk/at.h>
43 #include <net/if_dl.h>
55 debug_at(char *str
, size_t len
, const struct sockaddr_at
*sat
)
57 return snprintf(str
, len
, "sat_len=%u, sat_family=%u, sat_port=%u, "
58 "sat_addr.s_net=%u, sat_addr.s_node=%u, "
59 "sat_range.r_netrange.nr_phase=%u, "
60 "sat_range.r_netrange.nr_firstnet=%u, "
61 "sat_range.r_netrange.nr_lastnet=%u",
62 sat
->sat_len
, sat
->sat_family
, sat
->sat_port
,
63 sat
->sat_addr
.s_net
, sat
->sat_addr
.s_node
,
64 sat
->sat_range
.r_netrange
.nr_phase
,
65 sat
->sat_range
.r_netrange
.nr_firstnet
,
66 sat
->sat_range
.r_netrange
.nr_lastnet
);
70 debug_in(char *str
, size_t len
, const struct sockaddr_in
*sin
)
72 return snprintf(str
, len
, "sin_len=%u, sin_family=%u, sin_port=%u, "
73 "sin_addr.s_addr=%08x",
74 sin
->sin_len
, sin
->sin_family
, sin
->sin_port
,
75 sin
->sin_addr
.s_addr
);
79 debug_in6(char *str
, size_t len
, const struct sockaddr_in6
*sin6
)
81 const uint8_t *s
= sin6
->sin6_addr
.s6_addr
;
83 return snprintf(str
, len
, "sin6_len=%u, sin6_family=%u, sin6_port=%u, "
85 "sin6_addr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
86 "%02x:%02x:%02x:%02x:%02x:%02x, sin6_scope_id=%u",
87 sin6
->sin6_len
, sin6
->sin6_family
, sin6
->sin6_port
,
88 sin6
->sin6_flowinfo
, s
[0x0], s
[0x1], s
[0x2], s
[0x3], s
[0x4], s
[0x5],
89 s
[0x6], s
[0x7], s
[0x8], s
[0x9], s
[0xa], s
[0xb], s
[0xc], s
[0xd],
90 s
[0xe], s
[0xf], sin6
->sin6_scope_id
);
94 debug_un(char *str
, size_t len
, const struct sockaddr_un
*sun
)
96 return snprintf(str
, len
, "sun_len=%u, sun_family=%u, sun_path=%*s",
97 sun
->sun_len
, sun
->sun_family
, (int)sizeof(sun
->sun_path
),
102 debug_dl(char *str
, size_t len
, const struct sockaddr_dl
*sdl
)
104 const uint8_t *s
= (const void *)sdl
->sdl_data
;
106 return snprintf(str
, len
, "sdl_len=%u, sdl_family=%u, sdl_index=%u, "
107 "sdl_type=%u, sdl_nlen=%u, sdl_alen=%u, sdl_slen=%u, sdl_data="
108 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
109 sdl
->sdl_len
, sdl
->sdl_family
, sdl
->sdl_index
,
110 sdl
->sdl_type
, sdl
->sdl_nlen
, sdl
->sdl_alen
, sdl
->sdl_slen
,
111 s
[0x0], s
[0x1], s
[0x2], s
[0x3], s
[0x4], s
[0x5],
112 s
[0x6], s
[0x7], s
[0x8], s
[0x9], s
[0xa], s
[0xb]);
114 #endif /* !defined(__minix) */
117 sockaddr_snprintf(char * const sbuf
, const size_t len
, const char * const fmt
,
118 const struct sockaddr
* const sa
)
120 const void *a
= NULL
;
121 #if !defined(__minix)
122 char abuf
[1024], nbuf
[1024], *addr
= NULL
, *w
= NULL
;
124 char abuf
[1024], nbuf
[1024], *addr
= NULL
;
125 #endif /* !defined(__minix) */
126 char Abuf
[1024], pbuf
[32], *name
= NULL
, *port
= NULL
;
127 char *ebuf
= &sbuf
[len
- 1], *buf
= sbuf
;
130 #if !defined(__minix)
131 const struct sockaddr_at
*sat
= NULL
;
132 #endif /* !defined(__minix) */
133 const struct sockaddr_in
*sin4
= NULL
;
134 #if !defined(__minix)
135 const struct sockaddr_in6
*sin6
= NULL
;
136 const struct sockaddr_un
*sun
= NULL
;
137 const struct sockaddr_dl
*sdl
= NULL
;
138 #endif /* !defined(__minix) */
141 #define ADDC(c) do { if (buf < ebuf) *buf++ = c; else buf++; } \
142 while (/*CONSTCOND*/0)
143 #define ADDS(p) do { for (s = p; *s; s++) ADDC(*s); } \
144 while (/*CONSTCOND*/0)
145 #define ADDNA() do { if (na) ADDS("N/A"); } \
146 while (/*CONSTCOND*/0)
148 switch (sa
->sa_family
) {
151 #if !defined(__minix)
153 sat
= ((const struct sockaddr_at
*)(const void *)sa
);
154 p
= ntohs(sat
->sat_port
);
155 (void)snprintf(addr
= abuf
, sizeof(abuf
), "%u.%u",
156 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
);
157 (void)snprintf(port
= pbuf
, sizeof(pbuf
), "%d", p
);
160 sun
= ((const struct sockaddr_un
*)(const void *)sa
);
161 (void)strlcpy(addr
= abuf
, sun
->sun_path
, SUN_LEN(sun
));
163 #endif /* !defined(__minix) */
165 sin4
= ((const struct sockaddr_in
*)(const void *)sa
);
166 p
= ntohs(sin4
->sin_port
);
169 #if !defined(__minix)
171 sin6
= ((const struct sockaddr_in6
*)(const void *)sa
);
172 p
= ntohs(sin6
->sin6_port
);
173 a
= &sin6
->sin6_addr
;
176 sdl
= ((const struct sockaddr_dl
*)(const void *)sa
);
177 (void)strlcpy(addr
= abuf
, link_ntoa(sdl
), sizeof(abuf
));
178 if ((w
= strchr(addr
, ':')) != 0) {
183 #endif /* !defined(__minix) */
185 errno
= EAFNOSUPPORT
;
192 #if !defined(__minix)
193 if (a
&& getnameinfo(sa
, (socklen_t
)sa
->sa_len
, addr
= abuf
,
195 if (a
&& getnameinfo(sa
, (socklen_t
)len
, addr
= abuf
,
196 #endif /* !defined(__minix) */
197 (unsigned int)sizeof(abuf
), NULL
, 0,
198 NI_NUMERICHOST
|NI_NUMERICSERV
) != 0)
201 for (ptr
= fmt
; *ptr
; ptr
++) {
216 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", p
);
222 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", sa
->sa_family
);
226 #if !defined(__minix)
227 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", sa
->sa_len
);
229 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", len
);
230 #endif /* !defined(__minix) */
239 #if !defined(__minix)
240 getnameinfo(sa
, (socklen_t
)sa
->sa_len
,
242 getnameinfo(sa
, (socklen_t
)len
,
243 #endif /* !defined(__minix) */
245 (unsigned int)sizeof(nbuf
), NULL
, 0, 0);
255 #if !defined(__minix)
256 getnameinfo(sa
, (socklen_t
)sa
->sa_len
, NULL
, 0,
258 getnameinfo(sa
, (socklen_t
)len
, NULL
, 0,
259 #endif /* !defined(__minix) */
261 (unsigned int)sizeof(pbuf
), 0);
265 #if !defined(__minix)
267 if (sdl
&& addr
!= abuf
) {
275 (void)snprintf(nbuf
, sizeof(nbuf
), "%d",
276 sin6
->sin6_flowinfo
);
285 (void)snprintf(nbuf
, sizeof(nbuf
), "%d",
286 sin6
->sin6_scope_id
);
295 const struct netrange
*n
=
296 &sat
->sat_range
.r_netrange
;
297 (void)snprintf(nbuf
, sizeof(nbuf
),
298 "%d:[%d,%d]", n
->nr_phase
, n
->nr_firstnet
,
306 switch (sa
->sa_family
) {
308 debug_at(nbuf
, sizeof(nbuf
), sat
);
311 debug_un(nbuf
, sizeof(nbuf
), sun
);
314 debug_in(nbuf
, sizeof(nbuf
), sin4
);
317 debug_in6(nbuf
, sizeof(nbuf
), sin6
);
320 debug_dl(nbuf
, sizeof(nbuf
), sdl
);
327 #endif /* !defined(__minix) */
345 sbuf
[len
- 1] = '\0';
346 return (int)(buf
- sbuf
);