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