Module Name: src
Committed By: bouyer
Date: Mon Jan 16 18:04:27 UTC 2017
Modified Files:
src/tests/net/can [bouyer-socketcan]: t_can.c
Log Message:
Adapt to CAN_RAW_RECV_OWN_MSGS being off by default, and test
CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK options.
To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/tests/net/can/t_can.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/net/can/t_can.c
diff -u src/tests/net/can/t_can.c:1.1.2.1 src/tests/net/can/t_can.c:1.1.2.2
--- src/tests/net/can/t_can.c:1.1.2.1 Sun Jan 15 20:29:01 2017
+++ src/tests/net/can/t_can.c Mon Jan 16 18:04:27 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: t_can.c,v 1.1.2.1 2017/01/15 20:29:01 bouyer Exp $ */
+/* $NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $ */
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: t_can.c,v 1.1.2.1 2017/01/15 20:29:01 bouyer Exp $");
+__RCSID("$NetBSD: t_can.c,v 1.1.2.2 2017/01/16 18:04:27 bouyer Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -40,6 +40,7 @@ __RCSID("$NetBSD: t_can.c,v 1.1.2.1 2017
#include <sys/sysctl.h>
#include <sys/wait.h>
#include <sys/sockio.h>
+#include <sys/param.h>
#include <atf-c.h>
#include <assert.h>
@@ -119,6 +120,121 @@ ATF_TC_BODY(canlocreate, tc)
}
}
+ATF_TC(cannoown);
+ATF_TC_HEAD(cannoown, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that CAN sockets don't gets its own message");
+ atf_tc_set_md_var(tc, "timeout", "5");
+}
+
+ATF_TC_BODY(cannoown, tc)
+{
+ const char ifname[] = "canlo0";
+ int s, rv, v, vlen;
+ struct sockaddr_can sa;
+ int salen;
+ struct ifreq ifr;
+ struct can_frame cf_send, cf_receive;
+ fd_set rfds;
+ struct timeval tmout;
+
+ rump_init();
+ cancfg_rump_createif(ifname);
+
+ s = -1;
+ if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+ atf_tc_fail_errno("CAN socket");
+ }
+
+ strcpy(ifr.ifr_name, ifname );
+ if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
+ atf_tc_fail_errno("SIOCGIFINDEX");
+ }
+ ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
+ ifname, ifr.ifr_ifindex);
+
+ sa.can_family = AF_CAN;
+ sa.can_ifindex = ifr.ifr_ifindex;
+
+ if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+ atf_tc_fail_errno("bind");
+ }
+
+ /* check sockopt CAN_RAW_LOOPBACK */
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+ }
+ ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+ ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
+
+ /* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+ ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
+ ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
+
+ /*
+ * send a single byte message, but make sure remaining payload is
+ * not 0.
+ */
+
+ memset(&cf_send, 0, sizeof(cf_send));
+ cf_send.can_id = 1;
+ cf_send.can_dlc = 1;
+ cf_send.data[0] = 0xde;
+ cf_send.data[1] = 0xad;
+ cf_send.data[2] = 0xbe;
+ cf_send.data[3] = 0xef;
+
+ if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
+ atf_tc_fail_errno("write");
+ }
+
+ /* now try to read */
+
+ memset(&cf_receive, 0, sizeof(cf_receive));
+ FD_ZERO(&rfds);
+ FD_SET(s, &rfds);
+ /* we should receive no message; wait for 2 seconds */
+ tmout.tv_sec = 2;
+ tmout.tv_usec = 0;
+ rv = rump_sys_select(s + 1, &rfds, NULL, NULL, &tmout);
+ switch(rv) {
+ case -1:
+ atf_tc_fail_errno("select");
+ break;
+ case 0:
+ /* timeout: expected case */
+ return;
+ default: break;
+ }
+ salen = sizeof(sa);
+ ATF_CHECK_MSG(FD_ISSET(s, &rfds), "select returns but s not in set");
+ if (( rv = rump_sys_recvfrom(s, &cf_receive, sizeof(cf_receive),
+ 0, (struct sockaddr *)&sa, &salen)) < 0) {
+ atf_tc_fail_errno("recvfrom");
+ }
+
+ ATF_CHECK_MSG(rv > 0, "short read on socket");
+
+ ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
+ "recvfrom packet is not what we sent");
+ ATF_CHECK_MSG(sa.can_family == AF_CAN,
+ "recvfrom provided wrong %d family", sa.can_family);
+ ATF_CHECK_MSG(salen == sizeof(sa),
+ "recvfrom provided wrong size %d (!= %d)", salen, sizeof(sa));
+ ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+ "recvfrom provided wrong ifindex %d (!= %d)",
+ sa.can_ifindex, ifr.ifr_ifindex);
+ atf_tc_fail("we got our own message");
+}
+
ATF_TC(canwritelo);
ATF_TC_HEAD(canwritelo, tc)
{
@@ -130,7 +246,7 @@ ATF_TC_HEAD(canwritelo, tc)
ATF_TC_BODY(canwritelo, tc)
{
const char ifname[] = "canlo0";
- int s, rv;
+ int s, rv, v, vlen;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive;
@@ -144,7 +260,7 @@ ATF_TC_BODY(canwritelo, tc)
}
strcpy(ifr.ifr_name, ifname );
- if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
+ if (rump_sys_ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
atf_tc_fail_errno("SIOCGIFINDEX");
}
ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
@@ -153,10 +269,40 @@ ATF_TC_BODY(canwritelo, tc)
sa.can_family = AF_CAN;
sa.can_ifindex = ifr.ifr_ifindex;
- if ((rv = rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
+ if (rump_sys_bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
atf_tc_fail_errno("bind");
}
+ /* check sockopt CAN_RAW_LOOPBACK */
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+ }
+ ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+ ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
+
+ /* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+ ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
+ ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
+ v = 1;
+ if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+ /* check sockopt CAN_RAW_RECV_OWN_MSGS again */
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+ ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on");
+
/*
* send a single byte message, but make sure remaining payload is
* not 0.
@@ -240,7 +386,7 @@ ATF_TC_HEAD(cansendtolo, tc)
ATF_TC_BODY(cansendtolo, tc)
{
const char ifname[] = "canlo0";
- int s, rv;
+ int s, v, rv;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive;
@@ -253,6 +399,12 @@ ATF_TC_BODY(cansendtolo, tc)
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+
strcpy(ifr.ifr_name, ifname );
if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
atf_tc_fail_errno("SIOCGIFINDEX");
@@ -309,7 +461,7 @@ ATF_TC_HEAD(cansendtowrite, tc)
ATF_TC_BODY(cansendtowrite, tc)
{
const char ifname[] = "canlo0";
- int s, rv;
+ int s, rv, v;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive;
@@ -321,6 +473,11 @@ ATF_TC_BODY(cansendtowrite, tc)
if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
strcpy(ifr.ifr_name, ifname );
if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
@@ -381,6 +538,7 @@ ATF_TC_BODY(canreadlocal, tc)
const char ifname[] = "canlo0";
int s1, rv1;
int s2, rv2;
+ int v;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -408,6 +566,11 @@ ATF_TC_BODY(canreadlocal, tc)
if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
strcpy(ifr.ifr_name, ifname );
if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -467,6 +630,7 @@ ATF_TC_BODY(canrecvfrom, tc)
const char ifname[] = "canlo0";
int s1, rv1;
int s2, rv2;
+ int v;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -495,6 +659,11 @@ ATF_TC_BODY(canrecvfrom, tc)
if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
strcpy(ifr.ifr_name, ifname );
if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -560,6 +729,7 @@ ATF_TC_BODY(canbindfilter, tc)
const char ifname2[] = "canlo1";
int s1, rv1;
int s2, rv2;
+ int v;
struct sockaddr_can sa;
struct ifreq ifr;
struct can_frame cf_send, cf_receive1, cf_receive2;
@@ -584,6 +754,11 @@ ATF_TC_BODY(canbindfilter, tc)
if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
strcpy(ifr.ifr_name, ifname );
if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
@@ -605,6 +780,11 @@ ATF_TC_BODY(canbindfilter, tc)
if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
atf_tc_fail_errno("CAN socket");
}
+ v = 1;
+ if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
strcpy(ifr.ifr_name, ifname2);
if ((rv2 = rump_sys_ioctl(s2, SIOCGIFINDEX, &ifr)) < 0) {
@@ -672,10 +852,166 @@ ATF_TC_BODY(canbindfilter, tc)
atf_tc_fail("we got message from other interface");
}
+ATF_TC(cannoloop);
+ATF_TC_HEAD(cannoloop, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that disabling loopback works");
+ atf_tc_set_md_var(tc, "timeout", "5");
+}
+
+ATF_TC_BODY(cannoloop, tc)
+{
+ const char ifname[] = "canlo0";
+ int s1, rv1;
+ int s2, rv2;
+ int v, vlen;
+ struct sockaddr_can sa;
+ struct ifreq ifr;
+ struct can_frame cf_send, cf_receive1, cf_receive2;
+ socklen_t salen;
+ fd_set rfds;
+ struct timeval tmout;
+
+ rump_init();
+ cancfg_rump_createif(ifname);
+
+ memset(&cf_send, 0, sizeof(cf_send));
+ cf_send.can_id = 1;
+ cf_send.can_dlc = 8;
+ cf_send.data[0] = 0xde;
+ cf_send.data[1] = 0xad;
+ cf_send.data[2] = 0xbe;
+ cf_send.data[3] = 0xef;
+
+
+ s1 = -1;
+ if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+ atf_tc_fail_errno("CAN socket");
+ }
+ v = 1;
+ if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+ v = 0;
+ if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(LOOPBACK)");
+ }
+ v = -1;
+ vlen = sizeof(v);
+ if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
+ &v, &vlen) < 0) {
+ atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
+ }
+ ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
+ ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off");
+
+ strcpy(ifr.ifr_name, ifname );
+ if ((rv1 = rump_sys_ioctl(s1, SIOCGIFINDEX, &ifr)) < 0) {
+ atf_tc_fail_errno("SIOCGIFINDEX (1)");
+ }
+ ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
+ ifname, ifr.ifr_ifindex);
+
+ sa.can_family = AF_CAN;
+ sa.can_ifindex = ifr.ifr_ifindex;
+
+ if ((rv1 = rump_sys_bind(s1, (struct sockaddr *)&sa, sizeof(sa))) < 0) {
+ atf_tc_fail_errno("bind (1)");
+ }
+
+ /* create a second socket */
+
+ s2 = -1;
+ if ((s2 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+ atf_tc_fail_errno("CAN socket");
+ }
+ v = 1;
+ if (rump_sys_setsockopt(s2, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+ &v, sizeof(v)) < 0) {
+ atf_tc_fail_errno("setsockopt(CAN_RAW_RECV_OWN_MSGS)");
+ }
+
+ if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) {
+ atf_tc_fail_errno("write");
+ }
+
+
+ /* now check the sockets */
+ memset(&cf_receive1, 0, sizeof(cf_receive1));
+ memset(&cf_receive2, 0, sizeof(cf_receive2));
+ FD_ZERO(&rfds);
+ FD_SET(s1, &rfds);
+ FD_SET(s2, &rfds);
+ /* we should receive no message; wait for 2 seconds */
+ tmout.tv_sec = 2;
+ tmout.tv_usec = 0;
+ rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout);
+ switch(rv1) {
+ case -1:
+ atf_tc_fail_errno("select");
+ break;
+ case 0:
+ /* timeout: expected case */
+ return;
+ default: break;
+ }
+ salen = sizeof(sa);
+ ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds),
+ "select returns but s1 nor s2 is in set");
+ if (FD_ISSET(s1, &rfds)) {
+ if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1,
+ sizeof(cf_receive1), 0,
+ (struct sockaddr *)&sa, &salen)) < 0) {
+ atf_tc_fail_errno("recvfrom");
+ }
+
+ ATF_CHECK_MSG(rv1 > 0, "short read on socket");
+
+ ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1,
+ sizeof(cf_send)) == 0,
+ "recvfrom (1) packet is not what we sent");
+ ATF_CHECK_MSG(sa.can_family == AF_CAN,
+ "recvfrom provided wrong %d family", sa.can_family);
+ ATF_CHECK_MSG(salen == sizeof(sa),
+ "recvfrom provided wrong size %d (!= %d)",
+ salen, sizeof(sa));
+ ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+ "recvfrom provided wrong ifindex %d (!= %d)",
+ sa.can_ifindex, ifr.ifr_ifindex);
+ atf_tc_fail_nonfatal("we got message on s1");
+ }
+ if (FD_ISSET(s2, &rfds)) {
+ if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2,
+ sizeof(cf_receive2), 0,
+ (struct sockaddr *)&sa, &salen)) < 0) {
+ atf_tc_fail_errno("recvfrom");
+ }
+
+ ATF_CHECK_MSG(rv2 > 0, "short read on socket");
+
+ ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2,
+ sizeof(cf_send)) == 0,
+ "recvfrom (2) packet is not what we sent");
+ ATF_CHECK_MSG(sa.can_family == AF_CAN,
+ "recvfrom provided wrong %d family", sa.can_family);
+ ATF_CHECK_MSG(salen == sizeof(sa),
+ "recvfrom provided wrong size %d (!= %d)",
+ salen, sizeof(sa));
+ ATF_CHECK_MSG(sa.can_ifindex == ifr.ifr_ifindex,
+ "recvfrom provided wrong ifindex %d (!= %d)",
+ sa.can_ifindex, ifr.ifr_ifindex);
+ atf_tc_fail_nonfatal("we got message on s2");
+ }
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, canlocreate);
+ ATF_TP_ADD_TC(tp, cannoown);
ATF_TP_ADD_TC(tp, canwritelo);
ATF_TP_ADD_TC(tp, canwriteunbound);
ATF_TP_ADD_TC(tp, cansendtolo);
@@ -683,6 +1019,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, canreadlocal);
ATF_TP_ADD_TC(tp, canrecvfrom);
ATF_TP_ADD_TC(tp, canbindfilter);
+ ATF_TP_ADD_TC(tp, cannoloop);
return atf_no_error();
}