]> granicus.if.org Git - strace/blob - tests/net-sockaddr.c
tests: extend TEST_NETLINK_OBJECT macro
[strace] / tests / net-sockaddr.c
1 /*
2  * Check decoding of sockaddr structures
3  *
4  * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2016-2017 The strace developers.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "tests.h"
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include "netlink.h"
41 #include <linux/if_arp.h>
42 #include <linux/if_ether.h>
43 #include <linux/if_packet.h>
44 #include <linux/ipx.h>
45 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
46 # include <bluetooth/bluetooth.h>
47 # include <bluetooth/hci.h>
48 # include <bluetooth/l2cap.h>
49 # include <bluetooth/rfcomm.h>
50 # include <bluetooth/sco.h>
51 #endif
52
53 #ifdef HAVE_IF_INDEXTONAME
54 /* <linux/if.h> used to conflict with <net/if.h> */
55 extern unsigned int if_nametoindex(const char *);
56 #endif
57
58 static void
59 check_un(void)
60 {
61         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_un, un);
62         un->sun_family = AF_UNIX;
63         memset(un->sun_path, '0', sizeof(un->sun_path));
64         unsigned int len = sizeof(*un);
65         int ret = connect(-1, (void *) un, len);
66         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
67                ", %u) = %d EBADF (%m)\n",
68                (int) sizeof(un->sun_path), 0, len, ret);
69
70         un->sun_path[1] = 0;
71         ret = connect(-1, (void *) un, len);
72         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
73                " = %d EBADF (%m)\n", 0, len, ret);
74
75         un->sun_path[0] = 0;
76         un->sun_path[2] = 1;
77         ret = connect(-1, (void *) un, len);
78         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
79                ", %u) = %d EBADF (%m)\n",
80                (int) sizeof(un->sun_path) - 3, 0, len, ret);
81
82         un = ((void *) un) - 2;
83         un->sun_family = AF_UNIX;
84         memset(un->sun_path, '0', sizeof(un->sun_path));
85         len = sizeof(*un) + 2;
86         ret = connect(-1, (void *) un, len);
87         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
88                ", %u) = %d EBADF (%m)\n",
89                (int) sizeof(un->sun_path), 0, len, ret);
90
91         un->sun_path[0] = 0;
92         ret = connect(-1, (void *) un, len);
93         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
94                ", %u) = %d EBADF (%m)\n",
95                (int) sizeof(un->sun_path) - 1, 0, len, ret);
96
97         un = ((void *) un) + 4;
98         un->sun_family = AF_UNIX;
99         len = sizeof(*un) - 2;
100         ret = connect(-1, (void *) un, len);
101         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
102                ", %u) = %d EBADF (%m)\n",
103                (int) sizeof(un->sun_path) - 2, 0, len, ret);
104
105         un->sun_path[0] = 0;
106         ret = connect(-1, (void *) un, len);
107         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
108                ", %u) = %d EBADF (%m)\n",
109                (int) sizeof(un->sun_path) - 3, 0, len, ret);
110
111         len = sizeof(*un);
112         ret = connect(-1, (void *) un, len);
113         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
114
115         un = tail_alloc(sizeof(struct sockaddr_storage));
116         un->sun_family = AF_UNIX;
117         memset(un->sun_path, '0', sizeof(un->sun_path));
118         len = sizeof(struct sockaddr_storage) + 1;
119         ret = connect(-1, (void *) un, len);
120         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
121                ", %u) = %d EBADF (%m)\n",
122                (int) sizeof(un->sun_path), 0, len, ret);
123
124         un->sun_path[0] = 0;
125         ret = connect(-1, (void *) un, len);
126         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
127                ", %u) = %d EBADF (%m)\n",
128                (int) sizeof(un->sun_path) - 1, 0, len, ret);
129 }
130
131 static void
132 check_in(void)
133 {
134         const unsigned short h_port = 12345;
135         static const char h_addr[] = "12.34.56.78";
136
137         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in, in);
138         in->sin_family = AF_INET;
139         in->sin_port = htons(h_port);
140         in->sin_addr.s_addr = inet_addr(h_addr);
141         unsigned int len = sizeof(*in);
142         int ret = connect(-1, (void *) in, len);
143         printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
144                ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
145                h_port, h_addr, len, ret);
146
147         in = ((void *) in) - 4;
148         in->sin_family = AF_INET;
149         in->sin_port = htons(h_port);
150         in->sin_addr.s_addr = inet_addr(h_addr);
151         len = sizeof(*in) + 4;
152         ret = connect(-1, (void *) in, len);
153         printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
154                ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
155                h_port, h_addr, len, ret);
156
157         in = ((void *) in) + 8;
158         in->sin_family = AF_INET;
159         in->sin_port = 0;
160         in->sin_addr.s_addr = 0;
161         len = sizeof(*in) - 4;
162         ret = connect(-1, (void *) in, len);
163         printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
164                " = %d EBADF (%m)\n",
165                "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
166                len, ret);
167
168         len = sizeof(*in);
169         ret = connect(-1, (void *) in, len);
170         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
171 }
172
173 static void
174 check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
175 {
176         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
177
178         in6->sin6_scope_id = 0xfacefeed;
179         unsigned int len = sizeof(*in6);
180         int ret = connect(-1, (void *) in6, len);
181         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
182                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
183                ", sin6_flowinfo=htonl(%u)"
184                ", sin6_scope_id=%u}, %u)"
185                " = %d EBADF (%m)\n",
186                ntohs(in6->sin6_port), h_addr,
187                ntohl(in6->sin6_flowinfo), in6->sin6_scope_id, len, ret);
188
189 #ifdef HAVE_IF_INDEXTONAME
190         in6->sin6_scope_id = if_nametoindex("lo");
191         if (in6->sin6_scope_id) {
192                 ret = connect(-1, (void *) in6, len);
193                 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
194                        ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
195                        ", sin6_flowinfo=htonl(%u)"
196                        ", sin6_scope_id=if_nametoindex(\"lo\")}, %u)"
197                        " = %d EBADF (%m)\n",
198                        ntohs(in6->sin6_port), h_addr,
199                        ntohl(in6->sin6_flowinfo), len, ret);
200         }
201 #endif
202 }
203
204 static void
205 check_in6(void)
206 {
207         const unsigned short h_port = 12345;
208         const unsigned int h_flowinfo = 1234567890;
209         static const char h_addr[] = "12:34:56:78:90:ab:cd:ef";
210
211         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in6, in6);
212         in6->sin6_family = AF_INET6;
213         in6->sin6_port = htons(h_port);
214         in6->sin6_flowinfo = htonl(h_flowinfo);
215         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
216         in6->sin6_scope_id = 0xfacefeed;
217         unsigned int len = sizeof(*in6);
218         int ret = connect(-1, (void *) in6, len);
219         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
220                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
221                ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
222                " = %d EBADF (%m)\n",
223                h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
224
225         check_in6_linklocal(in6, "fe80::");
226         check_in6_linklocal(in6, "ff42::");
227
228         in6 = ((void *) in6) - 4;
229         in6->sin6_family = AF_INET6;
230         in6->sin6_port = htons(h_port);
231         in6->sin6_flowinfo = htonl(h_flowinfo);
232         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
233         in6->sin6_scope_id = 0xfacefeed;
234         len = sizeof(*in6) + 4;
235         ret = connect(-1, (void *) in6, len);
236         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
237                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
238                ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
239                " = %d EBADF (%m)\n",
240                h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
241
242         in6 = ((void *) in6) + 4 + sizeof(in6->sin6_scope_id);
243         in6->sin6_family = AF_INET6;
244         in6->sin6_port = htons(h_port);
245         in6->sin6_flowinfo = htonl(h_flowinfo);
246         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
247         len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
248         ret = connect(-1, (void *) in6, len);
249         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
250                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
251                ", sin6_flowinfo=htonl(%u)}, %u)"
252                " = %d EBADF (%m)\n",
253                h_port, h_addr, h_flowinfo, len, ret);
254
255         in6 = ((void *) in6) + 4;
256         in6->sin6_family = AF_INET6;
257         in6->sin6_port = 0;
258         in6->sin6_flowinfo = 0;
259         memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
260         len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
261         ret = connect(-1, (void *) in6, len);
262         printf("connect(-1, {sa_family=AF_INET6"
263                ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
264                " = %d EBADF (%m)\n",
265                (int) (len - offsetof(struct sockaddr_in6, sin6_addr)), 0,
266                len, ret);
267
268         len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
269         ret = connect(-1, (void *) in6, len);
270         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
271 }
272
273 static void
274 check_ipx(void)
275 {
276         const unsigned short h_port = 12345;
277         const unsigned int h_network = 0xfacefeed;
278         struct sockaddr_ipx c_ipx = {
279                 .sipx_family = AF_IPX,
280                 .sipx_port = htons(h_port),
281                 .sipx_network = htonl(h_network),
282                 .sipx_node = "ABCDEF",
283                 .sipx_type = -1
284         };
285         void *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
286         unsigned int len = sizeof(c_ipx);
287         int ret = connect(-1, ipx, len);
288         printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
289                ", sipx_network=htonl(%#x)"
290                ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
291                ", sipx_type=%#02x}, %u) = %d EBADF (%m)\n",
292                h_port, h_network,
293                c_ipx.sipx_node[0], c_ipx.sipx_node[1],
294                c_ipx.sipx_node[2], c_ipx.sipx_node[3],
295                c_ipx.sipx_node[4], c_ipx.sipx_node[5],
296                c_ipx.sipx_type, len, ret);
297 }
298
299 static void
300 check_nl(void)
301 {
302         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_nl, nl);
303         nl->nl_family = AF_NETLINK;
304         nl->nl_pid = 1234567890;
305         nl->nl_groups = 0xfacefeed;
306         unsigned int len = sizeof(*nl);
307         int ret = connect(-1, (void *) nl, len);
308         printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
309                ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
310                nl->nl_pid, nl->nl_groups, len, ret);
311
312         nl = ((void *) nl) - 4;
313         nl->nl_family = AF_NETLINK;
314         nl->nl_pid = 1234567890;
315         nl->nl_groups = 0xfacefeed;
316         len = sizeof(*nl) + 4;
317         ret = connect(-1, (void *) nl, len);
318         printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
319                ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
320                nl->nl_pid, nl->nl_groups, len, ret);
321 }
322
323 static void
324 check_ll(void)
325 {
326         struct sockaddr_ll c_ll = {
327                 .sll_family = AF_PACKET,
328                 .sll_protocol = htons(ETH_P_ALL),
329                 .sll_ifindex = 0xfacefeed,
330                 .sll_hatype = ARPHRD_ETHER,
331                 .sll_pkttype = PACKET_HOST,
332                 .sll_halen = sizeof(c_ll.sll_addr),
333                 .sll_addr = "abcdefgh"
334         };
335         void *ll = tail_memdup(&c_ll, sizeof(c_ll));
336         unsigned int len = sizeof(c_ll);
337         int ret = connect(-1, ll, len);
338         printf("connect(-1, {sa_family=AF_PACKET"
339                ", sll_protocol=htons(ETH_P_ALL)"
340                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
341                ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
342                "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
343                "}, %u) = %d EBADF (%m)\n",
344                c_ll.sll_ifindex, c_ll.sll_halen,
345                c_ll.sll_addr[0], c_ll.sll_addr[1],
346                c_ll.sll_addr[2], c_ll.sll_addr[3],
347                c_ll.sll_addr[4], c_ll.sll_addr[5],
348                c_ll.sll_addr[6], c_ll.sll_addr[7],
349                len, ret);
350
351         ((struct sockaddr_ll *) ll)->sll_halen++;
352         ret = connect(-1, ll, len);
353         printf("connect(-1, {sa_family=AF_PACKET"
354                ", sll_protocol=htons(ETH_P_ALL)"
355                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
356                ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
357                "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, ...]"
358                "}, %u) = %d EBADF (%m)\n",
359                c_ll.sll_ifindex, c_ll.sll_halen + 1,
360                c_ll.sll_addr[0], c_ll.sll_addr[1],
361                c_ll.sll_addr[2], c_ll.sll_addr[3],
362                c_ll.sll_addr[4], c_ll.sll_addr[5],
363                c_ll.sll_addr[6], c_ll.sll_addr[7],
364                len, ret);
365
366         ((struct sockaddr_ll *) ll)->sll_halen = 0;
367         ret = connect(-1, ll, len);
368         printf("connect(-1, {sa_family=AF_PACKET"
369                ", sll_protocol=htons(ETH_P_ALL)"
370                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
371                ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
372                " = %d EBADF (%m)\n", c_ll.sll_ifindex, len, ret);
373
374 #ifdef HAVE_IF_INDEXTONAME
375         const int id = if_nametoindex("lo");
376         if (id) {
377                 ((struct sockaddr_ll *) ll)->sll_ifindex = id;
378                 ret = connect(-1, ll, len);
379                 printf("connect(-1, {sa_family=AF_PACKET"
380                        ", sll_protocol=htons(ETH_P_ALL)"
381                        ", sll_ifindex=if_nametoindex(\"lo\")"
382                        ", sll_hatype=ARPHRD_ETHER"
383                        ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
384                        " = %d EBADF (%m)\n", len, ret);
385         }
386 #endif
387 }
388
389 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
390 static void
391 check_hci(void)
392 {
393         const unsigned short h_port = 12345;
394         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
395         hci->hci_family = AF_BLUETOOTH;
396         hci->hci_dev = htobs(h_port);
397         hci->hci_channel = HCI_CHANNEL_RAW;
398         unsigned int len = sizeof(*hci);
399         int ret = connect(-1, (void *) hci, len);
400         printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
401                ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
402                h_port, len, ret);
403 }
404
405 static void
406 check_sco(void)
407 {
408         const struct sockaddr_sco c_sco = {
409                 .sco_family = AF_BLUETOOTH,
410                 .sco_bdaddr.b = "abcdef"
411         };
412         void *sco = tail_memdup(&c_sco, sizeof(c_sco));
413         unsigned int len = sizeof(c_sco);
414         int ret = connect(-1, sco, len);
415         printf("connect(-1, {sa_family=AF_BLUETOOTH"
416                ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
417                "}, %u) = %d EBADF (%m)\n",
418                c_sco.sco_bdaddr.b[0], c_sco.sco_bdaddr.b[1],
419                c_sco.sco_bdaddr.b[2], c_sco.sco_bdaddr.b[3],
420                c_sco.sco_bdaddr.b[4], c_sco.sco_bdaddr.b[5],
421                len, ret);
422 }
423
424 static void
425 check_rc(void)
426 {
427         const struct sockaddr_rc c_rc = {
428                 .rc_family = AF_BLUETOOTH,
429                 .rc_bdaddr.b = "abcdef",
430                 .rc_channel = 42
431         };
432         void *rc = tail_memdup(&c_rc, sizeof(c_rc));
433         unsigned int len = sizeof(c_rc);
434         int ret = connect(-1, rc, len);
435         printf("connect(-1, {sa_family=AF_BLUETOOTH"
436                ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
437                ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
438                c_rc.rc_bdaddr.b[0], c_rc.rc_bdaddr.b[1],
439                c_rc.rc_bdaddr.b[2], c_rc.rc_bdaddr.b[3],
440                c_rc.rc_bdaddr.b[4], c_rc.rc_bdaddr.b[5],
441                c_rc.rc_channel, len, ret);
442 }
443
444 static void
445 check_l2(void)
446 {
447         const unsigned short h_psm = 12345;
448         const unsigned short h_cid = 13579;
449         const struct sockaddr_l2 c_l2 = {
450                 .l2_family = AF_BLUETOOTH,
451                 .l2_psm = htobs(h_psm),
452                 .l2_bdaddr.b = "abcdef",
453                 .l2_cid = htobs(h_cid),
454                 .l2_bdaddr_type = 42
455         };
456         void *l2 = tail_memdup(&c_l2, sizeof(c_l2));
457         unsigned int len = sizeof(c_l2);
458         int ret = connect(-1, l2, len);
459         printf("connect(-1, {sa_family=AF_BLUETOOTH"
460                ", l2_psm=htobs(%hu)"
461                ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
462                ", l2_cid=htobs(%hu), l2_bdaddr_type=%u}"
463                ", %u) = %d EBADF (%m)\n", h_psm,
464                c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
465                c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
466                c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
467                h_cid, c_l2.l2_bdaddr_type, len, ret);
468 }
469 #endif
470
471 static void
472 check_raw(void)
473 {
474         union {
475                 struct sockaddr *sa;
476                 struct sockaddr_storage *st;
477         } u = { .st = tail_alloc(sizeof(*u.st)) };
478         memset(u.st, '0', sizeof(*u.st));
479         u.sa->sa_family = 0xff;
480         unsigned int len = sizeof(*u.st) + 8;
481         int ret = connect(-1, (void *) u.st, len);
482         printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
483                ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
484                (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
485
486         u.sa->sa_family = 0;
487         len = sizeof(u.sa->sa_family) + 1;
488         ret = connect(-1, (void *) u.st, len);
489         printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
490                " = %d EBADF (%m)\n", len, ret);
491
492         u.sa->sa_family = AF_BLUETOOTH;
493         ++len;
494         ret = connect(-1, (void *) u.st, len);
495         printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
496                " = %d EBADF (%m)\n", len, ret);
497 }
498
499 int
500 main(void)
501 {
502         check_un();
503         check_in();
504         check_in6();
505         check_ipx();
506         check_nl();
507         check_ll();
508 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
509         check_hci();
510         check_sco();
511         check_rc();
512         check_l2();
513 #endif
514         check_raw();
515
516         puts("+++ exited with 0 +++");
517         return 0;
518 }