xref: /netbsd-src/tests/net/can/t_can.c (revision ca7653601e7602f5f52a0aeb07477fbd4eee5276)
1*ca765360Sandvar /*	$NetBSD: t_can.c,v 1.8 2021/08/20 20:25:28 andvar Exp $	*/
26e4cb2b9Sbouyer 
36e4cb2b9Sbouyer /*-
46e4cb2b9Sbouyer  * Copyright (c) 2017 The NetBSD Foundation, Inc.
56e4cb2b9Sbouyer  * All rights reserved.
66e4cb2b9Sbouyer  *
76e4cb2b9Sbouyer  * This code is derived from software contributed to The NetBSD Foundation
86e4cb2b9Sbouyer  * by Manuel Bouyer
96e4cb2b9Sbouyer  *
106e4cb2b9Sbouyer  * Redistribution and use in source and binary forms, with or without
116e4cb2b9Sbouyer  * modification, are permitted provided that the following conditions
126e4cb2b9Sbouyer  * are met:
136e4cb2b9Sbouyer  * 1. Redistributions of source code must retain the above copyright
146e4cb2b9Sbouyer  *    notice, this list of conditions and the following disclaimer.
156e4cb2b9Sbouyer  * 2. Redistributions in binary form must reproduce the above copyright
166e4cb2b9Sbouyer  *    notice, this list of conditions and the following disclaimer in the
176e4cb2b9Sbouyer  *    documentation and/or other materials provided with the distribution.
186e4cb2b9Sbouyer  *
196e4cb2b9Sbouyer  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
206e4cb2b9Sbouyer  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
216e4cb2b9Sbouyer  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
226e4cb2b9Sbouyer  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
236e4cb2b9Sbouyer  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
246e4cb2b9Sbouyer  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
256e4cb2b9Sbouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
266e4cb2b9Sbouyer  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
276e4cb2b9Sbouyer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
286e4cb2b9Sbouyer  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
296e4cb2b9Sbouyer  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
306e4cb2b9Sbouyer  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
316e4cb2b9Sbouyer  */
326e4cb2b9Sbouyer 
336e4cb2b9Sbouyer #include <sys/cdefs.h>
346e4cb2b9Sbouyer #ifndef lint
35*ca765360Sandvar __RCSID("$NetBSD: t_can.c,v 1.8 2021/08/20 20:25:28 andvar Exp $");
366e4cb2b9Sbouyer #endif /* not lint */
376e4cb2b9Sbouyer 
386e4cb2b9Sbouyer #include <sys/types.h>
396e4cb2b9Sbouyer #include <sys/resource.h>
406e4cb2b9Sbouyer #include <sys/wait.h>
416e4cb2b9Sbouyer #include <sys/sockio.h>
426e4cb2b9Sbouyer #include <sys/param.h>
436e4cb2b9Sbouyer 
446e4cb2b9Sbouyer #include <atf-c.h>
456e4cb2b9Sbouyer #include <assert.h>
466e4cb2b9Sbouyer #include <fcntl.h>
476e4cb2b9Sbouyer #include <stdio.h>
486e4cb2b9Sbouyer #include <stdlib.h>
496e4cb2b9Sbouyer #include <string.h>
506e4cb2b9Sbouyer #include <unistd.h>
516e4cb2b9Sbouyer 
526e4cb2b9Sbouyer #include <net/if.h>
536e4cb2b9Sbouyer #include <netcan/can.h>
546e4cb2b9Sbouyer 
556e4cb2b9Sbouyer #include <rump/rump.h>
566e4cb2b9Sbouyer #include <rump/rump_syscalls.h>
576e4cb2b9Sbouyer 
586e4cb2b9Sbouyer #include "h_macros.h"
596e4cb2b9Sbouyer #include "h_canutils.h"
606e4cb2b9Sbouyer 
616e4cb2b9Sbouyer ATF_TC(canlocreate);
ATF_TC_HEAD(canlocreate,tc)626e4cb2b9Sbouyer ATF_TC_HEAD(canlocreate, tc)
636e4cb2b9Sbouyer {
646e4cb2b9Sbouyer 
656e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check CAN loopback create/destroy");
666e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
676e4cb2b9Sbouyer }
686e4cb2b9Sbouyer 
ATF_TC_BODY(canlocreate,tc)696e4cb2b9Sbouyer ATF_TC_BODY(canlocreate, tc)
706e4cb2b9Sbouyer {
716e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
726e4cb2b9Sbouyer 	int s, rv;
736e4cb2b9Sbouyer 	struct ifreq ifr;
746e4cb2b9Sbouyer 
756e4cb2b9Sbouyer 	rump_init();
766e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
776e4cb2b9Sbouyer 
786e4cb2b9Sbouyer 	s = -1;
796e4cb2b9Sbouyer 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
806e4cb2b9Sbouyer 		atf_tc_fail_errno("if config socket(2)");
816e4cb2b9Sbouyer 	}
826e4cb2b9Sbouyer 
836e4cb2b9Sbouyer 	memset(&ifr, 0, sizeof(ifr));
846e4cb2b9Sbouyer 	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
856e4cb2b9Sbouyer 
866e4cb2b9Sbouyer 	if ((rv = rump_sys_ioctl(s, SIOCIFDESTROY, &ifr)) < 0) {
876e4cb2b9Sbouyer 		atf_tc_fail_errno("if config destroy");
886e4cb2b9Sbouyer 	}
896e4cb2b9Sbouyer }
906e4cb2b9Sbouyer 
916e4cb2b9Sbouyer ATF_TC(cannoown);
ATF_TC_HEAD(cannoown,tc)926e4cb2b9Sbouyer ATF_TC_HEAD(cannoown, tc)
936e4cb2b9Sbouyer {
946e4cb2b9Sbouyer 
956e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets don't gets its own message");
966e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
976e4cb2b9Sbouyer }
986e4cb2b9Sbouyer 
ATF_TC_BODY(cannoown,tc)996e4cb2b9Sbouyer ATF_TC_BODY(cannoown, tc)
1006e4cb2b9Sbouyer {
1016e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
1026e4cb2b9Sbouyer 	int s, rv, v;
1036e4cb2b9Sbouyer 	socklen_t vlen;
1046e4cb2b9Sbouyer 	struct sockaddr_can sa;
1056e4cb2b9Sbouyer 	int ifindex;
1066e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive;
1076e4cb2b9Sbouyer 
1086e4cb2b9Sbouyer 	rump_init();
1096e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
1106e4cb2b9Sbouyer 
1116e4cb2b9Sbouyer 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
1126e4cb2b9Sbouyer 		atf_tc_fail_errno("CAN socket");
1136e4cb2b9Sbouyer 	}
1146e4cb2b9Sbouyer 
1156e4cb2b9Sbouyer 	ifindex = can_bind(s, ifname);
1166e4cb2b9Sbouyer 
1176e4cb2b9Sbouyer 	/* check sockopt CAN_RAW_LOOPBACK */
1186e4cb2b9Sbouyer 	vlen = sizeof(v);
1196e4cb2b9Sbouyer 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
1206e4cb2b9Sbouyer 	    &v, &vlen) < 0) {
1216e4cb2b9Sbouyer 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
1226e4cb2b9Sbouyer 	}
1236e4cb2b9Sbouyer 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
1246e4cb2b9Sbouyer 	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
1256e4cb2b9Sbouyer 
1266e4cb2b9Sbouyer 	/* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
1276e4cb2b9Sbouyer 	vlen = sizeof(v);
1286e4cb2b9Sbouyer 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
1296e4cb2b9Sbouyer 	    &v, &vlen) < 0) {
1306e4cb2b9Sbouyer 		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
1316e4cb2b9Sbouyer 	}
1326e4cb2b9Sbouyer 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
1336e4cb2b9Sbouyer 	ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
1346e4cb2b9Sbouyer 
1356e4cb2b9Sbouyer 	/*
1366e4cb2b9Sbouyer 	 * send a single byte message, but make sure remaining payload is
1376e4cb2b9Sbouyer 	 * not 0.
1386e4cb2b9Sbouyer 	 */
1396e4cb2b9Sbouyer 
1406e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
1416e4cb2b9Sbouyer 	cf_send.can_id = 1;
1426e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
1436e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
1446e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
1456e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
1466e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
1476e4cb2b9Sbouyer 
1486e4cb2b9Sbouyer 	if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
1496e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
1506e4cb2b9Sbouyer 	}
1516e4cb2b9Sbouyer 
1526e4cb2b9Sbouyer 	/* now try to read */
1536e4cb2b9Sbouyer 	if (can_recvfrom(s, &cf_receive, &rv, &sa) < 0) {
1546e4cb2b9Sbouyer 		if (errno ==  EWOULDBLOCK)
1556e4cb2b9Sbouyer 			return; /* expected timeout */
1566e4cb2b9Sbouyer 		atf_tc_fail_errno("can_recvfrom");
1576e4cb2b9Sbouyer 	}
1586e4cb2b9Sbouyer 
1596e4cb2b9Sbouyer 	ATF_CHECK_MSG(sa.can_ifindex == ifindex,
1606e4cb2b9Sbouyer 	   "recvfrom provided wrong ifindex %d (!= %d)",
1616e4cb2b9Sbouyer 	    sa.can_ifindex, ifindex);
1626e4cb2b9Sbouyer 	atf_tc_fail("we got our own message");
1636e4cb2b9Sbouyer }
1646e4cb2b9Sbouyer 
1656e4cb2b9Sbouyer ATF_TC(canwritelo);
ATF_TC_HEAD(canwritelo,tc)1666e4cb2b9Sbouyer ATF_TC_HEAD(canwritelo, tc)
1676e4cb2b9Sbouyer {
1686e4cb2b9Sbouyer 
1696e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via write");
1706e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
1716e4cb2b9Sbouyer }
1726e4cb2b9Sbouyer 
ATF_TC_BODY(canwritelo,tc)1736e4cb2b9Sbouyer ATF_TC_BODY(canwritelo, tc)
1746e4cb2b9Sbouyer {
1756e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
1766e4cb2b9Sbouyer 	int s, rv, v;
1776e4cb2b9Sbouyer 	socklen_t vlen;
1786e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive;
1796e4cb2b9Sbouyer 
1806e4cb2b9Sbouyer 	rump_init();
1816e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
1826e4cb2b9Sbouyer 
1836e4cb2b9Sbouyer 	s = can_socket_with_own();
1846e4cb2b9Sbouyer 
1856e4cb2b9Sbouyer 	can_bind(s, ifname);
1866e4cb2b9Sbouyer 
1876e4cb2b9Sbouyer 	/* check sockopt CAN_RAW_LOOPBACK */
1886e4cb2b9Sbouyer 	vlen = sizeof(v);
1896e4cb2b9Sbouyer 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
1906e4cb2b9Sbouyer 	    &v, &vlen) < 0) {
1916e4cb2b9Sbouyer 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
1926e4cb2b9Sbouyer 	}
1936e4cb2b9Sbouyer 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
1946e4cb2b9Sbouyer 	ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
1956e4cb2b9Sbouyer 
1966e4cb2b9Sbouyer 	/* check that sockopt CAN_RAW_RECV_OWN_MSGS is on */
1976e4cb2b9Sbouyer 	vlen = sizeof(v);
1986e4cb2b9Sbouyer 	if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
1996e4cb2b9Sbouyer 	    &v, &vlen) < 0) {
2006e4cb2b9Sbouyer 		atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
2016e4cb2b9Sbouyer 	}
2026e4cb2b9Sbouyer 	ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on");
2036e4cb2b9Sbouyer 
2046e4cb2b9Sbouyer 	/*
2056e4cb2b9Sbouyer 	 * send a single byte message, but make sure remaining payload is
2066e4cb2b9Sbouyer 	 * not 0.
2076e4cb2b9Sbouyer 	 */
2086e4cb2b9Sbouyer 
2096e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
2106e4cb2b9Sbouyer 	cf_send.can_id = 1;
2116e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
2126e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
2136e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
2146e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
2156e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
2166e4cb2b9Sbouyer 
2176e4cb2b9Sbouyer 	if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
2186e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
2196e4cb2b9Sbouyer 	}
2206e4cb2b9Sbouyer 
2216e4cb2b9Sbouyer 	if (can_read(s, &cf_receive, &rv) < 0) {
2226e4cb2b9Sbouyer 		atf_tc_fail_errno("can_read");
2236e4cb2b9Sbouyer 	}
2246e4cb2b9Sbouyer 
2256e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
2266e4cb2b9Sbouyer 	cf_send.can_id = 1;
2276e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
2286e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
2296e4cb2b9Sbouyer 	/* other data[] are expected to be 0 */
2306e4cb2b9Sbouyer 
2316e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
2326e4cb2b9Sbouyer 	    "received packet is not what we sent");
2336e4cb2b9Sbouyer }
2346e4cb2b9Sbouyer 
2356e4cb2b9Sbouyer ATF_TC(canwriteunbound);
ATF_TC_HEAD(canwriteunbound,tc)2366e4cb2b9Sbouyer ATF_TC_HEAD(canwriteunbound, tc)
2376e4cb2b9Sbouyer {
2386e4cb2b9Sbouyer 
2396e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that write to unbound CAN sockets fails");
2406e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
2416e4cb2b9Sbouyer }
2426e4cb2b9Sbouyer 
ATF_TC_BODY(canwriteunbound,tc)2436e4cb2b9Sbouyer ATF_TC_BODY(canwriteunbound, tc)
2446e4cb2b9Sbouyer {
2456e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
2466e4cb2b9Sbouyer 	int s, rv;
2476e4cb2b9Sbouyer 	struct can_frame cf_send;
2486e4cb2b9Sbouyer 
2496e4cb2b9Sbouyer 	rump_init();
2506e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
2516e4cb2b9Sbouyer 
2526e4cb2b9Sbouyer 	s = -1;
2536e4cb2b9Sbouyer 	if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
2546e4cb2b9Sbouyer 		atf_tc_fail_errno("CAN socket");
2556e4cb2b9Sbouyer 	}
2566e4cb2b9Sbouyer 
2576e4cb2b9Sbouyer 	/*
2586e4cb2b9Sbouyer 	 * send a single byte message.
2596e4cb2b9Sbouyer 	 * not 0.
2606e4cb2b9Sbouyer 	 */
2616e4cb2b9Sbouyer 
2626e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
2636e4cb2b9Sbouyer 	cf_send.can_id = 1;
2646e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
2656e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
2666e4cb2b9Sbouyer 
2676e4cb2b9Sbouyer 	rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
2686e4cb2b9Sbouyer 	ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
2696e4cb2b9Sbouyer 	    "write to unbound socket didn't fail");
2706e4cb2b9Sbouyer }
2716e4cb2b9Sbouyer 
2726e4cb2b9Sbouyer ATF_TC(cansendtolo);
ATF_TC_HEAD(cansendtolo,tc)2736e4cb2b9Sbouyer ATF_TC_HEAD(cansendtolo, tc)
2746e4cb2b9Sbouyer {
2756e4cb2b9Sbouyer 
2766e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via sendto");
2776e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
2786e4cb2b9Sbouyer }
2796e4cb2b9Sbouyer 
ATF_TC_BODY(cansendtolo,tc)2806e4cb2b9Sbouyer ATF_TC_BODY(cansendtolo, tc)
2816e4cb2b9Sbouyer {
2826e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
2836e4cb2b9Sbouyer 	int s, rv;
2846e4cb2b9Sbouyer 	struct sockaddr_can sa;
2856e4cb2b9Sbouyer 	struct ifreq ifr;
2866e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive;
2876e4cb2b9Sbouyer 
2886e4cb2b9Sbouyer 	rump_init();
2896e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
2906e4cb2b9Sbouyer 
2916e4cb2b9Sbouyer 	s = can_socket_with_own();
2926e4cb2b9Sbouyer 
2936e4cb2b9Sbouyer 	strcpy(ifr.ifr_name, ifname );
2946e4cb2b9Sbouyer 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
2956e4cb2b9Sbouyer 		atf_tc_fail_errno("SIOCGIFINDEX");
2966e4cb2b9Sbouyer 	}
2976e4cb2b9Sbouyer 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
2986e4cb2b9Sbouyer 	    ifname, ifr.ifr_ifindex);
2996e4cb2b9Sbouyer 
3006e4cb2b9Sbouyer 	sa.can_family = AF_CAN;
3016e4cb2b9Sbouyer 	sa.can_ifindex = ifr.ifr_ifindex;
3026e4cb2b9Sbouyer 
3036e4cb2b9Sbouyer 	/*
3046e4cb2b9Sbouyer 	 * send a single byte message, but make sure remaining payload is
3056e4cb2b9Sbouyer 	 * not 0.
3066e4cb2b9Sbouyer 	 */
3076e4cb2b9Sbouyer 
3086e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
3096e4cb2b9Sbouyer 	cf_send.can_id = 1;
3106e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
3116e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
3126e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
3136e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
3146e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
3156e4cb2b9Sbouyer 
3166e4cb2b9Sbouyer 	if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
3176e4cb2b9Sbouyer 	    0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
3186e4cb2b9Sbouyer 		atf_tc_fail_errno("sendto");
3196e4cb2b9Sbouyer 	}
3206e4cb2b9Sbouyer 
3216e4cb2b9Sbouyer 	if (can_read(s, &cf_receive, &rv) < 0) {
3226e4cb2b9Sbouyer 		atf_tc_fail_errno("read");
3236e4cb2b9Sbouyer 	}
3246e4cb2b9Sbouyer 
3256e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
3266e4cb2b9Sbouyer 	cf_send.can_id = 1;
3276e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
3286e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
3296e4cb2b9Sbouyer 	/* other data[] are expected to be 0 */
3306e4cb2b9Sbouyer 
3316e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
3326e4cb2b9Sbouyer 	    "received packet is not what we sent");
3336e4cb2b9Sbouyer }
3346e4cb2b9Sbouyer 
3356e4cb2b9Sbouyer ATF_TC(cansendtowrite);
ATF_TC_HEAD(cansendtowrite,tc)3366e4cb2b9Sbouyer ATF_TC_HEAD(cansendtowrite, tc)
3376e4cb2b9Sbouyer {
3386e4cb2b9Sbouyer 
3396e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that write after sendto on unbound socket fails");
3406e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
3416e4cb2b9Sbouyer }
3426e4cb2b9Sbouyer 
ATF_TC_BODY(cansendtowrite,tc)3436e4cb2b9Sbouyer ATF_TC_BODY(cansendtowrite, tc)
3446e4cb2b9Sbouyer {
3456e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
3466e4cb2b9Sbouyer 	int s, rv;
3476e4cb2b9Sbouyer 	struct sockaddr_can sa;
3486e4cb2b9Sbouyer 	struct ifreq ifr;
3496e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive;
3506e4cb2b9Sbouyer 
3516e4cb2b9Sbouyer 	rump_init();
3526e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
3536e4cb2b9Sbouyer 
3546e4cb2b9Sbouyer 	s = can_socket_with_own();
3556e4cb2b9Sbouyer 
3566e4cb2b9Sbouyer 	strcpy(ifr.ifr_name, ifname );
3576e4cb2b9Sbouyer 	if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
3586e4cb2b9Sbouyer 		atf_tc_fail_errno("SIOCGIFINDEX");
3596e4cb2b9Sbouyer 	}
3606e4cb2b9Sbouyer 	ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
3616e4cb2b9Sbouyer 	    ifname, ifr.ifr_ifindex);
3626e4cb2b9Sbouyer 
3636e4cb2b9Sbouyer 	sa.can_family = AF_CAN;
3646e4cb2b9Sbouyer 	sa.can_ifindex = ifr.ifr_ifindex;
3656e4cb2b9Sbouyer 
3666e4cb2b9Sbouyer 	/*
3676e4cb2b9Sbouyer 	 * send a single byte message.
3686e4cb2b9Sbouyer 	 * not 0.
3696e4cb2b9Sbouyer 	 */
3706e4cb2b9Sbouyer 
3716e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
3726e4cb2b9Sbouyer 	cf_send.can_id = 1;
3736e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
3746e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
3756e4cb2b9Sbouyer 
3766e4cb2b9Sbouyer 	if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
3776e4cb2b9Sbouyer 	    0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
3786e4cb2b9Sbouyer 		atf_tc_fail_errno("sendto");
3796e4cb2b9Sbouyer 	}
3806e4cb2b9Sbouyer 
3816e4cb2b9Sbouyer 	if (can_read(s, &cf_receive, &rv) < 0) {
3826e4cb2b9Sbouyer 		atf_tc_fail_errno("read");
3836e4cb2b9Sbouyer 	}
3846e4cb2b9Sbouyer 
3856e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
3866e4cb2b9Sbouyer 	cf_send.can_id = 1;
3876e4cb2b9Sbouyer 	cf_send.can_dlc = 1;
3886e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
3896e4cb2b9Sbouyer 	/* other data[] are expected to be 0 */
3906e4cb2b9Sbouyer 
3916e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
3926e4cb2b9Sbouyer 	    "received packet is not what we sent");
3936e4cb2b9Sbouyer 
3946e4cb2b9Sbouyer 	rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
3956e4cb2b9Sbouyer 	ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
3966e4cb2b9Sbouyer 	    "write to unbound socket didn't fail");
3976e4cb2b9Sbouyer }
3986e4cb2b9Sbouyer 
3996e4cb2b9Sbouyer ATF_TC(canreadlocal);
ATF_TC_HEAD(canreadlocal,tc)4006e4cb2b9Sbouyer ATF_TC_HEAD(canreadlocal, tc)
4016e4cb2b9Sbouyer {
4026e4cb2b9Sbouyer 
4036e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check all CAN sockets get messages");
4046e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
4056e4cb2b9Sbouyer }
4066e4cb2b9Sbouyer 
ATF_TC_BODY(canreadlocal,tc)4076e4cb2b9Sbouyer ATF_TC_BODY(canreadlocal, tc)
4086e4cb2b9Sbouyer {
4096e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
4106e4cb2b9Sbouyer 	int s1, rv1;
4116e4cb2b9Sbouyer 	int s2, rv2;
4126e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive1, cf_receive2;
4136e4cb2b9Sbouyer 
4146e4cb2b9Sbouyer 	rump_init();
4156e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
4166e4cb2b9Sbouyer 
4176e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
4186e4cb2b9Sbouyer 	cf_send.can_id = 1;
4196e4cb2b9Sbouyer 	cf_send.can_dlc = 8;
4206e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
4216e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
4226e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
4236e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
4246e4cb2b9Sbouyer 
4256e4cb2b9Sbouyer 
4266e4cb2b9Sbouyer 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
4276e4cb2b9Sbouyer 		atf_tc_fail_errno("CAN socket");
4286e4cb2b9Sbouyer 	}
4296e4cb2b9Sbouyer 
4306e4cb2b9Sbouyer 	/* create a second socket */
4316e4cb2b9Sbouyer 
4326e4cb2b9Sbouyer 	s2 = can_socket_with_own();
4336e4cb2b9Sbouyer 
4346e4cb2b9Sbouyer 	can_bind(s2, ifname);
4356e4cb2b9Sbouyer 
4366e4cb2b9Sbouyer 	/*
4376e4cb2b9Sbouyer 	 * send a single byte message, but make sure remaining payload is
4386e4cb2b9Sbouyer 	 * not 0.
4396e4cb2b9Sbouyer 	 */
4406e4cb2b9Sbouyer 
4416e4cb2b9Sbouyer 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
4426e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
4436e4cb2b9Sbouyer 	}
4446e4cb2b9Sbouyer 
4456e4cb2b9Sbouyer 	if (can_read(s2, &cf_receive2, &rv2) < 0) {
4466e4cb2b9Sbouyer 		atf_tc_fail_errno("can_read");
4476e4cb2b9Sbouyer 	}
4486e4cb2b9Sbouyer 
4496e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
4506e4cb2b9Sbouyer 	    "received (2) packet is not what we sent");
4516e4cb2b9Sbouyer 
4526e4cb2b9Sbouyer 	/* now check first socket */
4536e4cb2b9Sbouyer 	if (can_read(s1, &cf_receive1, &rv1) < 0) {
4546e4cb2b9Sbouyer 		atf_tc_fail_errno("can_read");
4556e4cb2b9Sbouyer 	}
4566e4cb2b9Sbouyer 
4576e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
4586e4cb2b9Sbouyer 	    "received (1) packet is not what we sent");
4596e4cb2b9Sbouyer }
4606e4cb2b9Sbouyer 
4616e4cb2b9Sbouyer ATF_TC(canrecvfrom);
ATF_TC_HEAD(canrecvfrom,tc)4626e4cb2b9Sbouyer ATF_TC_HEAD(canrecvfrom, tc)
4636e4cb2b9Sbouyer {
4646e4cb2b9Sbouyer 
4656e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that recvfrom gets the CAN interface");
4666e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
4676e4cb2b9Sbouyer }
4686e4cb2b9Sbouyer 
ATF_TC_BODY(canrecvfrom,tc)4696e4cb2b9Sbouyer ATF_TC_BODY(canrecvfrom, tc)
4706e4cb2b9Sbouyer {
4716e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
4726e4cb2b9Sbouyer 	int s1, rv1;
4736e4cb2b9Sbouyer 	int s2, rv2;
4746e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive1, cf_receive2;
4756e4cb2b9Sbouyer 	int ifindex;
4766e4cb2b9Sbouyer 	struct sockaddr_can sa;
4776e4cb2b9Sbouyer 
4786e4cb2b9Sbouyer 	rump_init();
4796e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
4806e4cb2b9Sbouyer 
4816e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
4826e4cb2b9Sbouyer 	cf_send.can_id = 1;
4836e4cb2b9Sbouyer 	cf_send.can_dlc = 8;
4846e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
4856e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
4866e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
4876e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
4886e4cb2b9Sbouyer 
4896e4cb2b9Sbouyer 
4906e4cb2b9Sbouyer 	s1 = -1;
4916e4cb2b9Sbouyer 	if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
4926e4cb2b9Sbouyer 		atf_tc_fail_errno("CAN socket");
4936e4cb2b9Sbouyer 	}
4946e4cb2b9Sbouyer 
4956e4cb2b9Sbouyer 	/* create a second socket */
4966e4cb2b9Sbouyer 
4976e4cb2b9Sbouyer 	s2 = can_socket_with_own();
4986e4cb2b9Sbouyer 
4996e4cb2b9Sbouyer 	ifindex = can_bind(s2, ifname);
5006e4cb2b9Sbouyer 
5016e4cb2b9Sbouyer 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
5026e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
5036e4cb2b9Sbouyer 	}
5046e4cb2b9Sbouyer 
5056e4cb2b9Sbouyer 	if (can_read(s2, &cf_receive2, &rv2) < 0) {
5066e4cb2b9Sbouyer 		atf_tc_fail_errno("can_read");
5076e4cb2b9Sbouyer 	}
5086e4cb2b9Sbouyer 
5096e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
5106e4cb2b9Sbouyer 	    "received (2) packet is not what we sent");
5116e4cb2b9Sbouyer 
5126e4cb2b9Sbouyer 	/* now check first socket */
5136e4cb2b9Sbouyer 	memset(&sa, 0, sizeof(sa));
5146e4cb2b9Sbouyer 	if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
5156e4cb2b9Sbouyer 		atf_tc_fail_errno("can_recvfrom");
5166e4cb2b9Sbouyer 	}
5176e4cb2b9Sbouyer 
5186e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
5196e4cb2b9Sbouyer 	    "recvfrom (1) packet is not what we sent");
5206e4cb2b9Sbouyer 	ATF_CHECK_MSG(sa.can_ifindex == ifindex,
5216e4cb2b9Sbouyer 	   "recvfrom provided wrong ifindex %d (!= %d)",
5226e4cb2b9Sbouyer 	    sa.can_ifindex, ifindex);
5236e4cb2b9Sbouyer }
5246e4cb2b9Sbouyer 
5256e4cb2b9Sbouyer ATF_TC(canbindfilter);
ATF_TC_HEAD(canbindfilter,tc)5266e4cb2b9Sbouyer ATF_TC_HEAD(canbindfilter, tc)
5276e4cb2b9Sbouyer {
5286e4cb2b9Sbouyer 
529*ca765360Sandvar 	atf_tc_set_md_var(tc, "descr", "check that socket bound to an interface doesn't get other interface's messages");
5306e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
5316e4cb2b9Sbouyer }
5326e4cb2b9Sbouyer 
ATF_TC_BODY(canbindfilter,tc)5336e4cb2b9Sbouyer ATF_TC_BODY(canbindfilter, tc)
5346e4cb2b9Sbouyer {
5356e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
5366e4cb2b9Sbouyer 	const char ifname2[] = "canlo1";
5376e4cb2b9Sbouyer 	int s1, rv1;
5386e4cb2b9Sbouyer 	int s2, rv2;
5396e4cb2b9Sbouyer 	struct sockaddr_can sa;
5406e4cb2b9Sbouyer 	int ifindex2;
5416e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive1, cf_receive2;
5426e4cb2b9Sbouyer 
5436e4cb2b9Sbouyer 	rump_init();
5446e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
5456e4cb2b9Sbouyer 	cancfg_rump_createif(ifname2);
5466e4cb2b9Sbouyer 
5476e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
5486e4cb2b9Sbouyer 	cf_send.can_id = 1;
5496e4cb2b9Sbouyer 	cf_send.can_dlc = 8;
5506e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
5516e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
5526e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
5536e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
5546e4cb2b9Sbouyer 
5556e4cb2b9Sbouyer 
5566e4cb2b9Sbouyer 	s1 = can_socket_with_own();
5576e4cb2b9Sbouyer 
5586e4cb2b9Sbouyer 	can_bind(s1, ifname);
5596e4cb2b9Sbouyer 
5606e4cb2b9Sbouyer 	/* create a second socket */
5616e4cb2b9Sbouyer 
5626e4cb2b9Sbouyer 	s2 = can_socket_with_own();
5636e4cb2b9Sbouyer 
5646e4cb2b9Sbouyer 	ifindex2 = can_bind(s2, ifname2);
5656e4cb2b9Sbouyer 
5666e4cb2b9Sbouyer 	if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
5676e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
5686e4cb2b9Sbouyer 	}
5696e4cb2b9Sbouyer 
5706e4cb2b9Sbouyer 	if (can_read(s2, &cf_receive2, &rv2) < 0) {
5716e4cb2b9Sbouyer 		atf_tc_fail_errno("read");
5726e4cb2b9Sbouyer 	}
5736e4cb2b9Sbouyer 
5746e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
5756e4cb2b9Sbouyer 	    "received (2) packet is not what we sent");
5766e4cb2b9Sbouyer 
5776e4cb2b9Sbouyer 	/* now check first socket */
5786e4cb2b9Sbouyer 	if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
5796e4cb2b9Sbouyer 		if (errno == EWOULDBLOCK) {
5806e4cb2b9Sbouyer 			/* expected case */
5816e4cb2b9Sbouyer 			return;
5826e4cb2b9Sbouyer 		}
5836e4cb2b9Sbouyer 		atf_tc_fail_errno("can_recvfrom");
5846e4cb2b9Sbouyer 	}
5856e4cb2b9Sbouyer 	ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
5866e4cb2b9Sbouyer 	    "recvfrom (1) packet is not what we sent");
5876e4cb2b9Sbouyer 	ATF_CHECK_MSG(sa.can_ifindex == ifindex2,
5886e4cb2b9Sbouyer 	   "recvfrom provided wrong ifindex %d (!= %d)",
5896e4cb2b9Sbouyer 	    sa.can_ifindex, ifindex2);
5906e4cb2b9Sbouyer 	atf_tc_fail("we got message from other interface");
5916e4cb2b9Sbouyer }
5926e4cb2b9Sbouyer 
5936e4cb2b9Sbouyer ATF_TC(cannoloop);
ATF_TC_HEAD(cannoloop,tc)5946e4cb2b9Sbouyer ATF_TC_HEAD(cannoloop, tc)
5956e4cb2b9Sbouyer {
5966e4cb2b9Sbouyer 
5976e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "descr", "check that disabling loopback works");
5986e4cb2b9Sbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
5996e4cb2b9Sbouyer }
6006e4cb2b9Sbouyer 
ATF_TC_BODY(cannoloop,tc)6016e4cb2b9Sbouyer ATF_TC_BODY(cannoloop, tc)
6026e4cb2b9Sbouyer {
6036e4cb2b9Sbouyer 	const char ifname[] = "canlo0";
6046e4cb2b9Sbouyer 	int s1, rv1;
6056e4cb2b9Sbouyer 	int s2, rv2;
6066e4cb2b9Sbouyer 	int v;
6076e4cb2b9Sbouyer 	socklen_t vlen;
6086e4cb2b9Sbouyer 	struct sockaddr_can sa;
6096e4cb2b9Sbouyer 	struct can_frame cf_send, cf_receive1, cf_receive2;
6106e4cb2b9Sbouyer 	socklen_t salen;
6116e4cb2b9Sbouyer 	int ifindex;
6126e4cb2b9Sbouyer 	fd_set rfds;
6136e4cb2b9Sbouyer 	struct timeval tmout;
6146e4cb2b9Sbouyer 
6156e4cb2b9Sbouyer 	rump_init();
6166e4cb2b9Sbouyer 	cancfg_rump_createif(ifname);
6176e4cb2b9Sbouyer 
6186e4cb2b9Sbouyer 	memset(&cf_send, 0, sizeof(cf_send));
6196e4cb2b9Sbouyer 	cf_send.can_id = 1;
6206e4cb2b9Sbouyer 	cf_send.can_dlc = 8;
6216e4cb2b9Sbouyer 	cf_send.data[0] = 0xde;
6226e4cb2b9Sbouyer 	cf_send.data[1] = 0xad;
6236e4cb2b9Sbouyer 	cf_send.data[2] = 0xbe;
6246e4cb2b9Sbouyer 	cf_send.data[3] = 0xef;
6256e4cb2b9Sbouyer 
6266e4cb2b9Sbouyer 
6276e4cb2b9Sbouyer 	s1 = can_socket_with_own();
6286e4cb2b9Sbouyer 	v = 0;
6296e4cb2b9Sbouyer 	if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
6306e4cb2b9Sbouyer 	    &v, sizeof(v)) < 0) {
6316e4cb2b9Sbouyer 		atf_tc_fail_errno("setsockopt(LOOPBACK)");
6326e4cb2b9Sbouyer 	}
6336e4cb2b9Sbouyer 	v = -1;
6346e4cb2b9Sbouyer 	vlen = sizeof(v);
6356e4cb2b9Sbouyer 	if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
6366e4cb2b9Sbouyer 	    &v, &vlen) < 0) {
6376e4cb2b9Sbouyer 		atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
6386e4cb2b9Sbouyer 	}
6396e4cb2b9Sbouyer 	ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
6406e4cb2b9Sbouyer 	ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off");
6416e4cb2b9Sbouyer 
6426e4cb2b9Sbouyer 	ifindex = can_bind(s1, ifname);
6436e4cb2b9Sbouyer 
6446e4cb2b9Sbouyer 	/* create a second socket */
6456e4cb2b9Sbouyer 	s2 = can_socket_with_own();
6466e4cb2b9Sbouyer 
6476e4cb2b9Sbouyer 	if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) {
6486e4cb2b9Sbouyer 		atf_tc_fail_errno("write");
6496e4cb2b9Sbouyer 	}
6506e4cb2b9Sbouyer 
6516e4cb2b9Sbouyer 
6526e4cb2b9Sbouyer 	/* now check the sockets */
6536e4cb2b9Sbouyer 	memset(&cf_receive1, 0, sizeof(cf_receive1));
6546e4cb2b9Sbouyer 	memset(&cf_receive2, 0, sizeof(cf_receive2));
6556e4cb2b9Sbouyer 	FD_ZERO(&rfds);
6566e4cb2b9Sbouyer 	FD_SET(s1, &rfds);
6576e4cb2b9Sbouyer 	FD_SET(s2, &rfds);
6586e4cb2b9Sbouyer 	/* we should receive no message; wait for 1 seconds */
6596e4cb2b9Sbouyer 	tmout.tv_sec = 1;
6606e4cb2b9Sbouyer 	tmout.tv_usec = 0;
6616e4cb2b9Sbouyer 	rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout);
6626e4cb2b9Sbouyer 	switch(rv1) {
6636e4cb2b9Sbouyer 	case -1:
6646e4cb2b9Sbouyer 		atf_tc_fail_errno("select");
6656e4cb2b9Sbouyer 		break;
6666e4cb2b9Sbouyer 	case 0:
6676e4cb2b9Sbouyer 		/* timeout: expected case */
6686e4cb2b9Sbouyer 		return;
6696e4cb2b9Sbouyer 	default: break;
6706e4cb2b9Sbouyer 	}
6716e4cb2b9Sbouyer 	salen = sizeof(sa);
6726e4cb2b9Sbouyer 	ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds),
6736e4cb2b9Sbouyer 	   "select returns but s1 nor s2 is in set");
6746e4cb2b9Sbouyer 	if (FD_ISSET(s1, &rfds)) {
6756e4cb2b9Sbouyer 		if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1,
6766e4cb2b9Sbouyer 		    sizeof(cf_receive1), 0,
6776e4cb2b9Sbouyer 		    (struct sockaddr *)&sa, &salen)) < 0) {
6786e4cb2b9Sbouyer 			atf_tc_fail_errno("recvfrom");
6796e4cb2b9Sbouyer 		}
6806e4cb2b9Sbouyer 
6816e4cb2b9Sbouyer 		ATF_CHECK_MSG(rv1 > 0, "short read on socket");
6826e4cb2b9Sbouyer 
6836e4cb2b9Sbouyer 		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1,
6846e4cb2b9Sbouyer 		    sizeof(cf_send)) == 0,
6856e4cb2b9Sbouyer 		    "recvfrom (1) packet is not what we sent");
6866e4cb2b9Sbouyer 		ATF_CHECK_MSG(sa.can_family == AF_CAN,
6876e4cb2b9Sbouyer 		    "recvfrom provided wrong %d family", sa.can_family);
6886e4cb2b9Sbouyer 		ATF_CHECK_MSG(salen == sizeof(sa),
6891e8894c3Schristos 		    "recvfrom provided wrong size %u (!= %zu)",
6901e8894c3Schristos 		    salen, sizeof(sa));
6916e4cb2b9Sbouyer 		ATF_CHECK_MSG(sa.can_ifindex == ifindex,
6926e4cb2b9Sbouyer 		   "recvfrom provided wrong ifindex %d (!= %d)",
6936e4cb2b9Sbouyer 		    sa.can_ifindex, ifindex);
6946e4cb2b9Sbouyer 		atf_tc_fail_nonfatal("we got message on s1");
6956e4cb2b9Sbouyer 	}
6966e4cb2b9Sbouyer 	if (FD_ISSET(s2, &rfds)) {
6976e4cb2b9Sbouyer 		if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2,
6986e4cb2b9Sbouyer 		    sizeof(cf_receive2), 0,
6996e4cb2b9Sbouyer 		    (struct sockaddr *)&sa, &salen)) < 0) {
7006e4cb2b9Sbouyer 			atf_tc_fail_errno("recvfrom");
7016e4cb2b9Sbouyer 		}
7026e4cb2b9Sbouyer 
7036e4cb2b9Sbouyer 		ATF_CHECK_MSG(rv2 > 0, "short read on socket");
7046e4cb2b9Sbouyer 
7056e4cb2b9Sbouyer 		ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2,
7066e4cb2b9Sbouyer 		    sizeof(cf_send)) == 0,
7076e4cb2b9Sbouyer 		    "recvfrom (2) packet is not what we sent");
7086e4cb2b9Sbouyer 		ATF_CHECK_MSG(sa.can_family == AF_CAN,
7096e4cb2b9Sbouyer 		    "recvfrom provided wrong %d family", sa.can_family);
7106e4cb2b9Sbouyer 		ATF_CHECK_MSG(salen == sizeof(sa),
711bb623270Smartin 		    "recvfrom provided wrong size %u (!= %zu)",
7126e4cb2b9Sbouyer 		    salen, sizeof(sa));
7136e4cb2b9Sbouyer 		ATF_CHECK_MSG(sa.can_ifindex == ifindex,
7146e4cb2b9Sbouyer 		   "recvfrom provided wrong ifindex %d (!= %d)",
7156e4cb2b9Sbouyer 		    sa.can_ifindex, ifindex);
7166e4cb2b9Sbouyer 		atf_tc_fail_nonfatal("we got message on s2");
7176e4cb2b9Sbouyer 	}
7186e4cb2b9Sbouyer }
7196e4cb2b9Sbouyer 
720bc73b88aSbouyer ATF_TC(canbindunknown);
ATF_TC_HEAD(canbindunknown,tc)721bc73b88aSbouyer ATF_TC_HEAD(canbindunknown, tc)
722bc73b88aSbouyer {
723bc73b88aSbouyer 
724b801bf2fSskrll 	atf_tc_set_md_var(tc, "descr", "check that bind to unknown interface fails");
725bc73b88aSbouyer 	atf_tc_set_md_var(tc, "timeout", "5");
726bc73b88aSbouyer }
727bc73b88aSbouyer 
ATF_TC_BODY(canbindunknown,tc)728bc73b88aSbouyer ATF_TC_BODY(canbindunknown, tc)
729bc73b88aSbouyer {
730bc73b88aSbouyer 	struct sockaddr_can sa;
731bc73b88aSbouyer 	int r, s;
732bc73b88aSbouyer 
733bc73b88aSbouyer 	rump_init();
734bc73b88aSbouyer 
735bc73b88aSbouyer 	s = can_socket_with_own();
736bc73b88aSbouyer 
737bc73b88aSbouyer 	sa.can_family = AF_CAN;
738bc73b88aSbouyer 	sa.can_ifindex = 10; /* should not exist */
739bc73b88aSbouyer 
740bc73b88aSbouyer 	r = rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa));
741bc73b88aSbouyer 
742bc73b88aSbouyer 	ATF_CHECK_MSG(r < 0, "bind() didn't fail (%d)", r);
743bc73b88aSbouyer }
744bc73b88aSbouyer 
ATF_TP_ADD_TCS(tp)7456e4cb2b9Sbouyer ATF_TP_ADD_TCS(tp)
7466e4cb2b9Sbouyer {
7476e4cb2b9Sbouyer 
7486e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canlocreate);
7496e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, cannoown);
7506e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canwritelo);
7516e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canwriteunbound);
7526e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, cansendtolo);
7536e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, cansendtowrite);
7546e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canreadlocal);
7556e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canrecvfrom);
7566e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, canbindfilter);
7576e4cb2b9Sbouyer         ATF_TP_ADD_TC(tp, cannoloop);
758bc73b88aSbouyer         ATF_TP_ADD_TC(tp, canbindunknown);
7596e4cb2b9Sbouyer 	return atf_no_error();
7606e4cb2b9Sbouyer }
761