t_sockaddr_snprintf.c revision 1.5 1 /* $NetBSD: t_sockaddr_snprintf.c,v 1.5 2025/09/14 17:20:32 christos Exp $ */
2
3 /*
4 * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code was contributed to The NetBSD Foundation by Christos Zoulas.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <sys/cdefs.h>
32 __COPYRIGHT("@(#) Copyright (c) 2008, 2010\
33 The NetBSD Foundation, inc. All rights reserved.");
34 __RCSID("$NetBSD: t_sockaddr_snprintf.c,v 1.5 2025/09/14 17:20:32 christos Exp $");
35
36 #include <stdio.h>
37 #include <sys/socket.h> /* AF_ */
38 #include <sys/un.h> /* sun */
39
40 #include <net/if_dl.h> /* sdl */
41 #include <netatalk/at.h> /* sat */
42 #include <netinet/in.h> /* sin/sin6 */
43
44 #include <netdb.h>
45 #include <string.h>
46 #include <util.h>
47
48 #include <atf-c.h>
49
50 static void
51 make_dl(struct sockaddr_dl *sdl)
52 {
53 memset(sdl, 0, sizeof(*sdl));
54 sdl->sdl_len = sizeof(*sdl);
55 sdl->sdl_family = AF_LINK;
56 sdl->sdl_index = 0;
57 sdl->sdl_type = 0;
58 sdl->sdl_nlen = 0;
59 sdl->sdl_alen = 6;
60 sdl->sdl_slen = 0;
61 memcpy(sdl->sdl_data, "\01\02\03\04\05\06", 6);
62 }
63
64 static void
65 make_in4(struct sockaddr_in *sin4)
66 {
67 memset(sin4, 0, sizeof(*sin4));
68 sin4->sin_len = sizeof(*sin4);
69 sin4->sin_family = AF_INET;
70 sin4->sin_port = ntohs(80);
71 sin4->sin_addr.s_addr = ntohl(INADDR_LOOPBACK);
72 }
73
74 #ifdef INET6
75 static void
76 make_in6(struct sockaddr_in6 *sin6)
77 {
78 memset(sin6, 0, sizeof(*sin6));
79 sin6->sin6_len = sizeof(*sin6);
80 sin6->sin6_family = AF_INET6;
81 sin6->sin6_port = ntohs(80);
82 sin6->sin6_addr = in6addr_nodelocal_allnodes;
83 }
84 #endif
85
86 static void
87 make_at(struct sockaddr_at *sat)
88 {
89 memset(sat, 0, sizeof(*sat));
90 sat->sat_len = sizeof(*sat);
91 sat->sat_family = AF_APPLETALK;
92 sat->sat_addr.s_net = ntohs(101);
93 sat->sat_addr.s_node = 3;
94 }
95
96 static void
97 make_un(struct sockaddr_un *sun)
98 {
99 memset(sun, 0, sizeof(*sun));
100 sun->sun_len = sizeof(*sun);
101 sun->sun_family = AF_UNIX;
102 strncpy(sun->sun_path, "/tmp/sock", sizeof(sun->sun_path));
103 }
104
105 ATF_TC(sockaddr_snprintf_in);
106 ATF_TC_HEAD(sockaddr_snprintf_in, tc)
107 {
108 atf_tc_set_md_var(tc, "descr",
109 "Checks sockaddr_snprintf(3) with sockaddr_in");
110 }
111 ATF_TC_BODY(sockaddr_snprintf_in, tc)
112 {
113 char buf[1024];
114 struct sockaddr_in sin4;
115 int i;
116
117 make_in4(&sin4);
118
119 i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a",
120 (struct sockaddr *)&sin4);
121
122 ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sin4");
123 ATF_REQUIRE_STREQ(buf, "2 16 80 127.0.0.1");
124 }
125
126 ATF_TC(sockaddr_snprintf_in6);
127 ATF_TC_HEAD(sockaddr_snprintf_in6, tc)
128 {
129 atf_tc_set_md_var(tc, "descr",
130 "Checks sockaddr_snprintf(3) with sockaddr_in6");
131 }
132 ATF_TC_BODY(sockaddr_snprintf_in6, tc)
133 {
134 #ifdef INET6
135 char buf[1024];
136 struct sockaddr_in6 sin6;
137 int i;
138
139 make_in6(&sin6);
140
141 i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a",
142 (struct sockaddr *)&sin6);
143
144 ATF_REQUIRE_EQ_MSG(i, 16, "bad length for sin6");
145 ATF_REQUIRE_STREQ(buf, "24 28 80 ff01::1");
146 #else
147 atf_tc_skip("Tests built with USE_INET6=no");
148 #endif /* INET6 */
149 }
150
151 ATF_TC(sockaddr_snprintf_un);
152 ATF_TC_HEAD(sockaddr_snprintf_un, tc)
153 {
154 atf_tc_set_md_var(tc, "descr",
155 "Checks sockaddr_snprintf(3) with sockaddr_un");
156 }
157 ATF_TC_BODY(sockaddr_snprintf_un, tc)
158 {
159 char buf[1024];
160 struct sockaddr_un sun;
161 int i;
162
163 make_un(&sun);
164
165 i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
166 (struct sockaddr *)&sun);
167
168 ATF_REQUIRE_EQ_MSG(i, 15, "bad length for sun");
169 ATF_REQUIRE_STREQ(buf, "1 106 /tmp/sock");
170 }
171
172 ATF_TC(sockaddr_snprintf_at);
173 ATF_TC_HEAD(sockaddr_snprintf_at, tc)
174 {
175 atf_tc_set_md_var(tc, "descr",
176 "Checks sockaddr_snprintf(3) with sockaddr_at");
177 }
178 ATF_TC_BODY(sockaddr_snprintf_at, tc)
179 {
180 char buf[1024];
181 struct sockaddr_at sat;
182 int i;
183
184 make_at(&sat);
185
186 i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
187 (struct sockaddr *)&sat);
188
189 ATF_REQUIRE_EQ_MSG(i, 11, "bad length for sat");
190 ATF_REQUIRE_STREQ(buf, "16 16 101.3");
191 }
192
193 ATF_TC(sockaddr_snprintf_dl);
194 ATF_TC_HEAD(sockaddr_snprintf_dl, tc)
195 {
196 atf_tc_set_md_var(tc, "descr",
197 "Checks sockaddr_snprintf(3) with sockaddr_dl");
198 }
199 ATF_TC_BODY(sockaddr_snprintf_dl, tc)
200 {
201 char buf[1024];
202 struct sockaddr_dl sdl;
203 int i;
204
205 make_dl(&sdl);
206
207 i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
208 (struct sockaddr *)&sdl);
209
210 ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sdl");
211 ATF_REQUIRE_STREQ(buf, "18 32 1.2.3.4.5.6");
212 }
213
214
215 ATF_TC(sockaddr_snprintf_generic);
216 ATF_TC_HEAD(sockaddr_snprintf_generic, tc)
217 {
218 atf_tc_set_md_var(tc, "descr",
219 "Checks sockaddr_snprintf(3) with generic args");
220 }
221 ATF_TC_BODY(sockaddr_snprintf_generic, tc)
222 {
223 char buf[1024];
224 struct sockaddr_at sat;
225 struct sockaddr_dl sdl;
226 struct sockaddr_un sun;
227 struct sockaddr_in sin4;
228 struct sockaddr_in6 sin6;
229 struct addrinfo *res;
230 int i;
231
232
233 #define CHECK(a, b) \
234 ATF_REQUIRE_EQ_MSG(i, (a), "bad length"); \
235 ATF_REQUIRE_STREQ(buf, (b))
236
237 make_dl(&sdl);
238 i = sockaddr_snprintf(buf, sizeof(buf), "%n",
239 (struct sockaddr *)&sdl);
240 CHECK(11, "1.2.3.4.5.6");
241
242 make_in6(&sin6);
243 i = sockaddr_snprintf(buf, sizeof(buf), "%n",
244 (struct sockaddr *)&sin6);
245 CHECK(12, "[ff01::1]:80");
246
247 make_in4(&sin4);
248 i = sockaddr_snprintf(buf, sizeof(buf), "%n",
249 (struct sockaddr *)&sin4);
250 CHECK(12, "127.0.0.1:80");
251
252 make_at(&sat);
253 i = sockaddr_snprintf(buf, sizeof(buf), "%n",
254 (struct sockaddr *)&sat);
255 CHECK(7, "101.3:0");
256
257 make_un(&sun);
258 i = sockaddr_snprintf(buf, sizeof(buf), "%n",
259 (struct sockaddr *)&sun);
260 CHECK(9, "/tmp/sock");
261
262 if (getaddrinfo("morden.netbsd.org", "https", NULL, &res) == 0) {
263 for (struct addrinfo *ai = res; ai; ai = ai->ai_next) {
264 i = sockaddr_snprintf(buf, sizeof(buf), "%N",
265 ai->ai_addr);
266 if (strcmp(buf, "morden.netbsd.org:https") == 0 ||
267 strcmp(buf, "ftp.NetBSD.org:https") == 0)
268 continue;
269 fprintf(stderr, "Unexpected %s\n", buf);
270 }
271 freeaddrinfo(res);
272 }
273 }
274
275 ATF_TP_ADD_TCS(tp)
276 {
277
278 ATF_TP_ADD_TC(tp, sockaddr_snprintf_in);
279 ATF_TP_ADD_TC(tp, sockaddr_snprintf_in6);
280 ATF_TP_ADD_TC(tp, sockaddr_snprintf_un);
281 ATF_TP_ADD_TC(tp, sockaddr_snprintf_at);
282 ATF_TP_ADD_TC(tp, sockaddr_snprintf_dl);
283 ATF_TP_ADD_TC(tp, sockaddr_snprintf_generic);
284
285 return atf_no_error();
286 }
287