Home | History | Annotate | Line # | Download | only in can
t_can.c revision 1.1.2.2
      1 /*	$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer 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.1.2.2 2017/01/16 18:04:27 bouyer Exp $");
     36 #endif /* not lint */
     37 
     38 #include <sys/types.h>
     39 #include <sys/resource.h>
     40 #include <sys/sysctl.h>
     41 #include <sys/wait.h>
     42 #include <sys/sockio.h>
     43 #include <sys/param.h>
     44 
     45 #include <atf-c.h>
     46 #include <assert.h>
     47 #include <fcntl.h>
     48 #include <stdio.h>
     49 #include <stdlib.h>
     50 #include <string.h>
     51 #include <unistd.h>
     52 #include <signal.h>
     53 
     54 #include <net/if.h>
     55 #include <netcan/can.h>
     56 
     57 #include <rump/rump.h>
     58 #include <rump/rump_syscalls.h>
     59 
     60 #include "h_macros.h"
     61 
     62 static void
     63 cancfg_rump_createif(const char *ifname)
     64 {
     65 	int s, rv;
     66 	struct ifreq ifr;
     67 
     68 	s = -1;
     69 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
     70 		atf_tc_fail_errno("if config socket");
     71 	}
     72 
     73 	memset(&ifr, 0, sizeof(ifr));
     74 	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     75 
     76 	if ((rv = rump_sys_ioctl(s, SIOCIFCREATE, &ifr)) < 0) {
     77 		atf_tc_fail_errno("if config create");
     78 	}
     79 
     80 	memset(&ifr, 0, sizeof(ifr));
     81 	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
     82 
     83 	if ((rv = rump_sys_ioctl(s, SIOCGIFFLAGS, &ifr)) < 0) {
     84 		atf_tc_fail_errno("if config get flags");
     85 	}
     86 
     87 	ifr.ifr_flags |= IFF_UP;
     88 	if ((rv = rump_sys_ioctl(s, SIOCSIFFLAGS, &ifr)) < 0) {
     89 		atf_tc_fail_errno("if config set flags");
     90 	}
     91 }
     92 
     93 ATF_TC(canlocreate);
     94 ATF_TC_HEAD(canlocreate, tc)
     95 {
     96 
     97 	atf_tc_set_md_var(tc, "descr", "check CAN loopback create/destroy");
     98 	atf_tc_set_md_var(tc, "timeout", "5");
     99 }
    100 
    101 ATF_TC_BODY(canlocreate, tc)
    102 {
    103 	const char ifname[] = "canlo0";
    104 	int s, rv;
    105 	struct ifreq ifr;
    106 
    107 	rump_init();
    108 	cancfg_rump_createif(ifname);
    109 
    110 	s = -1;
    111 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    112 		atf_tc_fail_errno("if config socket(2)");
    113 	}
    114 
    115 	memset(&ifr, 0, sizeof(ifr));
    116 	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    117 
    118 	if ((rv = rump_sys_ioctl(s, SIOCIFDESTROY, &ifr)) < 0) {
    119 		atf_tc_fail_errno("if config destroy");
    120 	}
    121 }
    122 
    123 ATF_TC(cannoown);
    124 ATF_TC_HEAD(cannoown, tc)
    125 {
    126 
    127 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets don't gets its own message");
    128 	atf_tc_set_md_var(tc, "timeout", "5");
    129 }
    130 
    131 ATF_TC_BODY(cannoown, tc)
    132 {
    133 	const char ifname[] = "canlo0";
    134 	int s, rv, v, vlen;
    135 	struct sockaddr_can sa;
    136 	int salen;
    137 	struct ifreq ifr;
    138 	struct can_frame cf_send, cf_receive;
    139 	fd_set rfds;
    140 	struct timeval tmout;
    141 
    142 	rump_init();
    143 	cancfg_rump_createif(ifname);
    144 
    145 	s = -1;
    146 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    147 		atf_tc_fail_errno("CAN socket");
    148 	}
    149 
    150 	strcpy(ifr.ifr_name, ifname );
    151 	if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
    152 		atf_tc_fail_errno("SIOCGIFINDEX");
    153 	}
    154 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    155 	    ifname, ifr.ifr_ifindex);
    156 
    157 	sa.can_family = AF_CAN;
    158 	sa.can_ifindex = ifr.ifr_ifindex;
    159 
    160 	if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    161 		atf_tc_fail_errno("bind");
    162 	}
    163 
    164 	/* check sockopt CAN_RAW_LOOPBACK */
    165 	vlen = sizeof(v);
    166 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
    167 	    &v, &vlen) < 0) {
    168 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
    169 	}
    170 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
    171 	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
    172 
    173 	/* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
    174 	vlen = sizeof(v);
    175 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    176 	    &v, &vlen) < 0) {
    177 		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
    178 	}
    179 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
    180 	ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
    181 
    182 	/*
    183 	 * send a single byte message, but make sure remaining payload is
    184 	 * not 0.
    185 	 */
    186 
    187 	memset(&cf_send, 0, sizeof(cf_send));
    188 	cf_send.can_id = 1;
    189 	cf_send.can_dlc = 1;
    190 	cf_send.data[0] = 0xde;
    191 	cf_send.data[1] = 0xad;
    192 	cf_send.data[2] = 0xbe;
    193 	cf_send.data[3] = 0xef;
    194 
    195 	if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
    196 		atf_tc_fail_errno("write");
    197 	}
    198 
    199 	/* now try to read */
    200 
    201 	memset(&cf_receive, 0, sizeof(cf_receive));
    202 	FD_ZERO(&rfds);
    203 	FD_SET(s, &rfds);
    204 	/* we should receive no message; wait for 2 seconds */
    205 	tmout.tv_sec = 2;
    206 	tmout.tv_usec = 0;
    207 	rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
    208 	switch(rv) {
    209 	case -1:
    210 		atf_tc_fail_errno("select");
    211 		break;
    212 	case 0:
    213 		/* timeout: expected case */
    214 		return;
    215 	default: break;
    216 	}
    217 	salen = sizeof(sa);
    218 	ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
    219 	if (( rv = rump_sys_recvfrom(s, &cf_receive, sizeof(cf_receive),
    220 	    0, (struct sockaddr *)&sa, &salen)) < 0) {
    221 		atf_tc_fail_errno("recvfrom");
    222 	}
    223 
    224 	ATF_CHECK_MSG(rv > 0, "short read on socket");
    225 
    226 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
    227 	    "recvfrom packet is not what we sent");
    228 	ATF_CHECK_MSG(sa.can_family == AF_CAN,
    229 	    "recvfrom provided wrong %d family", sa.can_family);
    230 	ATF_CHECK_MSG(salen == sizeof(sa),
    231 	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
    232 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
    233 	   "recvfrom provided wrong ifindex %d (!= %d)",
    234 	    sa.can_ifindex, ifr.ifr_ifindex);
    235 	atf_tc_fail("we got our own message");
    236 }
    237 
    238 ATF_TC(canwritelo);
    239 ATF_TC_HEAD(canwritelo, tc)
    240 {
    241 
    242 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via write");
    243 	atf_tc_set_md_var(tc, "timeout", "5");
    244 }
    245 
    246 ATF_TC_BODY(canwritelo, tc)
    247 {
    248 	const char ifname[] = "canlo0";
    249 	int s, rv, v, vlen;
    250 	struct sockaddr_can sa;
    251 	struct ifreq ifr;
    252 	struct can_frame cf_send, cf_receive;
    253 
    254 	rump_init();
    255 	cancfg_rump_createif(ifname);
    256 
    257 	s = -1;
    258 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    259 		atf_tc_fail_errno("CAN socket");
    260 	}
    261 
    262 	strcpy(ifr.ifr_name, ifname );
    263 	if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
    264 		atf_tc_fail_errno("SIOCGIFINDEX");
    265 	}
    266 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    267 	    ifname, ifr.ifr_ifindex);
    268 
    269 	sa.can_family = AF_CAN;
    270 	sa.can_ifindex = ifr.ifr_ifindex;
    271 
    272 	if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    273 		atf_tc_fail_errno("bind");
    274 	}
    275 
    276 	/* check sockopt CAN_RAW_LOOPBACK */
    277 	vlen = sizeof(v);
    278 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
    279 	    &v, &vlen) < 0) {
    280 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
    281 	}
    282 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
    283 	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
    284 
    285 	/* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
    286 	vlen = sizeof(v);
    287 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    288 	    &v, &vlen) < 0) {
    289 		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
    290 	}
    291 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
    292 	ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
    293 	v = 1;
    294 	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    295 	    &v, sizeof(v)) < 0) {
    296 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    297 	}
    298 	/* check sockopt CAN_RAW_RECV_OWN_MSGS again */
    299 	vlen = sizeof(v);
    300 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    301 	    &v, &vlen) < 0) {
    302 		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
    303 	}
    304 	ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on");
    305 
    306 	/*
    307 	 * send a single byte message, but make sure remaining payload is
    308 	 * not 0.
    309 	 */
    310 
    311 	memset(&cf_send, 0, sizeof(cf_send));
    312 	cf_send.can_id = 1;
    313 	cf_send.can_dlc = 1;
    314 	cf_send.data[0] = 0xde;
    315 	cf_send.data[1] = 0xad;
    316 	cf_send.data[2] = 0xbe;
    317 	cf_send.data[3] = 0xef;
    318 
    319 	if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
    320 		atf_tc_fail_errno("write");
    321 	}
    322 
    323 	memset(&cf_receive, 0, sizeof(cf_receive));
    324 	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
    325 		atf_tc_fail_errno("read");
    326 	}
    327 
    328 	ATF_CHECK_MSG(rv > 0, "short read on socket");
    329 
    330 	memset(&cf_send, 0, sizeof(cf_send));
    331 	cf_send.can_id = 1;
    332 	cf_send.can_dlc = 1;
    333 	cf_send.data[0] = 0xde;
    334 	/* other data[] are expected to be 0 */
    335 
    336 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
    337 	    "received packet is not what we sent");
    338 }
    339 
    340 ATF_TC(canwriteunbound);
    341 ATF_TC_HEAD(canwriteunbound, tc)
    342 {
    343 
    344 	atf_tc_set_md_var(tc, "descr", "check that write to unbound CAN sockets fails");
    345 	atf_tc_set_md_var(tc, "timeout", "5");
    346 }
    347 
    348 ATF_TC_BODY(canwriteunbound, tc)
    349 {
    350 	const char ifname[] = "canlo0";
    351 	int s, rv;
    352 	struct sockaddr_can sa;
    353 	struct can_frame cf_send;
    354 
    355 	rump_init();
    356 	cancfg_rump_createif(ifname);
    357 
    358 	s = -1;
    359 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    360 		atf_tc_fail_errno("CAN socket");
    361 	}
    362 
    363 	/*
    364 	 * send a single byte message.
    365 	 * not 0.
    366 	 */
    367 
    368 	memset(&cf_send, 0, sizeof(cf_send));
    369 	cf_send.can_id = 1;
    370 	cf_send.can_dlc = 1;
    371 	cf_send.data[0] = 0xde;
    372 
    373 	rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
    374 	ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
    375 	    "write to unbound socket didn't fail");
    376 }
    377 
    378 ATF_TC(cansendtolo);
    379 ATF_TC_HEAD(cansendtolo, tc)
    380 {
    381 
    382 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via sendto");
    383 	atf_tc_set_md_var(tc, "timeout", "5");
    384 }
    385 
    386 ATF_TC_BODY(cansendtolo, tc)
    387 {
    388 	const char ifname[] = "canlo0";
    389 	int s, v, rv;
    390 	struct sockaddr_can sa;
    391 	struct ifreq ifr;
    392 	struct can_frame cf_send, cf_receive;
    393 
    394 	rump_init();
    395 	cancfg_rump_createif(ifname);
    396 
    397 	s = -1;
    398 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    399 		atf_tc_fail_errno("CAN socket");
    400 	}
    401 
    402 	v = 1;
    403 	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    404 	    &v, sizeof(v)) < 0) {
    405 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    406 	}
    407 
    408 	strcpy(ifr.ifr_name, ifname );
    409 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
    410 		atf_tc_fail_errno("SIOCGIFINDEX");
    411 	}
    412 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    413 	    ifname, ifr.ifr_ifindex);
    414 
    415 	sa.can_family = AF_CAN;
    416 	sa.can_ifindex = ifr.ifr_ifindex;
    417 
    418 	/*
    419 	 * send a single byte message, but make sure remaining payload is
    420 	 * not 0.
    421 	 */
    422 
    423 	memset(&cf_send, 0, sizeof(cf_send));
    424 	cf_send.can_id = 1;
    425 	cf_send.can_dlc = 1;
    426 	cf_send.data[0] = 0xde;
    427 	cf_send.data[1] = 0xad;
    428 	cf_send.data[2] = 0xbe;
    429 	cf_send.data[3] = 0xef;
    430 
    431 	if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
    432 	    0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    433 		atf_tc_fail_errno("sendto");
    434 	}
    435 
    436 	memset(&cf_receive, 0, sizeof(cf_receive));
    437 	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
    438 		atf_tc_fail_errno("read");
    439 	}
    440 
    441 	ATF_CHECK_MSG(rv > 0, "short read on socket");
    442 
    443 	memset(&cf_send, 0, sizeof(cf_send));
    444 	cf_send.can_id = 1;
    445 	cf_send.can_dlc = 1;
    446 	cf_send.data[0] = 0xde;
    447 	/* other data[] are expected to be 0 */
    448 
    449 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
    450 	    "received packet is not what we sent");
    451 }
    452 
    453 ATF_TC(cansendtowrite);
    454 ATF_TC_HEAD(cansendtowrite, tc)
    455 {
    456 
    457 	atf_tc_set_md_var(tc, "descr", "check that write after sendto on unbound socket fails");
    458 	atf_tc_set_md_var(tc, "timeout", "5");
    459 }
    460 
    461 ATF_TC_BODY(cansendtowrite, tc)
    462 {
    463 	const char ifname[] = "canlo0";
    464 	int s, rv, v;
    465 	struct sockaddr_can sa;
    466 	struct ifreq ifr;
    467 	struct can_frame cf_send, cf_receive;
    468 
    469 	rump_init();
    470 	cancfg_rump_createif(ifname);
    471 
    472 	s = -1;
    473 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    474 		atf_tc_fail_errno("CAN socket");
    475 	}
    476 	v = 1;
    477 	if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    478 	    &v, sizeof(v)) < 0) {
    479 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    480 	}
    481 
    482 	strcpy(ifr.ifr_name, ifname );
    483 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
    484 		atf_tc_fail_errno("SIOCGIFINDEX");
    485 	}
    486 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    487 	    ifname, ifr.ifr_ifindex);
    488 
    489 	sa.can_family = AF_CAN;
    490 	sa.can_ifindex = ifr.ifr_ifindex;
    491 
    492 	/*
    493 	 * send a single byte message.
    494 	 * not 0.
    495 	 */
    496 
    497 	memset(&cf_send, 0, sizeof(cf_send));
    498 	cf_send.can_id = 1;
    499 	cf_send.can_dlc = 1;
    500 	cf_send.data[0] = 0xde;
    501 
    502 	if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
    503 	    0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    504 		atf_tc_fail_errno("sendto");
    505 	}
    506 
    507 	memset(&cf_receive, 0, sizeof(cf_receive));
    508 	if (( rv = rump_sys_read(s, &cf_receive, sizeof(cf_receive))) < 0) {
    509 		atf_tc_fail_errno("read");
    510 	}
    511 
    512 	ATF_CHECK_MSG(rv > 0, "short read on socket");
    513 
    514 	memset(&cf_send, 0, sizeof(cf_send));
    515 	cf_send.can_id = 1;
    516 	cf_send.can_dlc = 1;
    517 	cf_send.data[0] = 0xde;
    518 	/* other data[] are expected to be 0 */
    519 
    520 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
    521 	    "received packet is not what we sent");
    522 
    523 	rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
    524 	ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
    525 	    "write to unbound socket didn't fail");
    526 }
    527 
    528 ATF_TC(canreadlocal);
    529 ATF_TC_HEAD(canreadlocal, tc)
    530 {
    531 
    532 	atf_tc_set_md_var(tc, "descr", "check all CAN sockets get messages");
    533 	atf_tc_set_md_var(tc, "timeout", "5");
    534 }
    535 
    536 ATF_TC_BODY(canreadlocal, tc)
    537 {
    538 	const char ifname[] = "canlo0";
    539 	int s1, rv1;
    540 	int s2, rv2;
    541 	int v;
    542 	struct sockaddr_can sa;
    543 	struct ifreq ifr;
    544 	struct can_frame cf_send, cf_receive1, cf_receive2;
    545 
    546 	rump_init();
    547 	cancfg_rump_createif(ifname);
    548 
    549 	memset(&cf_send, 0, sizeof(cf_send));
    550 	cf_send.can_id = 1;
    551 	cf_send.can_dlc = 8;
    552 	cf_send.data[0] = 0xde;
    553 	cf_send.data[1] = 0xad;
    554 	cf_send.data[2] = 0xbe;
    555 	cf_send.data[3] = 0xef;
    556 
    557 
    558 	s1 = -1;
    559 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    560 		atf_tc_fail_errno("CAN socket");
    561 	}
    562 
    563 	/* create a second socket */
    564 
    565 	s2 = -1;
    566 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    567 		atf_tc_fail_errno("CAN socket");
    568 	}
    569 	v = 1;
    570 	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    571 	    &v, sizeof(v)) < 0) {
    572 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    573 	}
    574 
    575 	strcpy(ifr.ifr_name, ifname );
    576 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
    577 		atf_tc_fail_errno("SIOCGIFINDEX");
    578 	}
    579 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    580 	    ifname, ifr.ifr_ifindex);
    581 
    582 	sa.can_family = AF_CAN;
    583 	sa.can_ifindex = ifr.ifr_ifindex;
    584 
    585 	if ((rv2 = rump_sys_bind(s2, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
    586 		atf_tc_fail_errno("bind");
    587 	}
    588 
    589 	/*
    590 	 * send a single byte message, but make sure remaining payload is
    591 	 * not 0.
    592 	 */
    593 
    594 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
    595 		atf_tc_fail_errno("write");
    596 	}
    597 
    598 	memset(&cf_receive2, 0, sizeof(cf_receive2));
    599 	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
    600 		atf_tc_fail_errno("read");
    601 	}
    602 
    603 	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
    604 
    605 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
    606 	    "received (2) packet is not what we sent");
    607 
    608 	/* now check first socket */
    609 	memset(&cf_receive1, 0, sizeof(cf_receive1));
    610 	if (( rv1 = rump_sys_read(s1, &cf_receive1, sizeof(cf_receive1))) < 0) {
    611 		atf_tc_fail_errno("read");
    612 	}
    613 
    614 	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
    615 
    616 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
    617 	    "received (1) packet is not what we sent");
    618 }
    619 
    620 ATF_TC(canrecvfrom);
    621 ATF_TC_HEAD(canrecvfrom, tc)
    622 {
    623 
    624 	atf_tc_set_md_var(tc, "descr", "check that recvfrom gets the CAN interface");
    625 	atf_tc_set_md_var(tc, "timeout", "5");
    626 }
    627 
    628 ATF_TC_BODY(canrecvfrom, tc)
    629 {
    630 	const char ifname[] = "canlo0";
    631 	int s1, rv1;
    632 	int s2, rv2;
    633 	int v;
    634 	struct sockaddr_can sa;
    635 	struct ifreq ifr;
    636 	struct can_frame cf_send, cf_receive1, cf_receive2;
    637 	socklen_t salen;
    638 
    639 	rump_init();
    640 	cancfg_rump_createif(ifname);
    641 
    642 	memset(&cf_send, 0, sizeof(cf_send));
    643 	cf_send.can_id = 1;
    644 	cf_send.can_dlc = 8;
    645 	cf_send.data[0] = 0xde;
    646 	cf_send.data[1] = 0xad;
    647 	cf_send.data[2] = 0xbe;
    648 	cf_send.data[3] = 0xef;
    649 
    650 
    651 	s1 = -1;
    652 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    653 		atf_tc_fail_errno("CAN socket");
    654 	}
    655 
    656 	/* create a second socket */
    657 
    658 	s2 = -1;
    659 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    660 		atf_tc_fail_errno("CAN socket");
    661 	}
    662 	v = 1;
    663 	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    664 	    &v, sizeof(v)) < 0) {
    665 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    666 	}
    667 
    668 	strcpy(ifr.ifr_name, ifname );
    669 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
    670 		atf_tc_fail_errno("SIOCGIFINDEX");
    671 	}
    672 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    673 	    ifname, ifr.ifr_ifindex);
    674 
    675 	sa.can_family = AF_CAN;
    676 	sa.can_ifindex = ifr.ifr_ifindex;
    677 
    678 	if ((rv2 = rump_sys_bind(s2, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
    679 		atf_tc_fail_errno("bind");
    680 	}
    681 
    682 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
    683 		atf_tc_fail_errno("write");
    684 	}
    685 
    686 	memset(&cf_receive2, 0, sizeof(cf_receive2));
    687 	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
    688 		atf_tc_fail_errno("read");
    689 	}
    690 
    691 	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
    692 
    693 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
    694 	    "received (2) packet is not what we sent");
    695 
    696 	/* now check first socket */
    697 	memset(&cf_receive1, 0, sizeof(cf_receive1));
    698 	memset(&sa, 0, sizeof(sa));
    699 	salen = sizeof(sa);
    700 	if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1, sizeof(cf_receive1),
    701 	    0, (struct sockaddr *)&sa, &salen)) < 0) {
    702 		atf_tc_fail_errno("recvfrom");
    703 	}
    704 
    705 	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
    706 
    707 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
    708 	    "recvfrom (1) packet is not what we sent");
    709 	ATF_CHECK_MSG(sa.can_family == AF_CAN,
    710 	    "recvfrom provided wrong %d family", sa.can_family);
    711 	ATF_CHECK_MSG(salen == sizeof(sa),
    712 	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
    713 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
    714 	   "recvfrom provided wrong ifindex %d (!= %d)",
    715 	    sa.can_ifindex, ifr.ifr_ifindex);
    716 }
    717 
    718 ATF_TC(canbindfilter);
    719 ATF_TC_HEAD(canbindfilter, tc)
    720 {
    721 
    722 	atf_tc_set_md_var(tc, "descr", "check that  socket bound to an interface doens't get other interface's messages");
    723 	atf_tc_set_md_var(tc, "timeout", "5");
    724 }
    725 
    726 ATF_TC_BODY(canbindfilter, tc)
    727 {
    728 	const char ifname[] = "canlo0";
    729 	const char ifname2[] = "canlo1";
    730 	int s1, rv1;
    731 	int s2, rv2;
    732 	int v;
    733 	struct sockaddr_can sa;
    734 	struct ifreq ifr;
    735 	struct can_frame cf_send, cf_receive1, cf_receive2;
    736 	socklen_t salen;
    737 	fd_set rfds;
    738 	struct timeval tmout;
    739 
    740 	rump_init();
    741 	cancfg_rump_createif(ifname);
    742 	cancfg_rump_createif(ifname2);
    743 
    744 	memset(&cf_send, 0, sizeof(cf_send));
    745 	cf_send.can_id = 1;
    746 	cf_send.can_dlc = 8;
    747 	cf_send.data[0] = 0xde;
    748 	cf_send.data[1] = 0xad;
    749 	cf_send.data[2] = 0xbe;
    750 	cf_send.data[3] = 0xef;
    751 
    752 
    753 	s1 = -1;
    754 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    755 		atf_tc_fail_errno("CAN socket");
    756 	}
    757 	v = 1;
    758 	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    759 	    &v, sizeof(v)) < 0) {
    760 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    761 	}
    762 
    763 	strcpy(ifr.ifr_name, ifname );
    764 	if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
    765 		atf_tc_fail_errno("SIOCGIFINDEX (1)");
    766 	}
    767 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    768 	    ifname, ifr.ifr_ifindex);
    769 
    770 	sa.can_family = AF_CAN;
    771 	sa.can_ifindex = ifr.ifr_ifindex;
    772 
    773 	if ((rv1 = rump_sys_bind(s1, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
    774 		atf_tc_fail_errno("bind (1)");
    775 	}
    776 
    777 	/* create a second socket */
    778 
    779 	s2 = -1;
    780 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    781 		atf_tc_fail_errno("CAN socket");
    782 	}
    783 	v = 1;
    784 	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    785 	    &v, sizeof(v)) < 0) {
    786 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    787 	}
    788 
    789 	strcpy(ifr.ifr_name, ifname2);
    790 	if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
    791 		atf_tc_fail_errno("SIOCGIFINDEX");
    792 	}
    793 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    794 	    ifname, ifr.ifr_ifindex);
    795 
    796 	sa.can_family = AF_CAN;
    797 	sa.can_ifindex = ifr.ifr_ifindex;
    798 
    799 	if ((rv2 = rump_sys_bind(s2, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
    800 		atf_tc_fail_errno("bind");
    801 	}
    802 
    803 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
    804 		atf_tc_fail_errno("write");
    805 	}
    806 
    807 	memset(&cf_receive2, 0, sizeof(cf_receive2));
    808 	if (( rv2 = rump_sys_read(s2, &cf_receive2, sizeof(cf_receive2))) < 0) {
    809 		atf_tc_fail_errno("read");
    810 	}
    811 
    812 	ATF_CHECK_MSG(rv2 > 0, "short read on socket");
    813 
    814 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
    815 	    "received (2) packet is not what we sent");
    816 
    817 	/* now check first socket */
    818 	memset(&cf_receive1, 0, sizeof(cf_receive1));
    819 	FD_ZERO(&rfds);
    820 	FD_SET(s1, &rfds);
    821 	/* we should receive no message; wait for 2 seconds */
    822 	tmout.tv_sec = 2;
    823 	tmout.tv_usec = 0;
    824 	rv1 = rump_sys_select(s1 + 1, &rfds, NULL, NULL, &tmout);
    825 	switch(rv1) {
    826 	case -1:
    827 		atf_tc_fail_errno("select");
    828 		break;
    829 	case 0:
    830 		/* timeout: expected case */
    831 		return;
    832 	default: break;
    833 	}
    834 	salen = sizeof(sa);
    835 	ATF_CHECK_MSG(FD_ISSET(s1, &rfds), "select returns but s1 not in set");
    836 	if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1, sizeof(cf_receive1),
    837 	    0, (struct sockaddr *)&sa, &salen)) < 0) {
    838 		atf_tc_fail_errno("recvfrom");
    839 	}
    840 
    841 	ATF_CHECK_MSG(rv1 > 0, "short read on socket");
    842 
    843 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
    844 	    "recvfrom (1) packet is not what we sent");
    845 	ATF_CHECK_MSG(sa.can_family == AF_CAN,
    846 	    "recvfrom provided wrong %d family", sa.can_family);
    847 	ATF_CHECK_MSG(salen == sizeof(sa),
    848 	    "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
    849 	ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
    850 	   "recvfrom provided wrong ifindex %d (!= %d)",
    851 	    sa.can_ifindex, ifr.ifr_ifindex);
    852 	atf_tc_fail("we got message from other interface");
    853 }
    854 
    855 ATF_TC(cannoloop);
    856 ATF_TC_HEAD(cannoloop, tc)
    857 {
    858 
    859 	atf_tc_set_md_var(tc, "descr", "check that disabling loopback works");
    860 	atf_tc_set_md_var(tc, "timeout", "5");
    861 }
    862 
    863 ATF_TC_BODY(cannoloop, tc)
    864 {
    865 	const char ifname[] = "canlo0";
    866 	int s1, rv1;
    867 	int s2, rv2;
    868 	int v, vlen;
    869 	struct sockaddr_can sa;
    870 	struct ifreq ifr;
    871 	struct can_frame cf_send, cf_receive1, cf_receive2;
    872 	socklen_t salen;
    873 	fd_set rfds;
    874 	struct timeval tmout;
    875 
    876 	rump_init();
    877 	cancfg_rump_createif(ifname);
    878 
    879 	memset(&cf_send, 0, sizeof(cf_send));
    880 	cf_send.can_id = 1;
    881 	cf_send.can_dlc = 8;
    882 	cf_send.data[0] = 0xde;
    883 	cf_send.data[1] = 0xad;
    884 	cf_send.data[2] = 0xbe;
    885 	cf_send.data[3] = 0xef;
    886 
    887 
    888 	s1 = -1;
    889 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    890 		atf_tc_fail_errno("CAN socket");
    891 	}
    892 	v = 1;
    893 	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    894 	    &v, sizeof(v)) < 0) {
    895 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    896 	}
    897 	v = 0;
    898 	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
    899 	    &v, sizeof(v)) < 0) {
    900 		atf_tc_fail_errno("setsockopt(LOOPBACK)");
    901 	}
    902 	v = -1;
    903 	vlen = sizeof(v);
    904 	if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
    905 	    &v, &vlen) < 0) {
    906 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
    907 	}
    908 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
    909 	ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off");
    910 
    911 	strcpy(ifr.ifr_name, ifname );
    912 	if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
    913 		atf_tc_fail_errno("SIOCGIFINDEX (1)");
    914 	}
    915 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
    916 	    ifname, ifr.ifr_ifindex);
    917 
    918 	sa.can_family = AF_CAN;
    919 	sa.can_ifindex = ifr.ifr_ifindex;
    920 
    921 	if ((rv1 = rump_sys_bind(s1, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
    922 		atf_tc_fail_errno("bind (1)");
    923 	}
    924 
    925 	/* create a second socket */
    926 
    927 	s2 = -1;
    928 	if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    929 		atf_tc_fail_errno("CAN socket");
    930 	}
    931 	v = 1;
    932 	if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
    933 	    &v, sizeof(v)) < 0) {
    934 		atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
    935 	}
    936 
    937 	if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) {
    938 		atf_tc_fail_errno("write");
    939 	}
    940 
    941 
    942 	/* now check the sockets */
    943 	memset(&cf_receive1, 0, sizeof(cf_receive1));
    944 	memset(&cf_receive2, 0, sizeof(cf_receive2));
    945 	FD_ZERO(&rfds);
    946 	FD_SET(s1, &rfds);
    947 	FD_SET(s2, &rfds);
    948 	/* we should receive no message; wait for 2 seconds */
    949 	tmout.tv_sec = 2;
    950 	tmout.tv_usec = 0;
    951 	rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout);
    952 	switch(rv1) {
    953 	case -1:
    954 		atf_tc_fail_errno("select");
    955 		break;
    956 	case 0:
    957 		/* timeout: expected case */
    958 		return;
    959 	default: break;
    960 	}
    961 	salen = sizeof(sa);
    962 	ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds),
    963 	   "select returns but s1 nor s2 is in set");
    964 	if (FD_ISSET(s1, &rfds)) {
    965 		if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1,
    966 		    sizeof(cf_receive1), 0,
    967 		    (struct sockaddr *)&sa, &salen)) < 0) {
    968 			atf_tc_fail_errno("recvfrom");
    969 		}
    970 
    971 		ATF_CHECK_MSG(rv1 > 0, "short read on socket");
    972 
    973 		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1,
    974 		    sizeof(cf_send)) == 0,
    975 		    "recvfrom (1) packet is not what we sent");
    976 		ATF_CHECK_MSG(sa.can_family == AF_CAN,
    977 		    "recvfrom provided wrong %d family", sa.can_family);
    978 		ATF_CHECK_MSG(salen == sizeof(sa),
    979 		    "recvfrom provided wrong size %d (!= %d)",
    980 		    salen, sizeof(sa));
    981 		ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
    982 		   "recvfrom provided wrong ifindex %d (!= %d)",
    983 		    sa.can_ifindex, ifr.ifr_ifindex);
    984 		atf_tc_fail_nonfatal("we got message on s1");
    985 	}
    986 	if (FD_ISSET(s2, &rfds)) {
    987 		if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2,
    988 		    sizeof(cf_receive2), 0,
    989 		    (struct sockaddr *)&sa, &salen)) < 0) {
    990 			atf_tc_fail_errno("recvfrom");
    991 		}
    992 
    993 		ATF_CHECK_MSG(rv2 > 0, "short read on socket");
    994 
    995 		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2,
    996 		    sizeof(cf_send)) == 0,
    997 		    "recvfrom (2) packet is not what we sent");
    998 		ATF_CHECK_MSG(sa.can_family == AF_CAN,
    999 		    "recvfrom provided wrong %d family", sa.can_family);
   1000 		ATF_CHECK_MSG(salen == sizeof(sa),
   1001 		    "recvfrom provided wrong size %d (!= %d)",
   1002 		    salen, sizeof(sa));
   1003 		ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
   1004 		   "recvfrom provided wrong ifindex %d (!= %d)",
   1005 		    sa.can_ifindex, ifr.ifr_ifindex);
   1006 		atf_tc_fail_nonfatal("we got message on s2");
   1007 	}
   1008 }
   1009 
   1010 ATF_TP_ADD_TCS(tp)
   1011 {
   1012 
   1013         ATF_TP_ADD_TC(tp, canlocreate);
   1014         ATF_TP_ADD_TC(tp, cannoown);
   1015         ATF_TP_ADD_TC(tp, canwritelo);
   1016         ATF_TP_ADD_TC(tp, canwriteunbound);
   1017         ATF_TP_ADD_TC(tp, cansendtolo);
   1018         ATF_TP_ADD_TC(tp, cansendtowrite);
   1019         ATF_TP_ADD_TC(tp, canreadlocal);
   1020         ATF_TP_ADD_TC(tp, canrecvfrom);
   1021         ATF_TP_ADD_TC(tp, canbindfilter);
   1022         ATF_TP_ADD_TC(tp, cannoloop);
   1023 	return atf_no_error();
   1024 }
   1025 
   1026