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