t_can.c revision 1.1.2.6 1 /* $NetBSD: t_can.c,v 1.1.2.6 2017/02/05 12:18:20 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.6 2017/02/05 12:18:20 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 socklen_t salen;
105 int ifindex;
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 if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
114 atf_tc_fail_errno("CAN socket");
115 }
116
117 ifindex = can_bind(s, ifname);
118
119 /* check sockopt CAN_RAW_LOOPBACK */
120 vlen = sizeof(v);
121 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
122 &v, &vlen) < 0) {
123 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
124 }
125 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
126 ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
127
128 /* check sockopt CAN_RAW_RECV_OWN_MSGS, and set it */
129 vlen = sizeof(v);
130 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
131 &v, &vlen) < 0) {
132 atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
133 }
134 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_RECV_OWN_MSGS) returns wrong len %d", vlen);
135 ATF_CHECK_MSG(v == 0, "CAN_RAW_RECV_OWN_MSGS is not off by default");
136
137 /*
138 * send a single byte message, but make sure remaining payload is
139 * not 0.
140 */
141
142 memset(&cf_send, 0, sizeof(cf_send));
143 cf_send.can_id = 1;
144 cf_send.can_dlc = 1;
145 cf_send.data[0] = 0xde;
146 cf_send.data[1] = 0xad;
147 cf_send.data[2] = 0xbe;
148 cf_send.data[3] = 0xef;
149
150 if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
151 atf_tc_fail_errno("write");
152 }
153
154 /* now try to read */
155 if (can_recvfrom(s, &cf_receive, &rv, &sa) < 0) {
156 if (errno == EWOULDBLOCK)
157 return; /* expected timeout */
158 atf_tc_fail_errno("can_recvfrom");
159 }
160
161 ATF_CHECK_MSG(sa.can_ifindex == ifindex,
162 "recvfrom provided wrong ifindex %d (!= %d)",
163 sa.can_ifindex, ifindex);
164 atf_tc_fail("we got our own message");
165 }
166
167 ATF_TC(canwritelo);
168 ATF_TC_HEAD(canwritelo, tc)
169 {
170
171 atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via write");
172 atf_tc_set_md_var(tc, "timeout", "5");
173 }
174
175 ATF_TC_BODY(canwritelo, tc)
176 {
177 const char ifname[] = "canlo0";
178 int s, rv, v, vlen;
179 struct can_frame cf_send, cf_receive;
180
181 rump_init();
182 cancfg_rump_createif(ifname);
183
184 s = can_socket_with_own();
185
186 can_bind(s, ifname);
187
188 /* check sockopt CAN_RAW_LOOPBACK */
189 vlen = sizeof(v);
190 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
191 &v, &vlen) < 0) {
192 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
193 }
194 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
195 ATF_CHECK_MSG(v == 1, "CAN_RAW_LOOPBACK is not on by default");
196
197 /* check that sockopt CAN_RAW_RECV_OWN_MSGS is on */
198 vlen = sizeof(v);
199 if (rump_sys_getsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
200 &v, &vlen) < 0) {
201 atf_tc_fail_errno("getsockopt(CAN_RAW_RECV_OWN_MSGS)");
202 }
203 ATF_CHECK_MSG(v == 1, "CAN_RAW_RECV_OWN_MSGS is not on");
204
205 /*
206 * send a single byte message, but make sure remaining payload is
207 * not 0.
208 */
209
210 memset(&cf_send, 0, sizeof(cf_send));
211 cf_send.can_id = 1;
212 cf_send.can_dlc = 1;
213 cf_send.data[0] = 0xde;
214 cf_send.data[1] = 0xad;
215 cf_send.data[2] = 0xbe;
216 cf_send.data[3] = 0xef;
217
218 if (rump_sys_write(s, &cf_send, sizeof(cf_send) - 7) < 0) {
219 atf_tc_fail_errno("write");
220 }
221
222 if (can_read(s, &cf_receive, &rv) < 0) {
223 atf_tc_fail_errno("can_read");
224 }
225
226 memset(&cf_send, 0, sizeof(cf_send));
227 cf_send.can_id = 1;
228 cf_send.can_dlc = 1;
229 cf_send.data[0] = 0xde;
230 /* other data[] are expected to be 0 */
231
232 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
233 "received packet is not what we sent");
234 }
235
236 ATF_TC(canwriteunbound);
237 ATF_TC_HEAD(canwriteunbound, tc)
238 {
239
240 atf_tc_set_md_var(tc, "descr", "check that write to unbound CAN sockets fails");
241 atf_tc_set_md_var(tc, "timeout", "5");
242 }
243
244 ATF_TC_BODY(canwriteunbound, tc)
245 {
246 const char ifname[] = "canlo0";
247 int s, rv;
248 struct sockaddr_can sa;
249 struct can_frame cf_send;
250
251 rump_init();
252 cancfg_rump_createif(ifname);
253
254 s = -1;
255 if ((s = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
256 atf_tc_fail_errno("CAN socket");
257 }
258
259 /*
260 * send a single byte message.
261 * not 0.
262 */
263
264 memset(&cf_send, 0, sizeof(cf_send));
265 cf_send.can_id = 1;
266 cf_send.can_dlc = 1;
267 cf_send.data[0] = 0xde;
268
269 rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
270 ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
271 "write to unbound socket didn't fail");
272 }
273
274 ATF_TC(cansendtolo);
275 ATF_TC_HEAD(cansendtolo, tc)
276 {
277
278 atf_tc_set_md_var(tc, "descr", "check that CAN sockets gets its own message via sendto");
279 atf_tc_set_md_var(tc, "timeout", "5");
280 }
281
282 ATF_TC_BODY(cansendtolo, tc)
283 {
284 const char ifname[] = "canlo0";
285 int s, v, rv;
286 struct sockaddr_can sa;
287 struct ifreq ifr;
288 struct can_frame cf_send, cf_receive;
289
290 rump_init();
291 cancfg_rump_createif(ifname);
292
293 s = can_socket_with_own();
294
295 strcpy(ifr.ifr_name, ifname );
296 if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
297 atf_tc_fail_errno("SIOCGIFINDEX");
298 }
299 ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
300 ifname, ifr.ifr_ifindex);
301
302 sa.can_family = AF_CAN;
303 sa.can_ifindex = ifr.ifr_ifindex;
304
305 /*
306 * send a single byte message, but make sure remaining payload is
307 * not 0.
308 */
309
310 memset(&cf_send, 0, sizeof(cf_send));
311 cf_send.can_id = 1;
312 cf_send.can_dlc = 1;
313 cf_send.data[0] = 0xde;
314 cf_send.data[1] = 0xad;
315 cf_send.data[2] = 0xbe;
316 cf_send.data[3] = 0xef;
317
318 if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
319 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
320 atf_tc_fail_errno("sendto");
321 }
322
323 if (can_read(s, &cf_receive, &rv) < 0) {
324 atf_tc_fail_errno("read");
325 }
326
327 memset(&cf_send, 0, sizeof(cf_send));
328 cf_send.can_id = 1;
329 cf_send.can_dlc = 1;
330 cf_send.data[0] = 0xde;
331 /* other data[] are expected to be 0 */
332
333 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
334 "received packet is not what we sent");
335 }
336
337 ATF_TC(cansendtowrite);
338 ATF_TC_HEAD(cansendtowrite, tc)
339 {
340
341 atf_tc_set_md_var(tc, "descr", "check that write after sendto on unbound socket fails");
342 atf_tc_set_md_var(tc, "timeout", "5");
343 }
344
345 ATF_TC_BODY(cansendtowrite, tc)
346 {
347 const char ifname[] = "canlo0";
348 int s, rv, v;
349 struct sockaddr_can sa;
350 struct ifreq ifr;
351 struct can_frame cf_send, cf_receive;
352
353 rump_init();
354 cancfg_rump_createif(ifname);
355
356 s = can_socket_with_own();
357
358 strcpy(ifr.ifr_name, ifname );
359 if ((rv = rump_sys_ioctl(s, SIOCGIFINDEX, &ifr)) < 0) {
360 atf_tc_fail_errno("SIOCGIFINDEX");
361 }
362 ATF_CHECK_MSG(ifr.ifr_ifindex > 0, "%s index is %d (not > 0)",
363 ifname, ifr.ifr_ifindex);
364
365 sa.can_family = AF_CAN;
366 sa.can_ifindex = ifr.ifr_ifindex;
367
368 /*
369 * send a single byte message.
370 * not 0.
371 */
372
373 memset(&cf_send, 0, sizeof(cf_send));
374 cf_send.can_id = 1;
375 cf_send.can_dlc = 1;
376 cf_send.data[0] = 0xde;
377
378 if (rump_sys_sendto(s, &cf_send, sizeof(cf_send) - 7,
379 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
380 atf_tc_fail_errno("sendto");
381 }
382
383 if (can_read(s, &cf_receive, &rv) < 0) {
384 atf_tc_fail_errno("read");
385 }
386
387 memset(&cf_send, 0, sizeof(cf_send));
388 cf_send.can_id = 1;
389 cf_send.can_dlc = 1;
390 cf_send.data[0] = 0xde;
391 /* other data[] are expected to be 0 */
392
393 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive, sizeof(cf_send)) == 0,
394 "received packet is not what we sent");
395
396 rv = rump_sys_write(s, &cf_send, sizeof(cf_send) - 7);
397 ATF_CHECK_MSG(rv < 0 && errno == EDESTADDRREQ,
398 "write to unbound socket didn't fail");
399 }
400
401 ATF_TC(canreadlocal);
402 ATF_TC_HEAD(canreadlocal, tc)
403 {
404
405 atf_tc_set_md_var(tc, "descr", "check all CAN sockets get messages");
406 atf_tc_set_md_var(tc, "timeout", "5");
407 }
408
409 ATF_TC_BODY(canreadlocal, tc)
410 {
411 const char ifname[] = "canlo0";
412 int s1, rv1;
413 int s2, rv2;
414 int v;
415 struct can_frame cf_send, cf_receive1, cf_receive2;
416
417 rump_init();
418 cancfg_rump_createif(ifname);
419
420 memset(&cf_send, 0, sizeof(cf_send));
421 cf_send.can_id = 1;
422 cf_send.can_dlc = 8;
423 cf_send.data[0] = 0xde;
424 cf_send.data[1] = 0xad;
425 cf_send.data[2] = 0xbe;
426 cf_send.data[3] = 0xef;
427
428
429 if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
430 atf_tc_fail_errno("CAN socket");
431 }
432
433 /* create a second socket */
434
435 s2 = can_socket_with_own();
436
437 can_bind(s2, ifname);
438
439 /*
440 * send a single byte message, but make sure remaining payload is
441 * not 0.
442 */
443
444 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
445 atf_tc_fail_errno("write");
446 }
447
448 if (can_read(s2, &cf_receive2, &rv2) < 0) {
449 atf_tc_fail_errno("can_read");
450 }
451
452 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
453 "received (2) packet is not what we sent");
454
455 /* now check first socket */
456 if (can_read(s1, &cf_receive1, &rv1) < 0) {
457 atf_tc_fail_errno("can_read");
458 }
459
460 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
461 "received (1) packet is not what we sent");
462 }
463
464 ATF_TC(canrecvfrom);
465 ATF_TC_HEAD(canrecvfrom, tc)
466 {
467
468 atf_tc_set_md_var(tc, "descr", "check that recvfrom gets the CAN interface");
469 atf_tc_set_md_var(tc, "timeout", "5");
470 }
471
472 ATF_TC_BODY(canrecvfrom, tc)
473 {
474 const char ifname[] = "canlo0";
475 int s1, rv1;
476 int s2, rv2;
477 int v;
478 struct can_frame cf_send, cf_receive1, cf_receive2;
479 socklen_t salen;
480 int ifindex;
481 struct sockaddr_can sa;
482
483 rump_init();
484 cancfg_rump_createif(ifname);
485
486 memset(&cf_send, 0, sizeof(cf_send));
487 cf_send.can_id = 1;
488 cf_send.can_dlc = 8;
489 cf_send.data[0] = 0xde;
490 cf_send.data[1] = 0xad;
491 cf_send.data[2] = 0xbe;
492 cf_send.data[3] = 0xef;
493
494
495 s1 = -1;
496 if ((s1 = rump_sys_socket(AF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
497 atf_tc_fail_errno("CAN socket");
498 }
499
500 /* create a second socket */
501
502 s2 = can_socket_with_own();
503
504 ifindex = can_bind(s2, ifname);
505
506 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
507 atf_tc_fail_errno("write");
508 }
509
510 if (can_read(s2, &cf_receive2, &rv2) < 0) {
511 atf_tc_fail_errno("can_read");
512 }
513
514 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
515 "received (2) packet is not what we sent");
516
517 /* now check first socket */
518 memset(&sa, 0, sizeof(sa));
519 if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
520 atf_tc_fail_errno("can_recvfrom");
521 }
522
523 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
524 "recvfrom (1) packet is not what we sent");
525 ATF_CHECK_MSG(sa.can_ifindex == ifindex,
526 "recvfrom provided wrong ifindex %d (!= %d)",
527 sa.can_ifindex, ifindex);
528 }
529
530 ATF_TC(canbindfilter);
531 ATF_TC_HEAD(canbindfilter, tc)
532 {
533
534 atf_tc_set_md_var(tc, "descr", "check that socket bound to an interface doens't get other interface's messages");
535 atf_tc_set_md_var(tc, "timeout", "5");
536 }
537
538 ATF_TC_BODY(canbindfilter, tc)
539 {
540 const char ifname[] = "canlo0";
541 const char ifname2[] = "canlo1";
542 int s1, rv1;
543 int s2, rv2;
544 int v;
545 struct sockaddr_can sa;
546 int ifindex2;
547 struct ifreq ifr;
548 struct can_frame cf_send, cf_receive1, cf_receive2;
549 socklen_t salen;
550 fd_set rfds;
551 struct timeval tmout;
552
553 rump_init();
554 cancfg_rump_createif(ifname);
555 cancfg_rump_createif(ifname2);
556
557 memset(&cf_send, 0, sizeof(cf_send));
558 cf_send.can_id = 1;
559 cf_send.can_dlc = 8;
560 cf_send.data[0] = 0xde;
561 cf_send.data[1] = 0xad;
562 cf_send.data[2] = 0xbe;
563 cf_send.data[3] = 0xef;
564
565
566 s1 = can_socket_with_own();
567
568 can_bind(s1, ifname);
569
570 /* create a second socket */
571
572 s2 = can_socket_with_own();
573
574 ifindex2 = can_bind(s2, ifname2);
575
576 if (rump_sys_write(s2, &cf_send, sizeof(cf_send)) < 0) {
577 atf_tc_fail_errno("write");
578 }
579
580 if (can_read(s2, &cf_receive2, &rv2) < 0) {
581 atf_tc_fail_errno("read");
582 }
583
584 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2, sizeof(cf_send)) == 0,
585 "received (2) packet is not what we sent");
586
587 /* now check first socket */
588 if (can_recvfrom(s1, &cf_receive1, &rv1, &sa) < 0) {
589 if (errno == EWOULDBLOCK) {
590 /* expected case */
591 return;
592 }
593 atf_tc_fail_errno("can_recvfrom");
594 }
595 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1, sizeof(cf_send)) == 0,
596 "recvfrom (1) packet is not what we sent");
597 ATF_CHECK_MSG(sa.can_ifindex == ifindex2,
598 "recvfrom provided wrong ifindex %d (!= %d)",
599 sa.can_ifindex, ifindex2);
600 atf_tc_fail("we got message from other interface");
601 }
602
603 ATF_TC(cannoloop);
604 ATF_TC_HEAD(cannoloop, tc)
605 {
606
607 atf_tc_set_md_var(tc, "descr", "check that disabling loopback works");
608 atf_tc_set_md_var(tc, "timeout", "5");
609 }
610
611 ATF_TC_BODY(cannoloop, tc)
612 {
613 const char ifname[] = "canlo0";
614 int s1, rv1;
615 int s2, rv2;
616 int v, vlen;
617 struct sockaddr_can sa;
618 struct ifreq ifr;
619 struct can_frame cf_send, cf_receive1, cf_receive2;
620 socklen_t salen;
621 int ifindex;
622 fd_set rfds;
623 struct timeval tmout;
624
625 rump_init();
626 cancfg_rump_createif(ifname);
627
628 memset(&cf_send, 0, sizeof(cf_send));
629 cf_send.can_id = 1;
630 cf_send.can_dlc = 8;
631 cf_send.data[0] = 0xde;
632 cf_send.data[1] = 0xad;
633 cf_send.data[2] = 0xbe;
634 cf_send.data[3] = 0xef;
635
636
637 s1 = can_socket_with_own();
638 v = 0;
639 if (rump_sys_setsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
640 &v, sizeof(v)) < 0) {
641 atf_tc_fail_errno("setsockopt(LOOPBACK)");
642 }
643 v = -1;
644 vlen = sizeof(v);
645 if (rump_sys_getsockopt(s1, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
646 &v, &vlen) < 0) {
647 atf_tc_fail_errno("getsockopt(CAN_RAW_LOOPBACK)");
648 }
649 ATF_CHECK_MSG(vlen == sizeof(v), "getsockopt(CAN_RAW_LOOPBACK) returns wrong len %d", vlen);
650 ATF_CHECK_MSG(v == 0, "CAN_RAW_LOOPBACK is not off");
651
652 ifindex = can_bind(s1, ifname);
653
654 /* create a second socket */
655 s2 = can_socket_with_own();
656
657 if (rump_sys_write(s1, &cf_send, sizeof(cf_send)) < 0) {
658 atf_tc_fail_errno("write");
659 }
660
661
662 /* now check the sockets */
663 memset(&cf_receive1, 0, sizeof(cf_receive1));
664 memset(&cf_receive2, 0, sizeof(cf_receive2));
665 FD_ZERO(&rfds);
666 FD_SET(s1, &rfds);
667 FD_SET(s2, &rfds);
668 /* we should receive no message; wait for 1 seconds */
669 tmout.tv_sec = 1;
670 tmout.tv_usec = 0;
671 rv1 = rump_sys_select(MAX(s1,s2) + 1, &rfds, NULL, NULL, &tmout);
672 switch(rv1) {
673 case -1:
674 atf_tc_fail_errno("select");
675 break;
676 case 0:
677 /* timeout: expected case */
678 return;
679 default: break;
680 }
681 salen = sizeof(sa);
682 ATF_CHECK_MSG(FD_ISSET(s1, &rfds) || FD_ISSET(s2, &rfds),
683 "select returns but s1 nor s2 is in set");
684 if (FD_ISSET(s1, &rfds)) {
685 if (( rv1 = rump_sys_recvfrom(s1, &cf_receive1,
686 sizeof(cf_receive1), 0,
687 (struct sockaddr *)&sa, &salen)) < 0) {
688 atf_tc_fail_errno("recvfrom");
689 }
690
691 ATF_CHECK_MSG(rv1 > 0, "short read on socket");
692
693 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive1,
694 sizeof(cf_send)) == 0,
695 "recvfrom (1) packet is not what we sent");
696 ATF_CHECK_MSG(sa.can_family == AF_CAN,
697 "recvfrom provided wrong %d family", sa.can_family);
698 ATF_CHECK_MSG(salen == sizeof(sa),
699 "recvfrom provided wrong size %d (!= %d)",
700 salen, sizeof(sa));
701 ATF_CHECK_MSG(sa.can_ifindex == ifindex,
702 "recvfrom provided wrong ifindex %d (!= %d)",
703 sa.can_ifindex, ifindex);
704 atf_tc_fail_nonfatal("we got message on s1");
705 }
706 if (FD_ISSET(s2, &rfds)) {
707 if (( rv2 = rump_sys_recvfrom(s2, &cf_receive2,
708 sizeof(cf_receive2), 0,
709 (struct sockaddr *)&sa, &salen)) < 0) {
710 atf_tc_fail_errno("recvfrom");
711 }
712
713 ATF_CHECK_MSG(rv2 > 0, "short read on socket");
714
715 ATF_CHECK_MSG(memcmp(&cf_send, &cf_receive2,
716 sizeof(cf_send)) == 0,
717 "recvfrom (2) packet is not what we sent");
718 ATF_CHECK_MSG(sa.can_family == AF_CAN,
719 "recvfrom provided wrong %d family", sa.can_family);
720 ATF_CHECK_MSG(salen == sizeof(sa),
721 "recvfrom provided wrong size %d (!= %d)",
722 salen, sizeof(sa));
723 ATF_CHECK_MSG(sa.can_ifindex == ifindex,
724 "recvfrom provided wrong ifindex %d (!= %d)",
725 sa.can_ifindex, ifindex);
726 atf_tc_fail_nonfatal("we got message on s2");
727 }
728 }
729
730 ATF_TP_ADD_TCS(tp)
731 {
732
733 ATF_TP_ADD_TC(tp, canlocreate);
734 ATF_TP_ADD_TC(tp, cannoown);
735 ATF_TP_ADD_TC(tp, canwritelo);
736 ATF_TP_ADD_TC(tp, canwriteunbound);
737 ATF_TP_ADD_TC(tp, cansendtolo);
738 ATF_TP_ADD_TC(tp, cansendtowrite);
739 ATF_TP_ADD_TC(tp, canreadlocal);
740 ATF_TP_ADD_TC(tp, canrecvfrom);
741 ATF_TP_ADD_TC(tp, canbindfilter);
742 ATF_TP_ADD_TC(tp, cannoloop);
743 return atf_no_error();
744 }
745