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