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