1 /* $NetBSD: sockaddr_snprintf.c,v 1.11 2013/12/31 12:58:02 mlelstv 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.11 2013/12/31 12:58:02 mlelstv Exp $");
34 #endif /* LIBC_SCCS and not lint */
36 #include <sys/types.h>
37 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <netatalk/at.h>
42 #include <net/if_dl.h>
52 debug_at(char *str
, size_t len
, const struct sockaddr_at
*sat
)
54 return snprintf(str
, len
, "sat_len=%u, sat_family=%u, sat_port=%u, "
55 "sat_addr.s_net=%u, sat_addr.s_node=%u, "
56 "sat_range.r_netrange.nr_phase=%u, "
57 "sat_range.r_netrange.nr_firstnet=%u, "
58 "sat_range.r_netrange.nr_lastnet=%u",
59 sat
->sat_len
, sat
->sat_family
, sat
->sat_port
,
60 sat
->sat_addr
.s_net
, sat
->sat_addr
.s_node
,
61 sat
->sat_range
.r_netrange
.nr_phase
,
62 sat
->sat_range
.r_netrange
.nr_firstnet
,
63 sat
->sat_range
.r_netrange
.nr_lastnet
);
67 debug_in(char *str
, size_t len
, const struct sockaddr_in
*sin
)
69 return snprintf(str
, len
, "sin_len=%u, sin_family=%u, sin_port=%u, "
70 "sin_addr.s_addr=%08x",
71 sin
->sin_len
, sin
->sin_family
, sin
->sin_port
,
72 sin
->sin_addr
.s_addr
);
76 debug_in6(char *str
, size_t len
, const struct sockaddr_in6
*sin6
)
78 const uint8_t *s
= sin6
->sin6_addr
.s6_addr
;
80 return snprintf(str
, len
, "sin6_len=%u, sin6_family=%u, sin6_port=%u, "
82 "sin6_addr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
83 "%02x:%02x:%02x:%02x:%02x:%02x, sin6_scope_id=%u",
84 sin6
->sin6_len
, sin6
->sin6_family
, sin6
->sin6_port
,
85 sin6
->sin6_flowinfo
, s
[0x0], s
[0x1], s
[0x2], s
[0x3], s
[0x4], s
[0x5],
86 s
[0x6], s
[0x7], s
[0x8], s
[0x9], s
[0xa], s
[0xb], s
[0xc], s
[0xd],
87 s
[0xe], s
[0xf], sin6
->sin6_scope_id
);
91 debug_un(char *str
, size_t len
, const struct sockaddr_un
*sun
)
93 return snprintf(str
, len
, "sun_len=%u, sun_family=%u, sun_path=%*s",
94 sun
->sun_len
, sun
->sun_family
, (int)sizeof(sun
->sun_path
),
99 debug_dl(char *str
, size_t len
, const struct sockaddr_dl
*sdl
)
101 const uint8_t *s
= (const void *)sdl
->sdl_data
;
103 return snprintf(str
, len
, "sdl_len=%u, sdl_family=%u, sdl_index=%u, "
104 "sdl_type=%u, sdl_nlen=%u, sdl_alen=%u, sdl_slen=%u, sdl_data="
105 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
106 sdl
->sdl_len
, sdl
->sdl_family
, sdl
->sdl_index
,
107 sdl
->sdl_type
, sdl
->sdl_nlen
, sdl
->sdl_alen
, sdl
->sdl_slen
,
108 s
[0x0], s
[0x1], s
[0x2], s
[0x3], s
[0x4], s
[0x5],
109 s
[0x6], s
[0x7], s
[0x8], s
[0x9], s
[0xa], s
[0xb]);
113 sockaddr_snprintf(char * const sbuf
, const size_t len
, const char * const fmt
,
114 const struct sockaddr
* const sa
)
116 const void *a
= NULL
;
117 char abuf
[1024], nbuf
[1024], *addr
= NULL
, *w
= NULL
;
118 char Abuf
[1024], pbuf
[32], *name
= NULL
, *port
= NULL
;
119 char *ebuf
= &sbuf
[len
- 1], *buf
= sbuf
;
122 const struct sockaddr_at
*sat
= NULL
;
123 const struct sockaddr_in
*sin4
= NULL
;
124 const struct sockaddr_in6
*sin6
= NULL
;
125 const struct sockaddr_un
*sun
= NULL
;
126 const struct sockaddr_dl
*sdl
= NULL
;
129 #define ADDC(c) do { if (buf < ebuf) *buf++ = c; else buf++; } \
130 while (/*CONSTCOND*/0)
131 #define ADDS(p) do { for (s = p; *s; s++) ADDC(*s); } \
132 while (/*CONSTCOND*/0)
133 #define ADDNA() do { if (na) ADDS("N/A"); } \
134 while (/*CONSTCOND*/0)
136 switch (sa
->sa_family
) {
140 sat
= ((const struct sockaddr_at
*)(const void *)sa
);
141 p
= ntohs(sat
->sat_port
);
142 (void)snprintf(addr
= abuf
, sizeof(abuf
), "%u.%u",
143 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
);
144 (void)snprintf(port
= pbuf
, sizeof(pbuf
), "%d", p
);
147 sun
= ((const struct sockaddr_un
*)(const void *)sa
);
148 (void)strlcpy(addr
= abuf
, sun
->sun_path
, sizeof(abuf
));
151 sin4
= ((const struct sockaddr_in
*)(const void *)sa
);
152 p
= ntohs(sin4
->sin_port
);
156 sin6
= ((const struct sockaddr_in6
*)(const void *)sa
);
157 p
= ntohs(sin6
->sin6_port
);
158 a
= &sin6
->sin6_addr
;
161 sdl
= ((const struct sockaddr_dl
*)(const void *)sa
);
162 (void)strlcpy(addr
= abuf
, link_ntoa(sdl
), sizeof(abuf
));
163 if ((w
= strchr(addr
, ':')) != 0) {
169 errno
= EAFNOSUPPORT
;
176 if (a
&& getnameinfo(sa
, (socklen_t
)sa
->sa_len
, addr
= abuf
,
177 (unsigned int)sizeof(abuf
), NULL
, 0,
178 NI_NUMERICHOST
|NI_NUMERICSERV
) != 0)
181 for (ptr
= fmt
; *ptr
; ptr
++) {
196 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", p
);
202 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", sa
->sa_family
);
206 (void)snprintf(nbuf
, sizeof(nbuf
), "%d", sa
->sa_len
);
215 getnameinfo(sa
, (socklen_t
)sa
->sa_len
,
217 (unsigned int)sizeof(nbuf
), NULL
, 0, 0);
227 getnameinfo(sa
, (socklen_t
)sa
->sa_len
, NULL
, 0,
229 (unsigned int)sizeof(pbuf
), 0);
234 if (sdl
&& addr
!= abuf
) {
242 (void)snprintf(nbuf
, sizeof(nbuf
), "%d",
243 sin6
->sin6_flowinfo
);
252 (void)snprintf(nbuf
, sizeof(nbuf
), "%d",
253 sin6
->sin6_scope_id
);
262 const struct netrange
*n
=
263 &sat
->sat_range
.r_netrange
;
264 (void)snprintf(nbuf
, sizeof(nbuf
),
265 "%d:[%d,%d]", n
->nr_phase
, n
->nr_firstnet
,
273 switch (sa
->sa_family
) {
275 debug_at(nbuf
, sizeof(nbuf
), sat
);
278 debug_un(nbuf
, sizeof(nbuf
), sun
);
281 debug_in(nbuf
, sizeof(nbuf
), sin4
);
284 debug_in6(nbuf
, sizeof(nbuf
), sin6
);
287 debug_dl(nbuf
, sizeof(nbuf
), sdl
);
311 sbuf
[len
- 1] = '\0';
312 return (int)(buf
- sbuf
);