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