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