1 /* $NetBSD: t_can.c,v 1.8 2021/08/20 20:25:28 andvar Exp $ */ 2 3 /*- 4 * Copyright (c) 2017 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Manuel Bouyer 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 20 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 28 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 30 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 #ifndef lint 35 __RCSID("$NetBSD: t_can.c,v 1.8 2021/08/20 20:25:28 andvar Exp $"); 36 #endif /* not lint */ 37 38 #include <sys/types.h> 39 #include <sys/resource.h> 40 #include <sys/wait.h> 41 #include <sys/sockio.h> 42 #include <sys/param.h> 43 44 #include <atf-c.h> 45 #include <assert.h> 46 #include <fcntl.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 52 #include <net/if.h> 53 #include <netcan/can.h> 54 55 #include <rump/rump.h> 56 #include <rump/rump_syscalls.h> 57 58 #include "h_macros.h" 59 #include "h_canutils.h" 60 61 ATF_TC(canlocreate); 62 ATF_TC_HEAD(canlocreate, tc) 63 { 64 65 atf_tc_set_md_var(tc, "descr", "check CAN loopback create/destroy"); 66 atf_tc_set_md_var(tc, "timeout", "5"); 67 } 68 69 ATF_TC_BODY(canlocreate, tc) 70 { 71 const char ifname[] = "canlo0"; 72 int s, rv; 73 struct ifreq ifr; 74 75 rump_init(); 76 cancfg_rump_createif(ifname); 77 78 s = -1; 79 if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 80 atf_tc_fail_errno("if config socket(2)"); 81 } 82 83 memset(&ifr, 0, sizeof(ifr)); 84 strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 85 86 if ((rv = rump_sys_ioctl(s, SIOCIFDESTROY, &ifr)) < 0) { 87 atf_tc_fail_errno("if config destroy"); 88 } 89 } 90 91 ATF_TC(cannoown); 92 ATF_TC_HEAD(cannoown, tc) 93 { 94 95 atf_tc_set_md_var(tc, "descr", "check that CAN sockets don't gets its own message"); 96 atf_tc_set_md_var(tc, "timeout", "5"); 97 } 98 99 ATF_TC_BODY(cannoown, tc) 100 { 101 const char ifname[] = "canlo0"; 102 int s, rv, v; 103 socklen_t vlen; 104 struct sockaddr_can sa; 105 int ifindex; 106 struct can_frame cf_send, cf_receive; 107 108 rump_init(); 109 cancfg_rump_createif(ifname); 110 111 if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 112 atf_tc_fail_errno("CAN socket"); 113 } 114 115 ifindex = can_bind(s, ifname); 116 117 /* check sockopt CAN_RAW_LOOPBACK */ 118 vlen = sizeof(v); 119 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, 120 &v, &vlen) < 0) { 121 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)"); 122 } 123 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen); 124 ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default"); 125 126 /* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */ 127 vlen = sizeof(v); 128 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, 129 &v, &vlen) < 0) { 130 atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)"); 131 } 132 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen); 133 ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default"); 134 135 /* 136 * send a single byte message, but make sure remaining payload is 137 * not 0. 138 */ 139 140 memset(&cf_send, 0, sizeof(cf_send)); 141 cf_send.can_id = 1; 142 cf_send.can_dlc = 1; 143 cf_send.data[0] = 0xde; 144 cf_send.data[1] = 0xad; 145 cf_send.data[2] = 0xbe; 146 cf_send.data[3] = 0xef; 147 148 if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) { 149 atf_tc_fail_errno("write"); 150 } 151 152 /* now try to read */ 153 if (can_recvfrom(s, &cf_receive, &rv, &sa) < 0) { 154 if (errno == EWOULDBLOCK) 155 return; /* expected timeout */ 156 atf_tc_fail_errno("can_recvfrom"); 157 } 158 159 ATF_CHECK_MSG(sa.can_ifindex == ifindex, 160 "recvfrom provided wrong ifindex %d (!= %d)", 161 sa.can_ifindex, ifindex); 162 atf_tc_fail("we got our own message"); 163 } 164 165 ATF_TC(canwritelo); 166 ATF_TC_HEAD(canwritelo, tc) 167 { 168 169 atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via write"); 170 atf_tc_set_md_var(tc, "timeout", "5"); 171 } 172 173 ATF_TC_BODY(canwritelo, tc) 174 { 175 const char ifname[] = "canlo0"; 176 int s, rv, v; 177 socklen_t vlen; 178 struct can_frame cf_send, cf_receive; 179 180 rump_init(); 181 cancfg_rump_createif(ifname); 182 183 s = can_socket_with_own(); 184 185 can_bind(s, ifname); 186 187 /* check sockopt CAN_RAW_LOOPBACK */ 188 vlen = sizeof(v); 189 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, 190 &v, &vlen) < 0) { 191 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)"); 192 } 193 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen); 194 ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default"); 195 196 /* check that sockopt CAN_RAW_RECV_OWN_MSGS is on */ 197 vlen = sizeof(v); 198 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, 199 &v, &vlen) < 0) { 200 atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)"); 201 } 202 ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on"); 203 204 /* 205 * send a single byte message, but make sure remaining payload is 206 * not 0. 207 */ 208 209 memset(&cf_send, 0, sizeof(cf_send)); 210 cf_send.can_id = 1; 211 cf_send.can_dlc = 1; 212 cf_send.data[0] = 0xde; 213 cf_send.data[1] = 0xad; 214 cf_send.data[2] = 0xbe; 215 cf_send.data[3] = 0xef; 216 217 if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) { 218 atf_tc_fail_errno("write"); 219 } 220 221 if (can_read(s, &cf_receive, &rv) < 0) { 222 atf_tc_fail_errno("can_read"); 223 } 224 225 memset(&cf_send, 0, sizeof(cf_send)); 226 cf_send.can_id = 1; 227 cf_send.can_dlc = 1; 228 cf_send.data[0] = 0xde; 229 /* other data[] are expected to be 0 */ 230 231 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0, 232 "received packet is not what we sent"); 233 } 234 235 ATF_TC(canwriteunbound); 236 ATF_TC_HEAD(canwriteunbound, tc) 237 { 238 239 atf_tc_set_md_var(tc, "descr", "check that write to unbound CAN sockets fails"); 240 atf_tc_set_md_var(tc, "timeout", "5"); 241 } 242 243 ATF_TC_BODY(canwriteunbound, tc) 244 { 245 const char ifname[] = "canlo0"; 246 int s, rv; 247 struct can_frame cf_send; 248 249 rump_init(); 250 cancfg_rump_createif(ifname); 251 252 s = -1; 253 if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 254 atf_tc_fail_errno("CAN socket"); 255 } 256 257 /* 258 * send a single byte message. 259 * not 0. 260 */ 261 262 memset(&cf_send, 0, sizeof(cf_send)); 263 cf_send.can_id = 1; 264 cf_send.can_dlc = 1; 265 cf_send.data[0] = 0xde; 266 267 rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7); 268 ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ, 269 "write to unbound socket didn't fail"); 270 } 271 272 ATF_TC(cansendtolo); 273 ATF_TC_HEAD(cansendtolo, tc) 274 { 275 276 atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via sendto"); 277 atf_tc_set_md_var(tc, "timeout", "5"); 278 } 279 280 ATF_TC_BODY(cansendtolo, tc) 281 { 282 const char ifname[] = "canlo0"; 283 int s, rv; 284 struct sockaddr_can sa; 285 struct ifreq ifr; 286 struct can_frame cf_send, cf_receive; 287 288 rump_init(); 289 cancfg_rump_createif(ifname); 290 291 s = can_socket_with_own(); 292 293 strcpy(ifr.ifr_name, ifname ); 294 if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) { 295 atf_tc_fail_errno("SIOCGIFINDEX"); 296 } 297 ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)", 298 ifname, ifr.ifr_ifindex); 299 300 sa.can_family = AF_CAN; 301 sa.can_ifindex = ifr.ifr_ifindex; 302 303 /* 304 * send a single byte message, but make sure remaining payload is 305 * not 0. 306 */ 307 308 memset(&cf_send, 0, sizeof(cf_send)); 309 cf_send.can_id = 1; 310 cf_send.can_dlc = 1; 311 cf_send.data[0] = 0xde; 312 cf_send.data[1] = 0xad; 313 cf_send.data[2] = 0xbe; 314 cf_send.data[3] = 0xef; 315 316 if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7, 317 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) { 318 atf_tc_fail_errno("sendto"); 319 } 320 321 if (can_read(s, &cf_receive, &rv) < 0) { 322 atf_tc_fail_errno("read"); 323 } 324 325 memset(&cf_send, 0, sizeof(cf_send)); 326 cf_send.can_id = 1; 327 cf_send.can_dlc = 1; 328 cf_send.data[0] = 0xde; 329 /* other data[] are expected to be 0 */ 330 331 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0, 332 "received packet is not what we sent"); 333 } 334 335 ATF_TC(cansendtowrite); 336 ATF_TC_HEAD(cansendtowrite, tc) 337 { 338 339 atf_tc_set_md_var(tc, "descr", "check that write after sendto on unbound socket fails"); 340 atf_tc_set_md_var(tc, "timeout", "5"); 341 } 342 343 ATF_TC_BODY(cansendtowrite, tc) 344 { 345 const char ifname[] = "canlo0"; 346 int s, rv; 347 struct sockaddr_can sa; 348 struct ifreq ifr; 349 struct can_frame cf_send, cf_receive; 350 351 rump_init(); 352 cancfg_rump_createif(ifname); 353 354 s = can_socket_with_own(); 355 356 strcpy(ifr.ifr_name, ifname ); 357 if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) { 358 atf_tc_fail_errno("SIOCGIFINDEX"); 359 } 360 ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)", 361 ifname, ifr.ifr_ifindex); 362 363 sa.can_family = AF_CAN; 364 sa.can_ifindex = ifr.ifr_ifindex; 365 366 /* 367 * send a single byte message. 368 * not 0. 369 */ 370 371 memset(&cf_send, 0, sizeof(cf_send)); 372 cf_send.can_id = 1; 373 cf_send.can_dlc = 1; 374 cf_send.data[0] = 0xde; 375 376 if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7, 377 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) { 378 atf_tc_fail_errno("sendto"); 379 } 380 381 if (can_read(s, &cf_receive, &rv) < 0) { 382 atf_tc_fail_errno("read"); 383 } 384 385 memset(&cf_send, 0, sizeof(cf_send)); 386 cf_send.can_id = 1; 387 cf_send.can_dlc = 1; 388 cf_send.data[0] = 0xde; 389 /* other data[] are expected to be 0 */ 390 391 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0, 392 "received packet is not what we sent"); 393 394 rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7); 395 ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ, 396 "write to unbound socket didn't fail"); 397 } 398 399 ATF_TC(canreadlocal); 400 ATF_TC_HEAD(canreadlocal, tc) 401 { 402 403 atf_tc_set_md_var(tc, "descr", "check all CAN sockets get messages"); 404 atf_tc_set_md_var(tc, "timeout", "5"); 405 } 406 407 ATF_TC_BODY(canreadlocal, tc) 408 { 409 const char ifname[] = "canlo0"; 410 int s1, rv1; 411 int s2, rv2; 412 struct can_frame cf_send, cf_receive1, cf_receive2; 413 414 rump_init(); 415 cancfg_rump_createif(ifname); 416 417 memset(&cf_send, 0, sizeof(cf_send)); 418 cf_send.can_id = 1; 419 cf_send.can_dlc = 8; 420 cf_send.data[0] = 0xde; 421 cf_send.data[1] = 0xad; 422 cf_send.data[2] = 0xbe; 423 cf_send.data[3] = 0xef; 424 425 426 if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 427 atf_tc_fail_errno("CAN socket"); 428 } 429 430 /* create a second socket */ 431 432 s2 = can_socket_with_own(); 433 434 can_bind(s2, ifname); 435 436 /* 437 * send a single byte message, but make sure remaining payload is 438 * not 0. 439 */ 440 441 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) { 442 atf_tc_fail_errno("write"); 443 } 444 445 if (can_read(s2, &cf_receive2, &rv2) < 0) { 446 atf_tc_fail_errno("can_read"); 447 } 448 449 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0, 450 "received (2) packet is not what we sent"); 451 452 /* now check first socket */ 453 if (can_read(s1, &cf_receive1, &rv1) < 0) { 454 atf_tc_fail_errno("can_read"); 455 } 456 457 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0, 458 "received (1) packet is not what we sent"); 459 } 460 461 ATF_TC(canrecvfrom); 462 ATF_TC_HEAD(canrecvfrom, tc) 463 { 464 465 atf_tc_set_md_var(tc, "descr", "check that recvfrom gets the CAN interface"); 466 atf_tc_set_md_var(tc, "timeout", "5"); 467 } 468 469 ATF_TC_BODY(canrecvfrom, tc) 470 { 471 const char ifname[] = "canlo0"; 472 int s1, rv1; 473 int s2, rv2; 474 struct can_frame cf_send, cf_receive1, cf_receive2; 475 int ifindex; 476 struct sockaddr_can sa; 477 478 rump_init(); 479 cancfg_rump_createif(ifname); 480 481 memset(&cf_send, 0, sizeof(cf_send)); 482 cf_send.can_id = 1; 483 cf_send.can_dlc = 8; 484 cf_send.data[0] = 0xde; 485 cf_send.data[1] = 0xad; 486 cf_send.data[2] = 0xbe; 487 cf_send.data[3] = 0xef; 488 489 490 s1 = -1; 491 if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 492 atf_tc_fail_errno("CAN socket"); 493 } 494 495 /* create a second socket */ 496 497 s2 = can_socket_with_own(); 498 499 ifindex = can_bind(s2, ifname); 500 501 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) { 502 atf_tc_fail_errno("write"); 503 } 504 505 if (can_read(s2, &cf_receive2, &rv2) < 0) { 506 atf_tc_fail_errno("can_read"); 507 } 508 509 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0, 510 "received (2) packet is not what we sent"); 511 512 /* now check first socket */ 513 memset(&sa, 0, sizeof(sa)); 514 if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) { 515 atf_tc_fail_errno("can_recvfrom"); 516 } 517 518 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0, 519 "recvfrom (1) packet is not what we sent"); 520 ATF_CHECK_MSG(sa.can_ifindex == ifindex, 521 "recvfrom provided wrong ifindex %d (!= %d)", 522 sa.can_ifindex, ifindex); 523 } 524 525 ATF_TC(canbindfilter); 526 ATF_TC_HEAD(canbindfilter, tc) 527 { 528 529 atf_tc_set_md_var(tc, "descr", "check that socket bound to an interface doesn't get other interface's messages"); 530 atf_tc_set_md_var(tc, "timeout", "5"); 531 } 532 533 ATF_TC_BODY(canbindfilter, tc) 534 { 535 const char ifname[] = "canlo0"; 536 const char ifname2[] = "canlo1"; 537 int s1, rv1; 538 int s2, rv2; 539 struct sockaddr_can sa; 540 int ifindex2; 541 struct can_frame cf_send, cf_receive1, cf_receive2; 542 543 rump_init(); 544 cancfg_rump_createif(ifname); 545 cancfg_rump_createif(ifname2); 546 547 memset(&cf_send, 0, sizeof(cf_send)); 548 cf_send.can_id = 1; 549 cf_send.can_dlc = 8; 550 cf_send.data[0] = 0xde; 551 cf_send.data[1] = 0xad; 552 cf_send.data[2] = 0xbe; 553 cf_send.data[3] = 0xef; 554 555 556 s1 = can_socket_with_own(); 557 558 can_bind(s1, ifname); 559 560 /* create a second socket */ 561 562 s2 = can_socket_with_own(); 563 564 ifindex2 = can_bind(s2, ifname2); 565 566 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) { 567 atf_tc_fail_errno("write"); 568 } 569 570 if (can_read(s2, &cf_receive2, &rv2) < 0) { 571 atf_tc_fail_errno("read"); 572 } 573 574 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0, 575 "received (2) packet is not what we sent"); 576 577 /* now check first socket */ 578 if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) { 579 if (errno == EWOULDBLOCK) { 580 /* expected case */ 581 return; 582 } 583 atf_tc_fail_errno("can_recvfrom"); 584 } 585 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0, 586 "recvfrom (1) packet is not what we sent"); 587 ATF_CHECK_MSG(sa.can_ifindex == ifindex2, 588 "recvfrom provided wrong ifindex %d (!= %d)", 589 sa.can_ifindex, ifindex2); 590 atf_tc_fail("we got message from other interface"); 591 } 592 593 ATF_TC(cannoloop); 594 ATF_TC_HEAD(cannoloop, tc) 595 { 596 597 atf_tc_set_md_var(tc, "descr", "check that disabling loopback works"); 598 atf_tc_set_md_var(tc, "timeout", "5"); 599 } 600 601 ATF_TC_BODY(cannoloop, tc) 602 { 603 const char ifname[] = "canlo0"; 604 int s1, rv1; 605 int s2, rv2; 606 int v; 607 socklen_t vlen; 608 struct sockaddr_can sa; 609 struct can_frame cf_send, cf_receive1, cf_receive2; 610 socklen_t salen; 611 int ifindex; 612 fd_set rfds; 613 struct timeval tmout; 614 615 rump_init(); 616 cancfg_rump_createif(ifname); 617 618 memset(&cf_send, 0, sizeof(cf_send)); 619 cf_send.can_id = 1; 620 cf_send.can_dlc = 8; 621 cf_send.data[0] = 0xde; 622 cf_send.data[1] = 0xad; 623 cf_send.data[2] = 0xbe; 624 cf_send.data[3] = 0xef; 625 626 627 s1 = can_socket_with_own(); 628 v = 0; 629 if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK, 630 &v, sizeof(v)) < 0) { 631 atf_tc_fail_errno("setsockopt(LOOPBACK)"); 632 } 633 v = -1; 634 vlen = sizeof(v); 635 if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK, 636 &v, &vlen) < 0) { 637 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)"); 638 } 639 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen); 640 ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off"); 641 642 ifindex = can_bind(s1, ifname); 643 644 /* create a second socket */ 645 s2 = can_socket_with_own(); 646 647 if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) { 648 atf_tc_fail_errno("write"); 649 } 650 651 652 /* now check the sockets */ 653 memset(&cf_receive1, 0, sizeof(cf_receive1)); 654 memset(&cf_receive2, 0, sizeof(cf_receive2)); 655 FD_ZERO(&rfds); 656 FD_SET(s1, &rfds); 657 FD_SET(s2, &rfds); 658 /* we should receive no message; wait for 1 seconds */ 659 tmout.tv_sec = 1; 660 tmout.tv_usec = 0; 661 rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout); 662 switch(rv1) { 663 case -1: 664 atf_tc_fail_errno("select"); 665 break; 666 case 0: 667 /* timeout: expected case */ 668 return; 669 default: break; 670 } 671 salen = sizeof(sa); 672 ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds), 673 "select returns but s1 nor s2 is in set"); 674 if (FD_ISSET(s1, &rfds)) { 675 if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1, 676 sizeof(cf_receive1), 0, 677 (struct sockaddr *)&sa, &salen)) < 0) { 678 atf_tc_fail_errno("recvfrom"); 679 } 680 681 ATF_CHECK_MSG(rv1 > 0, "short read on socket"); 682 683 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, 684 sizeof(cf_send)) == 0, 685 "recvfrom (1) packet is not what we sent"); 686 ATF_CHECK_MSG(sa.can_family == AF_CAN, 687 "recvfrom provided wrong %d family", sa.can_family); 688 ATF_CHECK_MSG(salen == sizeof(sa), 689 "recvfrom provided wrong size %u (!= %zu)", 690 salen, sizeof(sa)); 691 ATF_CHECK_MSG(sa.can_ifindex == ifindex, 692 "recvfrom provided wrong ifindex %d (!= %d)", 693 sa.can_ifindex, ifindex); 694 atf_tc_fail_nonfatal("we got message on s1"); 695 } 696 if (FD_ISSET(s2, &rfds)) { 697 if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2, 698 sizeof(cf_receive2), 0, 699 (struct sockaddr *)&sa, &salen)) < 0) { 700 atf_tc_fail_errno("recvfrom"); 701 } 702 703 ATF_CHECK_MSG(rv2 > 0, "short read on socket"); 704 705 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, 706 sizeof(cf_send)) == 0, 707 "recvfrom (2) packet is not what we sent"); 708 ATF_CHECK_MSG(sa.can_family == AF_CAN, 709 "recvfrom provided wrong %d family", sa.can_family); 710 ATF_CHECK_MSG(salen == sizeof(sa), 711 "recvfrom provided wrong size %u (!= %zu)", 712 salen, sizeof(sa)); 713 ATF_CHECK_MSG(sa.can_ifindex == ifindex, 714 "recvfrom provided wrong ifindex %d (!= %d)", 715 sa.can_ifindex, ifindex); 716 atf_tc_fail_nonfatal("we got message on s2"); 717 } 718 } 719 720 ATF_TC(canbindunknown); 721 ATF_TC_HEAD(canbindunknown, tc) 722 { 723 724 atf_tc_set_md_var(tc, "descr", "check that bind to unknown interface fails"); 725 atf_tc_set_md_var(tc, "timeout", "5"); 726 } 727 728 ATF_TC_BODY(canbindunknown, tc) 729 { 730 struct sockaddr_can sa; 731 int r, s; 732 733 rump_init(); 734 735 s = can_socket_with_own(); 736 737 sa.can_family = AF_CAN; 738 sa.can_ifindex = 10; /* should not exist */ 739 740 r = rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)); 741 742 ATF_CHECK_MSG(r < 0, "bind() didn't fail (%d)", r); 743 } 744 745 ATF_TP_ADD_TCS(tp) 746 { 747 748 ATF_TP_ADD_TC(tp, canlocreate); 749 ATF_TP_ADD_TC(tp, cannoown); 750 ATF_TP_ADD_TC(tp, canwritelo); 751 ATF_TP_ADD_TC(tp, canwriteunbound); 752 ATF_TP_ADD_TC(tp, cansendtolo); 753 ATF_TP_ADD_TC(tp, cansendtowrite); 754 ATF_TP_ADD_TC(tp, canreadlocal); 755 ATF_TP_ADD_TC(tp, canrecvfrom); 756 ATF_TP_ADD_TC(tp, canbindfilter); 757 ATF_TP_ADD_TC(tp, cannoloop); 758 ATF_TP_ADD_TC(tp, canbindunknown); 759 return atf_no_error(); 760 } 761