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