]> granicus.if.org Git - strace/blob - tests/net-sockaddr.c
Update copyright headers
[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-2018 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "tests.h"
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <sys/socket.h>
17 #include <sys/un.h>
18 #include <arpa/inet.h>
19 #include <netinet/in.h>
20 #include "netlink.h"
21 #include <linux/ax25.h>
22 #include <linux/if_arp.h>
23 #include <linux/if_ether.h>
24 #include <linux/if_packet.h>
25 #include <linux/x25.h>
26 #include <linux/ipx.h>
27 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
28 # include <bluetooth/bluetooth.h>
29 # include <bluetooth/hci.h>
30 # include <bluetooth/l2cap.h>
31 # include <bluetooth/rfcomm.h>
32 # include <bluetooth/sco.h>
33 #endif
34
35 static void
36 check_un(void)
37 {
38         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_un, un);
39         un->sun_family = AF_UNIX;
40         memset(un->sun_path, '0', sizeof(un->sun_path));
41         unsigned int len = sizeof(*un);
42         int ret = connect(-1, (void *) un, len);
43         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
44                ", %u) = %d EBADF (%m)\n",
45                (int) sizeof(un->sun_path), 0, len, ret);
46
47         un->sun_path[1] = 0;
48         ret = connect(-1, (void *) un, len);
49         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%u\"}, %u)"
50                " = %d EBADF (%m)\n", 0, len, ret);
51
52         un->sun_path[0] = 0;
53         un->sun_path[2] = 1;
54         ret = connect(-1, (void *) un, len);
55         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"\\0\\001%.*u\"}"
56                ", %u) = %d EBADF (%m)\n",
57                (int) sizeof(un->sun_path) - 3, 0, len, ret);
58
59         un = ((void *) un) - 2;
60         un->sun_family = AF_UNIX;
61         memset(un->sun_path, '0', sizeof(un->sun_path));
62         len = sizeof(*un) + 2;
63         ret = connect(-1, (void *) un, len);
64         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
65                ", %u) = %d EBADF (%m)\n",
66                (int) sizeof(un->sun_path), 0, len, ret);
67
68         un->sun_path[0] = 0;
69         ret = connect(-1, (void *) un, len);
70         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
71                ", %u) = %d EBADF (%m)\n",
72                (int) sizeof(un->sun_path) - 1, 0, len, ret);
73
74         un = ((void *) un) + 4;
75         un->sun_family = AF_UNIX;
76         len = sizeof(*un) - 2;
77         ret = connect(-1, (void *) un, len);
78         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
79                ", %u) = %d EBADF (%m)\n",
80                (int) sizeof(un->sun_path) - 2, 0, len, ret);
81
82         un->sun_path[0] = 0;
83         ret = connect(-1, (void *) un, len);
84         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
85                ", %u) = %d EBADF (%m)\n",
86                (int) sizeof(un->sun_path) - 3, 0, len, ret);
87
88         len = sizeof(*un);
89         ret = connect(-1, (void *) un, len);
90         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", un, len, ret);
91
92         un = tail_alloc(sizeof(struct sockaddr_storage));
93         un->sun_family = AF_UNIX;
94         memset(un->sun_path, '0', sizeof(un->sun_path));
95         len = sizeof(struct sockaddr_storage) + 1;
96         ret = connect(-1, (void *) un, len);
97         printf("connect(-1, {sa_family=AF_UNIX, sun_path=\"%.*u\"}"
98                ", %u) = %d EBADF (%m)\n",
99                (int) sizeof(un->sun_path), 0, len, ret);
100
101         un->sun_path[0] = 0;
102         ret = connect(-1, (void *) un, len);
103         printf("connect(-1, {sa_family=AF_UNIX, sun_path=@\"%.*u\"}"
104                ", %u) = %d EBADF (%m)\n",
105                (int) sizeof(un->sun_path) - 1, 0, len, ret);
106 }
107
108 static void
109 check_in(void)
110 {
111         const unsigned short h_port = 12345;
112         static const char h_addr[] = "12.34.56.78";
113
114         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in, in);
115         in->sin_family = AF_INET;
116         in->sin_port = htons(h_port);
117         in->sin_addr.s_addr = inet_addr(h_addr);
118         unsigned int len = sizeof(*in);
119         int ret = connect(-1, (void *) in, len);
120         printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
121                ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
122                h_port, h_addr, len, ret);
123
124         in = ((void *) in) - 4;
125         in->sin_family = AF_INET;
126         in->sin_port = htons(h_port);
127         in->sin_addr.s_addr = inet_addr(h_addr);
128         len = sizeof(*in) + 4;
129         ret = connect(-1, (void *) in, len);
130         printf("connect(-1, {sa_family=AF_INET, sin_port=htons(%hu)"
131                ", sin_addr=inet_addr(\"%s\")}, %u) = %d EBADF (%m)\n",
132                h_port, h_addr, len, ret);
133
134         in = ((void *) in) + 8;
135         in->sin_family = AF_INET;
136         in->sin_port = 0;
137         in->sin_addr.s_addr = 0;
138         len = sizeof(*in) - 4;
139         ret = connect(-1, (void *) in, len);
140         printf("connect(-1, {sa_family=AF_INET, sa_data=\"%s\"}, %u)"
141                " = %d EBADF (%m)\n",
142                "\\0\\0\\0\\0\\0\\0\\377\\377\\377\\377",
143                len, ret);
144
145         len = sizeof(*in);
146         ret = connect(-1, (void *) in, len);
147         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in, len, ret);
148 }
149
150 static void
151 check_in6_linklocal(struct sockaddr_in6 *const in6, const char *const h_addr)
152 {
153         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
154
155         in6->sin6_scope_id = 0xfacefeed;
156         unsigned int len = sizeof(*in6);
157         int ret = connect(-1, (void *) in6, len);
158         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
159                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
160                ", sin6_flowinfo=htonl(%u)"
161                ", sin6_scope_id=%u}, %u)"
162                " = %d EBADF (%m)\n",
163                ntohs(in6->sin6_port), h_addr,
164                ntohl(in6->sin6_flowinfo), in6->sin6_scope_id, len, ret);
165
166         in6->sin6_scope_id = ifindex_lo();
167         if (in6->sin6_scope_id) {
168                 ret = connect(-1, (void *) in6, len);
169                 printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
170                        ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
171                        ", sin6_flowinfo=htonl(%u)"
172                        ", sin6_scope_id=%s}, %u)"
173                        " = %d EBADF (%m)\n",
174                        ntohs(in6->sin6_port), h_addr, ntohl(in6->sin6_flowinfo),
175                        IFINDEX_LO_STR, len, ret);
176         }
177 }
178
179 static void
180 check_in6(void)
181 {
182         const unsigned short h_port = 12345;
183         const unsigned int h_flowinfo = 1234567890;
184         static const char h_addr[] = "12:34:56:78:90:ab:cd:ef";
185
186         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_in6, in6);
187         in6->sin6_family = AF_INET6;
188         in6->sin6_port = htons(h_port);
189         in6->sin6_flowinfo = htonl(h_flowinfo);
190         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
191         in6->sin6_scope_id = 0xfacefeed;
192         unsigned int len = sizeof(*in6);
193         int ret = connect(-1, (void *) in6, len);
194         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
195                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
196                ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
197                " = %d EBADF (%m)\n",
198                h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
199
200         check_in6_linklocal(in6, "fe80::");
201         check_in6_linklocal(in6, "ff42::");
202
203         in6 = ((void *) in6) - 4;
204         in6->sin6_family = AF_INET6;
205         in6->sin6_port = htons(h_port);
206         in6->sin6_flowinfo = htonl(h_flowinfo);
207         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
208         in6->sin6_scope_id = 0xfacefeed;
209         len = sizeof(*in6) + 4;
210         ret = connect(-1, (void *) in6, len);
211         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
212                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
213                ", sin6_flowinfo=htonl(%u), sin6_scope_id=%u}, %u)"
214                " = %d EBADF (%m)\n",
215                h_port, h_addr, h_flowinfo, in6->sin6_scope_id, len, ret);
216
217         in6 = ((void *) in6) + 4 + sizeof(in6->sin6_scope_id);
218         in6->sin6_family = AF_INET6;
219         in6->sin6_port = htons(h_port);
220         in6->sin6_flowinfo = htonl(h_flowinfo);
221         inet_pton(AF_INET6, h_addr, &in6->sin6_addr);
222         len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
223         ret = connect(-1, (void *) in6, len);
224         printf("connect(-1, {sa_family=AF_INET6, sin6_port=htons(%hu)"
225                ", inet_pton(AF_INET6, \"%s\", &sin6_addr)"
226                ", sin6_flowinfo=htonl(%u)}, %u)"
227                " = %d EBADF (%m)\n",
228                h_port, h_addr, h_flowinfo, len, ret);
229
230         in6 = ((void *) in6) + 4;
231         in6->sin6_family = AF_INET6;
232         in6->sin6_port = 0;
233         in6->sin6_flowinfo = 0;
234         memset(&in6->sin6_addr, '0', sizeof(in6->sin6_addr) - 4);
235         len = sizeof(*in6) - sizeof(in6->sin6_scope_id) - 4;
236         ret = connect(-1, (void *) in6, len);
237         printf("connect(-1, {sa_family=AF_INET6"
238                ", sa_data=\"\\0\\0\\0\\0\\0\\000%.*u\"}, %u)"
239                " = %d EBADF (%m)\n",
240                (int) (len - offsetof(struct sockaddr_in6, sin6_addr)), 0,
241                len, ret);
242
243         len = sizeof(*in6) - sizeof(in6->sin6_scope_id);
244         ret = connect(-1, (void *) in6, len);
245         printf("connect(-1, %p, %u) = %d EBADF (%m)\n", in6, len, ret);
246 }
247
248 static void
249 check_ipx(void)
250 {
251         const unsigned short h_port = 12345;
252         const unsigned int h_network = 0xfacefeed;
253         struct sockaddr_ipx c_ipx = {
254                 .sipx_family = AF_IPX,
255                 .sipx_port = htons(h_port),
256                 .sipx_network = htonl(h_network),
257                 .sipx_node = "ABCDEF",
258                 .sipx_type = -1
259         };
260         void *ipx = tail_memdup(&c_ipx, sizeof(c_ipx));
261         unsigned int len = sizeof(c_ipx);
262         int ret = connect(-1, ipx, len);
263         printf("connect(-1, {sa_family=AF_IPX, sipx_port=htons(%u)"
264                ", sipx_network=htonl(%#x)"
265                ", sipx_node=[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
266                ", sipx_type=%#02x}, %u) = %d EBADF (%m)\n",
267                h_port, h_network,
268                c_ipx.sipx_node[0], c_ipx.sipx_node[1],
269                c_ipx.sipx_node[2], c_ipx.sipx_node[3],
270                c_ipx.sipx_node[4], c_ipx.sipx_node[5],
271                c_ipx.sipx_type, len, ret);
272 }
273
274 /* for a bit more compact AX.25 address definitions */
275 #define AX25_ADDR(c_, s_) \
276         { { (c_)[0] << 1, (c_)[1] << 1, (c_)[2] << 1, \
277             (c_)[3] << 1, (c_)[4] << 1, (c_)[5] << 1, (s_) << 1 } } \
278         /* End of AX25_ADDR definition */
279
280 static void
281 check_ax25(void)
282 {
283         const struct full_sockaddr_ax25 ax25 = {
284                 .fsa_ax25 = {
285                         .sax25_family = AF_AX25,
286                         .sax25_call = AX25_ADDR("VALID ", 13),
287                         .sax25_ndigis = 8,
288                 },
289                 .fsa_digipeater = {
290                         AX25_ADDR("SPA CE", 0),
291                         AX25_ADDR("SSID  ", 16),
292                         AX25_ADDR("      ", 0),
293                         AX25_ADDR("NULL\0", 3),
294                         AX25_ADDR("A-B-C", 4),
295                         AX25_ADDR(",}]\"\\'", 5),
296                         AX25_ADDR("DASH-0", 6),
297                         AX25_ADDR("\n\tABCD", 7),
298                 },
299         };
300         const ax25_address aux_addrs[] = {
301                 AX25_ADDR("VALID2", 7),
302                 AX25_ADDR("OK    ", 15),
303                 AX25_ADDR("FINE  ", 2),
304                 AX25_ADDR("smalls", 9),
305         };
306
307         enum { AX25_ALIGN = ALIGNOF(struct full_sockaddr_ax25), };
308         size_t size = sizeof(ax25);
309         size_t surplus = ROUNDUP(sizeof(ax25_address), AX25_ALIGN);
310         void *sax_void = midtail_alloc(size, surplus);
311         struct full_sockaddr_ax25 *sax = sax_void;
312         long rc;
313
314         fill_memory(sax, size);
315         sax->fsa_ax25.sax25_family = AF_AX25;
316         rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25) - 1);
317         printf("connect(-1, {sa_family=AF_AX25, sa_data=\"\\202\\203\\204\\205"
318                "\\206\\207\\210\\211\\212\\213\\214\\215\\216\"}, %zu) = %s\n",
319                sizeof(struct sockaddr_ax25) - 1, sprintrc(rc));
320
321         memcpy(sax, &ax25, sizeof(ax25));
322         rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
323         printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
324                ", sax25_ndigis=8}, fsa_digipeater=[/* ??? */]}, %zu) = %s\n",
325                sizeof(struct sockaddr_ax25), sprintrc(rc));
326
327         sax->fsa_ax25.sax25_ndigis = 0;
328         rc = connect(-1, sax_void, sizeof(struct sockaddr_ax25));
329         printf("connect(-1, {sa_family=AF_AX25, sax25_call=VALID-13"
330                ", sax25_ndigis=0}, %zu) = %s\n",
331                sizeof(struct sockaddr_ax25), sprintrc(rc));
332
333         sax->fsa_ax25.sax25_ndigis = 8;
334         size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 3 + 1;
335         rc = connect(-1, sax_void, size);
336         printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
337                ", sax25_ndigis=8}, fsa_digipeater"
338                "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
339                    "} /* SPA CE-0 */"
340                ", {ax25_call=\"\\xa6\\xa6\\x92\\x88\\x40\\x40\\x20\""
341                    "} /* SSID-0 */"
342                ", *"
343                ", /* ??? */], ...}, %zu) = %s\n",
344                size, sprintrc(rc));
345
346         sax->fsa_digipeater[2].ax25_call[6] = 0x4;
347         size = sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 4;
348         rc = connect(-1, sax_void, size);
349         printf("connect(-1, {sa_family=AF_AX25, fsa_ax25={sax25_call=VALID-13"
350                ", sax25_ndigis=8}, fsa_digipeater"
351                "=[{ax25_call=\"\\xa6\\xa0\\x82\\x40\\x86\\x8a\\x00\""
352                    "} /* SPA CE-0 */"
353                ", {ax25_call=\"\\xa6\\xa6\\x92\\x88\\x40\\x40\\x20\""
354                    "} /* SSID-0 */"
355                ", {ax25_call=\"\\x40\\x40\\x40\\x40\\x40\\x40\\x04\"} /* -2 */"
356                ", {ax25_call=\"\\x9c\\xaa\\x98\\x98\\x00\\x00\\x06\"}"
357                ", /* ??? */]}, %zu) = %s\n",
358                size, sprintrc(rc));
359
360         memcpy(sax->fsa_digipeater, aux_addrs, sizeof(aux_addrs));
361         sax->fsa_digipeater[2].ax25_call[6] = 0xa5;
362         sax->fsa_digipeater[4].ax25_call[5] = 0x40;
363         for (size_t i = 0; i < 3; i++) {
364                 size = sizeof(ax25) + sizeof(ax25_address) * (i / 2);
365                 rc = connect(-1, sax_void, size);
366                 printf("connect(-1, {sa_family=AF_AX25"
367                        ", fsa_ax25={sax25_call=VALID-13, sax25_ndigis=%d}"
368                        ", fsa_digipeater=[VALID2-7, OK-15, %s /* FINE-2 */"
369                        ", {ax25_call=\"\\xe6\\xda\\xc2\\xd8\\xd8\\xe6\\x12\""
370                            "} /* smalls-9 */"
371                        ", {ax25_call=\"\\x%s\\x%s\\x84\\x5a\\x86\\x40\\x08\""
372                            "} /* %sB-C-4 */"
373                        ", {ax25_call=\"\\x58\\xfa\\xba\\x44\\x%s\\x%s\\x0a\""
374                            "}%s"
375                        ", {ax25_call=\"\\x88\\x82\\xa6\\x90\\x5a\\x%s\\x0c\""
376                            "}%s"
377                        "%s]%s}, %zu) = %s\n"
378                        , sax->fsa_ax25.sax25_ndigis
379                        , i
380                        ? "{ax25_call=\"\\x8c\\x92\\x9c\\x8a\\x40\\x41\\x04\"}"
381                        : "{ax25_call=\"\\x8c\\x92\\x9c\\x8a\\x40\\x40\\xa5\"}"
382                        , i ? "40" : "82"
383                        , i ? "40" : "5a"
384                        , i ? "  " : "A-"
385                        , i ? "54" : "b8"
386                        , i ? "5e" : "4e"
387                        , i ? "" : " /* ,}]\"\\'-5 */"
388                        , i ? "fe" : "60"
389                        , i ? "" : " /* DASH-0-6 */"
390                        , i == 1
391                        ? ""
392                        : ", {ax25_call=\"\\x14\\x12\\x82\\x84\\x86\\x88\\x0e\"}"
393                        , i > 1 ? ", ..." : ""
394                        , size, sprintrc(rc));
395
396                 if (i == 1) {
397                         sax_void = (char *) sax_void - surplus;
398                         memmove(sax_void, sax, sizeof(ax25));
399                         sax = sax_void;
400                 }
401
402                 sax->fsa_ax25.sax25_ndigis = 7 + 2 * i;
403
404                 sax->fsa_digipeater[2].ax25_call[5] = 0x41;
405                 sax->fsa_digipeater[2].ax25_call[6] = 0x4;
406
407                 sax->fsa_digipeater[4].ax25_call[0] = 0x40;
408                 sax->fsa_digipeater[4].ax25_call[1] = 0x40;
409
410                 sax->fsa_digipeater[5].ax25_call[4] = '*' << 1;
411                 sax->fsa_digipeater[5].ax25_call[5] = '/' << 1;
412
413                 sax->fsa_digipeater[6].ax25_call[5] = 0xfe;
414         }
415 }
416
417 static void
418 check_x25(void)
419 {
420         static const struct sockaddr_x25 c_x25 = {
421                 .sx25_family = AF_X25,
422                 .sx25_addr = { "0123456789abcdef" },
423         };
424         void *x25_void = tail_memdup(&c_x25, sizeof(c_x25) + 1);
425         struct sockaddr_x25 *x25 = x25_void;
426         long rc;
427
428         rc = connect(-1, x25, sizeof(c_x25) - 1);
429         printf("connect(-1, {sa_family=AF_X25"
430                ", sa_data=\"0123456789abcde\"}, %zu) = %s\n",
431                sizeof(c_x25) - 1, sprintrc(rc));
432
433         for (size_t i = 0; i < 2; i++) {
434                 rc = connect(-1, x25, sizeof(c_x25) + i);
435                 printf("connect(-1, {sa_family=AF_X25"
436                        ", sx25_addr={x25_addr=\"0123456789abcde\"...}"
437                        "}, %zu) = %s\n",
438                        sizeof(c_x25) + i, sprintrc(rc));
439         }
440
441         x25->sx25_addr.x25_addr[10] = '\0';
442         rc = connect(-1, x25, sizeof(c_x25));
443         printf("connect(-1, {sa_family=AF_X25"
444                ", sx25_addr={x25_addr=\"0123456789\"}"
445                "}, %zu) = %s\n",
446                sizeof(c_x25), sprintrc(rc));
447 }
448
449 static void
450 check_nl(void)
451 {
452         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_nl, nl);
453         nl->nl_family = AF_NETLINK;
454         nl->nl_pid = 1234567890;
455         nl->nl_groups = 0xfacefeed;
456         unsigned int len = sizeof(*nl);
457         int ret = connect(-1, (void *) nl, len);
458         printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
459                ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
460                nl->nl_pid, nl->nl_groups, len, ret);
461
462         nl = ((void *) nl) - 4;
463         nl->nl_family = AF_NETLINK;
464         nl->nl_pid = 1234567890;
465         nl->nl_groups = 0xfacefeed;
466         len = sizeof(*nl) + 4;
467         ret = connect(-1, (void *) nl, len);
468         printf("connect(-1, {sa_family=AF_NETLINK, nl_pid=%d"
469                ", nl_groups=%#08x}, %u) = %d EBADF (%m)\n",
470                nl->nl_pid, nl->nl_groups, len, ret);
471 }
472
473 static void
474 check_ll(void)
475 {
476         struct sockaddr_ll c_ll = {
477                 .sll_family = AF_PACKET,
478                 .sll_protocol = htons(ETH_P_ALL),
479                 .sll_ifindex = 0xfacefeed,
480                 .sll_hatype = ARPHRD_ETHER,
481                 .sll_pkttype = PACKET_HOST,
482                 .sll_halen = sizeof(c_ll.sll_addr),
483                 .sll_addr = "abcdefgh"
484         };
485         void *ll = tail_memdup(&c_ll, sizeof(c_ll));
486         unsigned int len = sizeof(c_ll);
487         int ret = connect(-1, ll, len);
488         printf("connect(-1, {sa_family=AF_PACKET"
489                ", sll_protocol=htons(ETH_P_ALL)"
490                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
491                ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
492                "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x]"
493                "}, %u) = %d EBADF (%m)\n",
494                c_ll.sll_ifindex, c_ll.sll_halen,
495                c_ll.sll_addr[0], c_ll.sll_addr[1],
496                c_ll.sll_addr[2], c_ll.sll_addr[3],
497                c_ll.sll_addr[4], c_ll.sll_addr[5],
498                c_ll.sll_addr[6], c_ll.sll_addr[7],
499                len, ret);
500
501         ((struct sockaddr_ll *) ll)->sll_halen++;
502         ret = connect(-1, ll, len);
503         printf("connect(-1, {sa_family=AF_PACKET"
504                ", sll_protocol=htons(ETH_P_ALL)"
505                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
506                ", sll_pkttype=PACKET_HOST, sll_halen=%u, sll_addr="
507                "[%#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, %#02x, ...]"
508                "}, %u) = %d EBADF (%m)\n",
509                c_ll.sll_ifindex, c_ll.sll_halen + 1,
510                c_ll.sll_addr[0], c_ll.sll_addr[1],
511                c_ll.sll_addr[2], c_ll.sll_addr[3],
512                c_ll.sll_addr[4], c_ll.sll_addr[5],
513                c_ll.sll_addr[6], c_ll.sll_addr[7],
514                len, ret);
515
516         ((struct sockaddr_ll *) ll)->sll_halen = 0;
517         ret = connect(-1, ll, len);
518         printf("connect(-1, {sa_family=AF_PACKET"
519                ", sll_protocol=htons(ETH_P_ALL)"
520                ", sll_ifindex=%u, sll_hatype=ARPHRD_ETHER"
521                ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
522                " = %d EBADF (%m)\n", c_ll.sll_ifindex, len, ret);
523
524         ((struct sockaddr_ll *) ll)->sll_ifindex = ifindex_lo();
525         if (((struct sockaddr_ll *) ll)->sll_ifindex) {
526                 ret = connect(-1, ll, len);
527                 printf("connect(-1, {sa_family=AF_PACKET"
528                        ", sll_protocol=htons(ETH_P_ALL)"
529                        ", sll_ifindex=%s"
530                        ", sll_hatype=ARPHRD_ETHER"
531                        ", sll_pkttype=PACKET_HOST, sll_halen=0}, %u)"
532                        " = %d EBADF (%m)\n", IFINDEX_LO_STR, len, ret);
533         }
534 }
535
536 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
537 static void
538 check_hci(void)
539 {
540         const unsigned short h_port = 12345;
541         TAIL_ALLOC_OBJECT_VAR_PTR(struct sockaddr_hci, hci);
542         hci->hci_family = AF_BLUETOOTH;
543         hci->hci_dev = htobs(h_port);
544         hci->hci_channel = HCI_CHANNEL_RAW;
545         unsigned int len = sizeof(*hci);
546         int ret = connect(-1, (void *) hci, len);
547         printf("connect(-1, {sa_family=AF_BLUETOOTH, hci_dev=htobs(%hu)"
548                ", hci_channel=HCI_CHANNEL_RAW}, %u) = %d EBADF (%m)\n",
549                h_port, len, ret);
550 }
551
552 static void
553 check_sco(void)
554 {
555         const struct sockaddr_sco c_sco = {
556                 .sco_family = AF_BLUETOOTH,
557                 .sco_bdaddr.b = "abcdef"
558         };
559         void *sco = tail_memdup(&c_sco, sizeof(c_sco));
560         unsigned int len = sizeof(c_sco);
561         int ret = connect(-1, sco, len);
562         printf("connect(-1, {sa_family=AF_BLUETOOTH"
563                ", sco_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
564                "}, %u) = %d EBADF (%m)\n",
565                c_sco.sco_bdaddr.b[0], c_sco.sco_bdaddr.b[1],
566                c_sco.sco_bdaddr.b[2], c_sco.sco_bdaddr.b[3],
567                c_sco.sco_bdaddr.b[4], c_sco.sco_bdaddr.b[5],
568                len, ret);
569 }
570
571 static void
572 check_rc(void)
573 {
574         const struct sockaddr_rc c_rc = {
575                 .rc_family = AF_BLUETOOTH,
576                 .rc_bdaddr.b = "abcdef",
577                 .rc_channel = 42
578         };
579         void *rc = tail_memdup(&c_rc, sizeof(c_rc));
580         unsigned int len = sizeof(c_rc);
581         int ret = connect(-1, rc, len);
582         printf("connect(-1, {sa_family=AF_BLUETOOTH"
583                ", rc_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
584                ", rc_channel=%u}, %u) = %d EBADF (%m)\n",
585                c_rc.rc_bdaddr.b[0], c_rc.rc_bdaddr.b[1],
586                c_rc.rc_bdaddr.b[2], c_rc.rc_bdaddr.b[3],
587                c_rc.rc_bdaddr.b[4], c_rc.rc_bdaddr.b[5],
588                c_rc.rc_channel, len, ret);
589 }
590
591 static void
592 check_l2(void)
593 {
594         const unsigned short h_psm = 12345;
595         const unsigned short h_cid = 13579;
596         struct sockaddr_l2 c_l2 = {
597                 .l2_family = AF_BLUETOOTH,
598                 .l2_psm = htobs(h_psm),
599                 .l2_bdaddr.b = "abcdef",
600                 .l2_cid = htobs(h_cid),
601 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
602                 .l2_bdaddr_type = 0xce,
603 #endif
604         };
605         void *l2 = tail_memdup(&c_l2, sizeof(c_l2));
606         unsigned int len = sizeof(c_l2);
607
608         int ret = connect(-1, l2, len);
609         printf("connect(-1, {sa_family=AF_BLUETOOTH"
610                ", l2_psm=htobs(L2CAP_PSM_DYN_START + %hu)"
611                ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
612                ", l2_cid=htobs(L2CAP_CID_DYN_START + %hu)"
613 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
614                ", l2_bdaddr_type=0xce /* BDADDR_??? */"
615 #endif
616                "}, %u) = %d EBADF (%m)\n",
617                (short) (h_psm - 0x1001),
618                c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
619                c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
620                c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
621                (short) (h_cid - 0x40), len, ret);
622
623         c_l2.l2_psm = htobs(1);
624         c_l2.l2_cid = htobs(1);
625 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
626         c_l2.l2_bdaddr_type = BDADDR_LE_RANDOM;
627 #endif
628         memcpy(l2, &c_l2, sizeof(c_l2));
629         ret = connect(-1, l2, len);
630         printf("connect(-1, {sa_family=AF_BLUETOOTH"
631                ", l2_psm=htobs(L2CAP_PSM_SDP)"
632                ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
633                ", l2_cid=htobs(L2CAP_CID_SIGNALING)"
634 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
635                ", l2_bdaddr_type=BDADDR_LE_RANDOM"
636 #endif
637                "}, %u) = %d EBADF (%m)\n",
638                c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
639                c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
640                c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
641                len, ret);
642
643         c_l2.l2_psm = htobs(0xbad);
644         c_l2.l2_cid = htobs(8);
645 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
646         c_l2.l2_bdaddr_type = 3;
647 #endif
648         memcpy(l2, &c_l2, sizeof(c_l2));
649         ret = connect(-1, l2, len);
650         printf("connect(-1, {sa_family=AF_BLUETOOTH"
651                ", l2_psm=htobs(0xbad /* L2CAP_PSM_??? */)"
652                ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
653                ", l2_cid=htobs(0x8 /* L2CAP_CID_??? */)"
654 #ifdef HAVE_STRUCT_SOCKADDR_L2_L2_BDADDR_TYPE
655                ", l2_bdaddr_type=0x3 /* BDADDR_??? */"
656 #endif
657                "}, %u) = %d EBADF (%m)\n",
658                c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
659                c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
660                c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
661                len, ret);
662
663         c_l2.l2_psm = htobs(0x10ff);
664         c_l2.l2_cid = htobs(0xffff);
665         memcpy(l2, &c_l2, 12);
666         ret = connect(-1, l2, 12);
667         printf("connect(-1, {sa_family=AF_BLUETOOTH"
668                ", l2_psm=htobs(L2CAP_PSM_AUTO_END)"
669                ", l2_bdaddr=%02x:%02x:%02x:%02x:%02x:%02x"
670                ", l2_cid=htobs(L2CAP_CID_DYN_END)"
671                "}, 12) = %d EBADF (%m)\n",
672                c_l2.l2_bdaddr.b[0], c_l2.l2_bdaddr.b[1],
673                c_l2.l2_bdaddr.b[2], c_l2.l2_bdaddr.b[3],
674                c_l2.l2_bdaddr.b[4], c_l2.l2_bdaddr.b[5],
675                ret);
676 }
677 #endif
678
679 static void
680 check_raw(void)
681 {
682         union {
683                 struct sockaddr *sa;
684                 struct sockaddr_storage *st;
685         } u = { .st = tail_alloc(sizeof(*u.st)) };
686         memset(u.st, '0', sizeof(*u.st));
687         u.sa->sa_family = 0xff;
688         unsigned int len = sizeof(*u.st) + 8;
689         int ret = connect(-1, (void *) u.st, len);
690         printf("connect(-1, {sa_family=%#x /* AF_??? */, sa_data=\"%.*u\"}"
691                ", %u) = %d EBADF (%m)\n", u.sa->sa_family,
692                (int) (sizeof(*u.st) - sizeof(u.sa->sa_family)), 0, len, ret);
693
694         u.sa->sa_family = 0;
695         len = sizeof(u.sa->sa_family) + 1;
696         ret = connect(-1, (void *) u.st, len);
697         printf("connect(-1, {sa_family=AF_UNSPEC, sa_data=\"0\"}, %u)"
698                " = %d EBADF (%m)\n", len, ret);
699
700         u.sa->sa_family = AF_BLUETOOTH;
701         ++len;
702         ret = connect(-1, (void *) u.st, len);
703         printf("connect(-1, {sa_family=AF_BLUETOOTH, sa_data=\"00\"}, %u)"
704                " = %d EBADF (%m)\n", len, ret);
705 }
706
707 int
708 main(void)
709 {
710         check_un();
711         check_in();
712         check_in6();
713         check_ipx();
714         check_ax25();
715         check_x25();
716         check_nl();
717         check_ll();
718 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
719         check_hci();
720         check_sco();
721         check_rc();
722         check_l2();
723 #endif
724         check_raw();
725
726         puts("+++ exited with 0 +++");
727         return 0;
728 }