├── .gitignore ├── Makefile ├── bcm ├── cansniffer.c ├── tst-bcm-cycle.c ├── tst-bcm-dump.c ├── tst-bcm-filter.c ├── tst-bcm-nframes.c ├── tst-bcm-rtr.c ├── tst-bcm-rx-sendto.c ├── tst-bcm-single.c ├── tst-bcm-throttle.c ├── tst-bcm-tx-delete.c ├── tst-bcm-tx-read.c ├── tst-bcm-tx-sendto.c ├── tst-bcmfd-cycle.c └── tst-bcmfd-filter.c ├── drv └── canfdtest.c ├── gw └── gwtest.c ├── include └── linux │ ├── can.h │ ├── can │ ├── bcm.h │ ├── error.h │ ├── gw.h │ ├── isotp.h │ ├── j1939.h │ ├── netlink.h │ ├── raw.h │ └── vxcan.h │ ├── errqueue.h │ ├── net_tstamp.h │ └── netlink.h ├── j1939 ├── README.md ├── j1939_ac_100k_dual_can.sh ├── j1939_ac_100k_local0.sh ├── j1939_ac_1k_bam_local0.sh ├── j1939_ac_1k_local0.sh ├── j1939_ac_1m_local0.sh ├── j1939_ac_8b_local0.sh ├── j1939_multisock_dualack_100k.sh ├── j1939_multisock_dualack_1k.sh ├── j1939_multisock_timeout_100k.sh ├── run_all.sh └── tst-j1939-ac.c ├── lib ├── lib.c ├── lib.h └── terminal.h ├── netlayer ├── test_netlayer.sh ├── tst-filter-master.c ├── tst-filter-server.c ├── tst-filter-server.result ├── tst-filter.c ├── tst-packet.c ├── tst-proc.c └── tst-rcv-own-msgs.c └── raw ├── canecho.c ├── canpump.c ├── tst-err.c ├── tst-raw-filter.c ├── tst-raw-sendto.c ├── tst-raw-sockopt.c ├── tst-raw-sockopt.txt └── tst-raw.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | 3 | /bcm/cansniffer 4 | /bcm/tst-bcm-cycle 5 | /bcm/tst-bcm-dump 6 | /bcm/tst-bcm-filter 7 | /bcm/tst-bcm-rtr 8 | /bcm/tst-bcm-rx-sendto 9 | /bcm/tst-bcm-single 10 | /bcm/tst-bcm-throttle 11 | /bcm/tst-bcm-tx-sendto 12 | /bcm/tst-bcm-tx_delete 13 | /bcm/tst-bcm-tx_read 14 | /bcm/tst-bcmfd-cycle 15 | /bcm/tst-bcmfd-filter 16 | /drv/canfdtest 17 | /gw/gwtest 18 | /netlayer/tst-filter 19 | /netlayer/tst-filter-master 20 | /netlayer/tst-filter-server 21 | /netlayer/tst-packet 22 | /netlayer/tst-proc 23 | /netlayer/tst-rcv-own-msgs 24 | /raw/canecho 25 | /raw/canpump 26 | /raw/tst-err 27 | /raw/tst-raw 28 | /raw/tst-raw-filter 29 | /raw/tst-raw-sendto 30 | /raw/tst-raw-sockopt 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 | # 3 | # Copyright (c) 2002-2007 Volkswagen Group Electronic Research 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions, the following disclaimer and 11 | # the referenced file 'COPYING'. 12 | # 2. Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 3. Neither the name of Volkswagen nor the names of its contributors 16 | # may be used to endorse or promote products derived from this software 17 | # without specific prior written permission. 18 | # 19 | # Alternatively, provided that this notice is retained in full, this 20 | # software may be distributed under the terms of the GNU General 21 | # Public License ("GPL") version 2 as distributed in the 'COPYING' 22 | # file from the main directory of the linux kernel source. 23 | # 24 | # The provided data structures and external interfaces from this code 25 | # are not restricted to be used by modules with a GPL compatible license. 26 | # 27 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 38 | # DAMAGE. 39 | # 40 | # Send feedback to 41 | 42 | DESTDIR ?= 43 | PREFIX ?= /usr/local 44 | 45 | MAKEFLAGS = -k 46 | 47 | CFLAGS = -O2 -Wall -Wno-parentheses \ 48 | -fno-strict-aliasing 49 | 50 | CPPFLAGS += -Iinclude \ 51 | -Ilib \ 52 | -D_FILE_OFFSET_BITS=64 \ 53 | -DSO_RXQ_OVFL=40 \ 54 | -DETH_P_CAN=0x000C \ 55 | -DPF_CAN=29 \ 56 | -DAF_CAN=PF_CAN 57 | 58 | PROGRAMS := \ 59 | bcm/tst-bcm-cycle \ 60 | bcm/tst-bcm-nframes \ 61 | bcm/tst-bcm-dump \ 62 | bcm/tst-bcm-filter \ 63 | bcm/tst-bcm-rtr \ 64 | bcm/tst-bcm-rx-sendto \ 65 | bcm/tst-bcm-single \ 66 | bcm/tst-bcm-throttle \ 67 | bcm/tst-bcm-tx-sendto \ 68 | bcm/tst-bcm-tx-delete \ 69 | bcm/tst-bcm-tx-read \ 70 | bcm/tst-bcmfd-cycle \ 71 | bcm/tst-bcmfd-filter \ 72 | bcm/cansniffer \ 73 | drv/canfdtest \ 74 | gw/gwtest \ 75 | netlayer/tst-filter \ 76 | netlayer/tst-filter-master \ 77 | netlayer/tst-filter-server \ 78 | netlayer/tst-packet \ 79 | netlayer/tst-proc \ 80 | netlayer/tst-rcv-own-msgs \ 81 | raw/canecho \ 82 | raw/canpump \ 83 | raw/tst-err \ 84 | raw/tst-raw \ 85 | raw/tst-raw-filter \ 86 | raw/tst-raw-sockopt \ 87 | raw/tst-raw-sendto \ 88 | j1939/tst-j1939-ac 89 | 90 | J1939 := \ 91 | j1939/j1939_ac_100k_dual_can.sh \ 92 | j1939/j1939_ac_100k_local0.sh \ 93 | j1939/j1939_ac_1k_bam_local0.sh \ 94 | j1939/j1939_ac_1k_local0.sh \ 95 | j1939/j1939_ac_1m_local0.sh \ 96 | j1939/j1939_ac_8b_local0.sh \ 97 | j1939/j1939_multisock_dualack_100k.sh \ 98 | j1939/j1939_multisock_dualack_1k.sh \ 99 | j1939/j1939_multisock_timeout_100k.sh \ 100 | j1939/run_all.sh 101 | 102 | all: $(PROGRAMS) 103 | 104 | install: 105 | mkdir -p $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/lib/can-tests/j1939 106 | cp -f $(PROGRAMS) $(DESTDIR)$(PREFIX)/bin 107 | cp -f $(J1939) $(DESTDIR)$(PREFIX)/lib/can-tests/j1939 108 | 109 | clean: 110 | rm -f $(PROGRAMS) */*.o 111 | 112 | distclean: 113 | rm -f $(PROGRAMS) *.o *~ 114 | 115 | bcm/cansniffer.o: lib/lib.h 116 | bcm/cansniffer: bcm/cansniffer.o lib/lib.o 117 | raw/canpump.o: lib/lib.h 118 | raw/canpump: raw/canpump.o lib/lib.o 119 | -------------------------------------------------------------------------------- /bcm/tst-bcm-cycle.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-cycle.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s; 64 | struct sockaddr_can addr; 65 | 66 | struct { 67 | struct bcm_msg_head msg_head; 68 | struct can_frame frame[4]; 69 | } msg; 70 | 71 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 72 | perror("socket"); 73 | return 1; 74 | } 75 | 76 | addr.can_family = PF_CAN; 77 | addr.can_ifindex = if_nametoindex("vcan2"); 78 | 79 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 80 | perror("connect"); 81 | return 1; 82 | } 83 | 84 | msg.msg_head.opcode = TX_SETUP; 85 | msg.msg_head.can_id = 0x42; 86 | msg.msg_head.flags = SETTIMER|STARTTIMER; 87 | msg.msg_head.nframes = 1; 88 | msg.msg_head.count = 10; 89 | msg.msg_head.ival1.tv_sec = 1; 90 | msg.msg_head.ival1.tv_usec = 0; 91 | msg.msg_head.ival2.tv_sec = 0; 92 | msg.msg_head.ival2.tv_usec = 0; 93 | msg.frame[0].can_id = 0x42; 94 | msg.frame[0].can_dlc = 8; 95 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 96 | 97 | if (write(s, &msg, sizeof(msg)) < 0) 98 | perror("write"); 99 | 100 | printf("Press any key to stop the cycle ...\n"); 101 | 102 | getchar(); 103 | 104 | msg.msg_head.opcode = TX_SETUP; 105 | msg.msg_head.can_id = 0x42; 106 | msg.msg_head.flags = SETTIMER|STARTTIMER; 107 | msg.msg_head.nframes = 1; 108 | msg.msg_head.count = 0; 109 | msg.msg_head.ival1.tv_sec = 0; 110 | msg.msg_head.ival1.tv_usec = 0; 111 | msg.msg_head.ival2.tv_sec = 0; 112 | msg.msg_head.ival2.tv_usec = 0; 113 | msg.frame[0].can_id = 0x42; 114 | msg.frame[0].can_dlc = 8; 115 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 116 | 117 | if (write(s, &msg, sizeof(msg)) < 0) 118 | perror("write"); 119 | 120 | printf("Press any key to close the socket ...\n"); 121 | 122 | getchar(); 123 | 124 | close(s); 125 | 126 | printf("Press any key to end the program ...\n"); 127 | 128 | getchar(); 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /bcm/tst-bcm-dump.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-dump.c 4 | * 5 | * Copyright (c) 2008 Oliver Hartkopp 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the version 2 of the GNU General Public License 9 | * as published by the Free Software Foundation 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Send feedback to 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #define DEFAULT_IFACE "vcan0" 42 | #define DEFAULT_CANID 0x42 43 | 44 | void print_usage(char *prg) 45 | { 46 | fprintf(stderr, "\nUsage: %s [options]\n", prg); 47 | fprintf(stderr, "Options: -i (CAN interface. Default: '%s')\n", DEFAULT_IFACE); 48 | fprintf(stderr, " -c (used CAN ID. Default: 0x%03X)\n", DEFAULT_CANID); 49 | fprintf(stderr, " -o (Timeout value in nsecs. Default: 0)\n"); 50 | fprintf(stderr, " -t (Throttle value in nsecs. Default: 0)\n"); 51 | fprintf(stderr, " -q (Quit after receiption of #msgs)\n"); 52 | fprintf(stderr, " -s (set STARTTIMER flag. Default: off)\n"); 53 | fprintf(stderr, "\n"); 54 | } 55 | 56 | int main(int argc, char **argv) 57 | { 58 | int s; 59 | struct sockaddr_can addr; 60 | int nbytes; 61 | int i; 62 | char *ifname = DEFAULT_IFACE; 63 | canid_t canid = DEFAULT_CANID; 64 | int opt; 65 | struct timeval tv; 66 | unsigned long starttimer = 0; 67 | unsigned long long timeout = 0; 68 | unsigned long long throttle = 0; 69 | unsigned long msgs = 0; 70 | struct { 71 | struct bcm_msg_head msg_head; 72 | struct can_frame frame; 73 | } msg; 74 | 75 | while ((opt = getopt(argc, argv, "i:c:o:t:q:s")) != -1) { 76 | switch (opt) { 77 | 78 | case 'i': 79 | ifname = optarg; 80 | break; 81 | 82 | case 'c': 83 | canid = strtoul(optarg, (char **)NULL, 16); 84 | break; 85 | 86 | case 'o': 87 | timeout = strtoull(optarg, (char **)NULL, 10); 88 | break; 89 | 90 | case 't': 91 | throttle = strtoull(optarg, (char **)NULL, 10); 92 | break; 93 | 94 | case 'q': 95 | msgs = strtoul(optarg, (char **)NULL, 10); 96 | break; 97 | 98 | case 's': 99 | starttimer = STARTTIMER; 100 | break; 101 | 102 | case '?': 103 | default: 104 | print_usage(basename(argv[0])); 105 | exit(1); 106 | break; 107 | } 108 | } 109 | 110 | 111 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 112 | perror("socket"); 113 | return 1; 114 | } 115 | 116 | if (strcmp(ifname, "any") == 0) 117 | addr.can_ifindex = 0; 118 | else 119 | addr.can_ifindex = if_nametoindex(ifname); 120 | 121 | addr.can_family = PF_CAN; 122 | 123 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 124 | perror("connect"); 125 | return 1; 126 | } 127 | 128 | msg.msg_head.opcode = RX_SETUP; 129 | msg.msg_head.can_id = canid; 130 | msg.msg_head.flags = SETTIMER|RX_FILTER_ID|starttimer; 131 | msg.msg_head.ival1.tv_sec = timeout / 1000000; 132 | msg.msg_head.ival1.tv_usec = timeout % 1000000; 133 | msg.msg_head.ival2.tv_sec = throttle / 1000000; 134 | msg.msg_head.ival2.tv_usec = throttle % 1000000; 135 | msg.msg_head.nframes = 0; 136 | 137 | gettimeofday(&tv, NULL); 138 | printf("[%ld.%06ld] ", tv.tv_sec, tv.tv_usec); 139 | printf("Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n", 140 | msg.msg_head.can_id); 141 | 142 | if (write(s, &msg, sizeof(msg)) < 0) 143 | perror("write"); 144 | 145 | while (1) { 146 | 147 | nbytes = read(s, &msg, sizeof(msg)); 148 | if (nbytes < 0) { 149 | perror("read"); 150 | return 1; 151 | } 152 | gettimeofday(&tv, NULL); 153 | printf("[%ld.%06ld] ", tv.tv_sec, tv.tv_usec); 154 | 155 | if (nbytes == sizeof(msg)) { 156 | 157 | if (ioctl(s, SIOCGSTAMP, &tv) < 0) 158 | perror("SIOCGSTAMP"); 159 | else 160 | printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec); 161 | 162 | if (msg.msg_head.opcode != RX_CHANGED) { 163 | printf("missing RX_CHANGED.\n"); 164 | return 1; 165 | } 166 | 167 | printf("RX_CHANGED "); 168 | 169 | for (i=0; i < msg.frame.can_dlc; i++) 170 | printf("%02X ", msg.frame.data[i]); 171 | 172 | } else { 173 | 174 | if (msg.msg_head.opcode != RX_TIMEOUT) { 175 | printf("missing RX_TIMEOUT.\n"); 176 | return 1; 177 | } 178 | 179 | printf("RX_TIMEOUT"); 180 | } 181 | 182 | printf("\n"); 183 | fflush(stdout); 184 | 185 | if (msgs && !(--msgs)) 186 | break; 187 | } 188 | 189 | close(s); 190 | 191 | return 0; 192 | } 193 | -------------------------------------------------------------------------------- /bcm/tst-bcm-nframes.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-nframes.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) 60 | #define NFRAMES 16 61 | #define LOOPS 0x100 62 | 63 | int main(int argc, char **argv) 64 | { 65 | int s; 66 | struct sockaddr_can addr; 67 | int i, loops; 68 | 69 | static struct { 70 | struct bcm_msg_head msg_head; 71 | struct can_frame frame[NFRAMES]; 72 | } msg; 73 | 74 | s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM); 75 | if (s < 0) { 76 | perror("socket"); 77 | return 1; 78 | } 79 | 80 | addr.can_family = PF_CAN; 81 | addr.can_ifindex = if_nametoindex("vcan2"); 82 | 83 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 84 | perror("connect"); 85 | return 1; 86 | } 87 | 88 | for (loops = 1; loops < LOOPS; loops++) { 89 | 90 | /* vary the time to update the bcm operation */ 91 | usleep(2900 + 9 * loops); 92 | 93 | /* set header values */ 94 | msg.msg_head.opcode = TX_SETUP; 95 | msg.msg_head.can_id = 0x42; 96 | msg.msg_head.flags = SETTIMER|STARTTIMER; 97 | msg.msg_head.nframes = NFRAMES; 98 | msg.msg_head.count = 8; 99 | msg.msg_head.ival1.tv_sec = 0; 100 | msg.msg_head.ival1.tv_usec = 1000; 101 | msg.msg_head.ival2.tv_sec = 0; 102 | msg.msg_head.ival2.tv_usec = 0; 103 | 104 | /* fill data that shows the variables */ 105 | for (i = 0; i < NFRAMES; i++) { 106 | msg.frame[i].can_id = loops; 107 | msg.frame[i].len = (i & 7) + 1; 108 | msg.frame[i].data[0] = i; 109 | } 110 | 111 | if (write(s, &msg, sizeof(msg)) < 0) 112 | perror("write"); 113 | } 114 | 115 | usleep(20000); 116 | 117 | msg.msg_head.opcode = TX_SETUP; 118 | msg.msg_head.can_id = 0x42; 119 | msg.msg_head.flags = SETTIMER|STARTTIMER; 120 | msg.msg_head.nframes = NFRAMES/2; 121 | msg.msg_head.count = 0; 122 | msg.msg_head.ival1.tv_sec = 0; 123 | msg.msg_head.ival1.tv_usec = 0; 124 | msg.msg_head.ival2.tv_sec = 0; 125 | msg.msg_head.ival2.tv_usec = 0; 126 | msg.frame[0].can_id = 0x42; 127 | msg.frame[0].can_dlc = 8; 128 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 129 | 130 | if (write(s, &msg, sizeof(msg)) < 0) 131 | perror("write"); 132 | 133 | usleep(20000); 134 | 135 | for (loops = 1; loops < LOOPS; loops++) { 136 | 137 | /* vary the time to update the bcm operation */ 138 | usleep(2900 + 9 * loops); 139 | 140 | /* set header values */ 141 | msg.msg_head.opcode = TX_SETUP; 142 | msg.msg_head.can_id = 0x42; 143 | 144 | if (loops & 3) 145 | msg.msg_head.flags = SETTIMER|STARTTIMER; 146 | else 147 | msg.msg_head.flags = 0; 148 | 149 | /* test TX_RESET_MULTI_IDX */ 150 | if (loops & 16) 151 | msg.msg_head.flags |= TX_RESET_MULTI_IDX; 152 | 153 | msg.msg_head.nframes = NFRAMES/2; 154 | msg.msg_head.count = 8; 155 | msg.msg_head.ival1.tv_sec = 0; 156 | msg.msg_head.ival1.tv_usec = 1000; 157 | msg.msg_head.ival2.tv_sec = 0; 158 | msg.msg_head.ival2.tv_usec = 0; 159 | 160 | /* fill data that shows the variables */ 161 | for (i = 0; i < NFRAMES; i++) { 162 | msg.frame[i].can_id = loops; 163 | msg.frame[i].len = (i & 7) + 1; 164 | msg.frame[i].data[0] = i; 165 | } 166 | 167 | if (write(s, &msg, sizeof(msg)) < 0) 168 | perror("write"); 169 | } 170 | 171 | usleep(20000); 172 | 173 | msg.msg_head.opcode = TX_SETUP; 174 | msg.msg_head.can_id = 0x42; 175 | msg.msg_head.flags = SETTIMER|STARTTIMER; 176 | msg.msg_head.nframes = 1; 177 | msg.msg_head.count = 0; 178 | msg.msg_head.ival1.tv_sec = 0; 179 | msg.msg_head.ival1.tv_usec = 0; 180 | msg.msg_head.ival2.tv_sec = 0; 181 | msg.msg_head.ival2.tv_usec = 0; 182 | msg.frame[0].can_id = 0x42; 183 | msg.frame[0].can_dlc = 8; 184 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 185 | 186 | if (write(s, &msg, sizeof(msg)) < 0) 187 | perror("write"); 188 | 189 | close(s); 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /bcm/tst-bcm-rtr.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-rtr.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | #include 59 | 60 | #define RTR_SETUP 61 | 62 | int main(int argc, char **argv) 63 | { 64 | int s,nbytes; 65 | struct sockaddr_can addr; 66 | struct timeval tv; 67 | 68 | struct { 69 | struct bcm_msg_head msg_head; 70 | struct can_frame frame; 71 | } txmsg, rxmsg; 72 | 73 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 74 | perror("socket"); 75 | return 1; 76 | } 77 | 78 | addr.can_family = PF_CAN; 79 | addr.can_ifindex = if_nametoindex("vcan2"); 80 | 81 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 82 | perror("connect"); 83 | return 1; 84 | } 85 | 86 | #ifdef RTR_SETUP 87 | /* specify CAN-Frame to send as reply to a RTR-request */ 88 | txmsg.msg_head.opcode = RX_SETUP; 89 | txmsg.msg_head.can_id = 0x359 | CAN_RTR_FLAG; 90 | txmsg.msg_head.flags = RX_RTR_FRAME; /* | TX_CP_CAN_ID */; 91 | txmsg.msg_head.ival1.tv_sec = 0; /* no timers in RTR-mode */ 92 | txmsg.msg_head.ival1.tv_usec = 0; 93 | txmsg.msg_head.ival2.tv_sec = 0; 94 | txmsg.msg_head.ival2.tv_usec = 0; 95 | txmsg.msg_head.nframes = 1; /* exact 1 */ 96 | 97 | /* the frame to send as reply ... */ 98 | txmsg.frame.can_id = 0x359; /* 'should' be the same */ 99 | txmsg.frame.can_dlc = 3; 100 | txmsg.frame.data[0] = 0x12; 101 | txmsg.frame.data[1] = 0x34; 102 | txmsg.frame.data[2] = 0x56; 103 | 104 | #else 105 | /* normal receiption of RTR-frames in Userspace */ 106 | txmsg.msg_head.opcode = RX_SETUP; 107 | txmsg.msg_head.can_id = 0x359 | CAN_RTR_FLAG; 108 | txmsg.msg_head.flags = RX_FILTER_ID; 109 | txmsg.msg_head.ival1.tv_sec = 0; 110 | txmsg.msg_head.ival1.tv_usec = 0; 111 | txmsg.msg_head.ival2.tv_sec = 0; 112 | txmsg.msg_head.ival2.tv_usec = 0; 113 | txmsg.msg_head.nframes = 0; 114 | #endif 115 | 116 | if (write(s, &txmsg, sizeof(txmsg)) < 0) 117 | perror("write"); 118 | 119 | while (1) { 120 | 121 | if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0) 122 | perror("read"); 123 | 124 | ioctl(s, SIOCGSTAMP, &tv); 125 | printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec); 126 | 127 | if (rxmsg.msg_head.opcode == RX_CHANGED && 128 | nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) && 129 | (rxmsg.msg_head.can_id & CAN_SFF_MASK) == 0x359 && 130 | (rxmsg.frame.can_id & CAN_SFF_MASK) == 0x359) { 131 | printf("RX_CHANGED message for can_id <%03X> RTR = %d\n", 132 | rxmsg.frame.can_id, (rxmsg.frame.can_id & CAN_RTR_FLAG)?1:0); 133 | } 134 | } 135 | 136 | close(s); 137 | 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /bcm/tst-bcm-rx-sendto.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-rx-sendto.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | #include 59 | 60 | int main(int argc, char **argv) 61 | { 62 | int s,nbytes; 63 | struct sockaddr_can addr; 64 | struct ifreq ifr; 65 | struct timeval tv; 66 | 67 | struct { 68 | struct bcm_msg_head msg_head; 69 | struct can_frame frame; 70 | } txmsg, rxmsg; 71 | 72 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 73 | perror("socket"); 74 | return 1; 75 | } 76 | 77 | addr.can_family = PF_CAN; 78 | addr.can_ifindex = 0; /* bind to 'any' device */ 79 | 80 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 81 | perror("connect"); 82 | return 1; 83 | } 84 | 85 | memset(&txmsg, 0, sizeof(txmsg)); /* clear timers, nframes, etc. */ 86 | 87 | txmsg.msg_head.opcode = RX_SETUP; 88 | txmsg.msg_head.can_id = 0x123; 89 | txmsg.msg_head.flags = RX_FILTER_ID; 90 | 91 | if (write(s, &txmsg, sizeof(txmsg)) < 0) 92 | perror("write"); 93 | 94 | addr.can_family = PF_CAN; 95 | addr.can_ifindex = if_nametoindex("vcan2"); 96 | 97 | txmsg.msg_head.opcode = RX_SETUP; 98 | txmsg.msg_head.can_id = 0x321; 99 | txmsg.msg_head.flags = RX_FILTER_ID; 100 | 101 | if (sendto(s, &txmsg, sizeof(txmsg), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) 102 | perror("sendto"); 103 | 104 | addr.can_family = PF_CAN; 105 | addr.can_ifindex = if_nametoindex("vcan1"); 106 | 107 | txmsg.msg_head.opcode = RX_SETUP; 108 | txmsg.msg_head.can_id = 0x424; 109 | txmsg.msg_head.flags = RX_FILTER_ID; 110 | 111 | if (sendto(s, &txmsg, sizeof(txmsg), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) 112 | perror("sendto"); 113 | 114 | while (1) { 115 | socklen_t len = sizeof(addr); 116 | nbytes = recvfrom(s, &rxmsg, sizeof(rxmsg), 117 | 0, (struct sockaddr*)&addr, &len); 118 | if (nbytes < 0) { 119 | perror("recvfrom"); 120 | return 1; 121 | } else if (nbytes < sizeof(rxmsg)) { 122 | fprintf(stderr, "recvfrom: incomplete BCM message from iface %d\n", 123 | addr.can_ifindex); 124 | return 1; 125 | } else { 126 | int i; 127 | 128 | ioctl(s, SIOCGSTAMP, &tv); 129 | printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec); 130 | 131 | ifr.ifr_ifindex = addr.can_ifindex; 132 | ioctl(s, SIOCGIFNAME, &ifr); 133 | 134 | printf(" %-5s ", ifr.ifr_name); 135 | if (rxmsg.frame.can_id & CAN_EFF_FLAG) 136 | printf("%8X ", rxmsg.frame.can_id & CAN_EFF_MASK); 137 | else 138 | printf("%3X ", rxmsg.frame.can_id & CAN_SFF_MASK); 139 | 140 | printf("[%d] ", rxmsg.frame.can_dlc); 141 | 142 | for (i = 0; i < rxmsg.frame.can_dlc; i++) { 143 | printf("%02X ", rxmsg.frame.data[i]); 144 | } 145 | if (rxmsg.frame.can_id & CAN_RTR_FLAG) 146 | printf("remote request"); 147 | printf("\n"); 148 | fflush(stdout); 149 | } 150 | } 151 | 152 | close(s); 153 | 154 | return 0; 155 | } 156 | -------------------------------------------------------------------------------- /bcm/tst-bcm-single.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-single.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | int main(int argc, char **argv) 60 | { 61 | int s; 62 | struct sockaddr_can addr; 63 | 64 | struct { 65 | struct bcm_msg_head msg_head; 66 | struct can_frame frame; 67 | } msg; 68 | 69 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 70 | perror("socket"); 71 | return 1; 72 | } 73 | 74 | addr.can_family = PF_CAN; 75 | addr.can_ifindex = if_nametoindex("vcan2"); 76 | 77 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 78 | perror("connect"); 79 | return 1; 80 | } 81 | 82 | msg.msg_head.opcode = TX_SEND; 83 | msg.msg_head.can_id = 0x760; 84 | msg.msg_head.flags = 0; 85 | msg.msg_head.nframes = 1; 86 | msg.msg_head.count = 0; 87 | msg.msg_head.ival1.tv_sec = 0; 88 | msg.msg_head.ival1.tv_usec = 0; 89 | msg.msg_head.ival2.tv_sec = 0; 90 | msg.msg_head.ival2.tv_usec = 0; 91 | msg.frame.can_id = 0x760; 92 | msg.frame.can_dlc = 6; 93 | msg.frame.data[0] = 0xA1; 94 | msg.frame.data[1] = 0x0F; 95 | msg.frame.data[2] = 0x10; 96 | msg.frame.data[3] = 0x00; 97 | msg.frame.data[4] = 0x00; 98 | msg.frame.data[5] = 0x00; 99 | 100 | 101 | if (write(s, &msg, sizeof(msg)) < 0) 102 | perror("write"); 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /bcm/tst-bcm-tx-delete.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-tx_delete.c 4 | * 5 | * Copyright (c) 2016 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s; 64 | struct sockaddr_can addr; 65 | 66 | struct { 67 | struct bcm_msg_head msg_head; 68 | struct can_frame frame; 69 | } msg; 70 | 71 | struct { 72 | struct bcm_msg_head msg_head; 73 | struct canfd_frame frame; 74 | } fdmsg; 75 | 76 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 77 | perror("socket"); 78 | return 1; 79 | } 80 | 81 | addr.can_family = PF_CAN; 82 | addr.can_ifindex = if_nametoindex("vcan2"); 83 | 84 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 85 | perror("connect"); 86 | return 1; 87 | } 88 | 89 | msg.msg_head.opcode = TX_SETUP; 90 | msg.msg_head.can_id = 0x42; 91 | msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID; 92 | msg.msg_head.nframes = 1; 93 | msg.msg_head.count = 0; 94 | msg.msg_head.ival1.tv_sec = 0; 95 | msg.msg_head.ival1.tv_usec = 0; 96 | msg.msg_head.ival2.tv_sec = 0; 97 | msg.msg_head.ival2.tv_usec = 1; 98 | msg.frame.can_dlc = 8; 99 | U64_DATA(&msg.frame) = (__u64) 0xdeadbeefdeadbeefULL; 100 | 101 | if (write(s, &msg, sizeof(msg)) < 0) 102 | perror("write"); 103 | 104 | printf("Press any key to stop the cycle ...\n"); 105 | 106 | getchar(); 107 | 108 | msg.msg_head.opcode = TX_DELETE; 109 | msg.msg_head.can_id = 0x42; 110 | msg.msg_head.flags = 0; 111 | msg.msg_head.nframes = 0; 112 | msg.msg_head.count = 0; 113 | msg.msg_head.ival1.tv_sec = 0; 114 | msg.msg_head.ival1.tv_usec = 0; 115 | msg.msg_head.ival2.tv_sec = 0; 116 | msg.msg_head.ival2.tv_usec = 0; 117 | 118 | if (write(s, &msg, sizeof(struct bcm_msg_head)) < 0) 119 | perror("write"); 120 | 121 | printf("Press any key to start the FD cycle ...\n"); 122 | 123 | getchar(); 124 | 125 | fdmsg.msg_head.opcode = TX_SETUP; 126 | fdmsg.msg_head.can_id = 0x42; 127 | fdmsg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID|CAN_FD_FRAME; 128 | fdmsg.msg_head.nframes = 1; 129 | fdmsg.msg_head.count = 0; 130 | fdmsg.msg_head.ival1.tv_sec = 0; 131 | fdmsg.msg_head.ival1.tv_usec = 0; 132 | fdmsg.msg_head.ival2.tv_sec = 0; 133 | fdmsg.msg_head.ival2.tv_usec = 1; 134 | fdmsg.frame.len = 8; 135 | U64_DATA(&fdmsg.frame) = (__u64) 0xdeadbeefdeadbeefULL; 136 | 137 | if (write(s, &fdmsg, sizeof(fdmsg)) < 0) 138 | perror("write"); 139 | 140 | printf("Press any key to stop the cycle ...\n"); 141 | 142 | getchar(); 143 | 144 | fdmsg.msg_head.opcode = TX_DELETE; 145 | fdmsg.msg_head.can_id = 0x42; 146 | fdmsg.msg_head.flags = CAN_FD_FRAME; 147 | fdmsg.msg_head.nframes = 0; 148 | fdmsg.msg_head.count = 0; 149 | fdmsg.msg_head.ival1.tv_sec = 0; 150 | fdmsg.msg_head.ival1.tv_usec = 0; 151 | fdmsg.msg_head.ival2.tv_sec = 0; 152 | fdmsg.msg_head.ival2.tv_usec = 0; 153 | 154 | if (write(s, &fdmsg, sizeof(struct bcm_msg_head)) < 0) 155 | perror("write"); 156 | 157 | printf("Press any key to close the socket ...\n"); 158 | 159 | getchar(); 160 | 161 | close(s); 162 | 163 | printf("done\n"); 164 | 165 | return 0; 166 | } 167 | -------------------------------------------------------------------------------- /bcm/tst-bcm-tx-read.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-tx_read.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s,i,nbytes; 64 | struct sockaddr_can addr; 65 | 66 | struct { 67 | struct bcm_msg_head msg_head; 68 | struct can_frame frame[4]; 69 | } msg; 70 | 71 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 72 | perror("socket"); 73 | return 1; 74 | } 75 | 76 | addr.can_family = PF_CAN; 77 | addr.can_ifindex = if_nametoindex("vcan2"); 78 | 79 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 80 | perror("connect"); 81 | return 1; 82 | } 83 | 84 | msg.msg_head.opcode = TX_SETUP; 85 | msg.msg_head.can_id = 0x42; 86 | msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID|TX_COUNTEVT; 87 | msg.msg_head.nframes = 1; 88 | msg.msg_head.count = 2; 89 | msg.msg_head.ival1.tv_sec = 3; 90 | msg.msg_head.ival1.tv_usec = 0; 91 | msg.msg_head.ival2.tv_sec = 5; 92 | msg.msg_head.ival2.tv_usec = 0; 93 | msg.frame[0].can_id = 0xAA; 94 | msg.frame[0].can_dlc = 8; 95 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 96 | 97 | if (write(s, &msg, sizeof(msg)) < 0) 98 | perror("write"); 99 | 100 | printf("Press any key to stop the cycle ...\n"); 101 | 102 | getchar(); 103 | 104 | msg.msg_head.opcode = TX_SETUP; 105 | msg.msg_head.can_id = 0x42; 106 | msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID; 107 | msg.msg_head.nframes = 1; 108 | msg.msg_head.count = 0; 109 | msg.msg_head.ival1.tv_sec = 0; 110 | msg.msg_head.ival1.tv_usec = 0; 111 | msg.msg_head.ival2.tv_sec = 0; 112 | msg.msg_head.ival2.tv_usec = 0; 113 | msg.frame[0].can_id = 0xAA; 114 | msg.frame[0].can_dlc = 8; 115 | U64_DATA(&msg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL; 116 | 117 | if (write(s, &msg, sizeof(msg)) < 0) 118 | perror("write"); 119 | 120 | printf("Press any key to read the entry ...\n"); 121 | 122 | getchar(); 123 | 124 | msg.msg_head.opcode = TX_READ; 125 | msg.msg_head.can_id = 0x42; 126 | msg.msg_head.nframes = 0; 127 | 128 | if (write(s, &msg, sizeof(msg)) < 0) 129 | perror("write"); 130 | 131 | printf("Press any key to read from the socket ...\n"); 132 | 133 | getchar(); 134 | 135 | if ((nbytes = read(s, &msg, sizeof(msg))) < 0) 136 | perror("read"); 137 | for (i = 0; i < nbytes; i++) 138 | printf(" %02x", ((unsigned char*)&msg)[i]); 139 | putchar('\n'); 140 | 141 | printf("Press any key to close the socket ...\n"); 142 | 143 | getchar(); 144 | 145 | close(s); 146 | 147 | printf("Press any key to end the program ...\n"); 148 | 149 | getchar(); 150 | 151 | return 0; 152 | } 153 | -------------------------------------------------------------------------------- /bcm/tst-bcm-tx-sendto.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-tx-sendto.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s; 64 | struct sockaddr_can addr; 65 | 66 | struct { 67 | struct bcm_msg_head msg_head; 68 | struct can_frame frame; 69 | } txmsg; 70 | 71 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 72 | perror("socket"); 73 | return 1; 74 | } 75 | 76 | addr.can_family = PF_CAN; 77 | addr.can_ifindex = 0; /* bind to 'any' device */ 78 | 79 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 80 | perror("connect"); 81 | return 1; 82 | } 83 | 84 | txmsg.msg_head.opcode = TX_SETUP; 85 | txmsg.msg_head.can_id = 0x42; 86 | txmsg.msg_head.flags = SETTIMER|STARTTIMER; 87 | txmsg.msg_head.nframes = 1; 88 | txmsg.msg_head.count = 10; 89 | txmsg.msg_head.ival1.tv_sec = 1; 90 | txmsg.msg_head.ival1.tv_usec = 0; 91 | txmsg.msg_head.ival2.tv_sec = 0; 92 | txmsg.msg_head.ival2.tv_usec = 0; 93 | txmsg.frame.can_id = 0x42; 94 | txmsg.frame.can_dlc = 8; 95 | U64_DATA(&txmsg.frame) = (__u64) 0xdeadbeefdeadbeefULL; 96 | 97 | /* should cause an error due to ifindex = 0 */ 98 | if (write(s, &txmsg, sizeof(txmsg)) < 0) 99 | perror("write"); 100 | 101 | printf("Press any key to send on valid device ...\n"); 102 | getchar(); 103 | 104 | addr.can_family = PF_CAN; 105 | addr.can_ifindex = if_nametoindex("vcan2"); 106 | 107 | if (sendto(s, &txmsg, sizeof(txmsg), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) 108 | perror("sendto"); 109 | 110 | printf("Press any key to close the socket ...\n"); 111 | getchar(); 112 | 113 | close(s); 114 | 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /bcm/tst-bcmfd-cycle.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-bcm-cycle.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define U64_DATA(p) (*(unsigned long long*)p) 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s; 64 | struct sockaddr_can addr; 65 | 66 | struct { 67 | struct bcm_msg_head msg_head; 68 | struct canfd_frame frame; 69 | } msg; 70 | 71 | if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) { 72 | perror("socket"); 73 | return 1; 74 | } 75 | 76 | addr.can_family = PF_CAN; 77 | addr.can_ifindex = if_nametoindex("vcan2"); 78 | 79 | if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 80 | perror("connect"); 81 | return 1; 82 | } 83 | 84 | msg.msg_head.opcode = TX_SETUP; 85 | msg.msg_head.can_id = 0x42; 86 | msg.msg_head.flags = SETTIMER|STARTTIMER|CAN_FD_FRAME; 87 | msg.msg_head.nframes = 1; 88 | msg.msg_head.count = 10; 89 | msg.msg_head.ival1.tv_sec = 1; 90 | msg.msg_head.ival1.tv_usec = 0; 91 | msg.msg_head.ival2.tv_sec = 0; 92 | msg.msg_head.ival2.tv_usec = 0; 93 | msg.frame.can_id = 0x42; 94 | msg.frame.len = 16; 95 | U64_DATA(&msg.frame.data[0]) = (__u64) 0xdeadbeefdeadbeefULL; 96 | U64_DATA(&msg.frame.data[8]) = (__u64) 0x123456789ABCDEFULL; 97 | 98 | if (write(s, &msg, sizeof(msg)) < 0) 99 | perror("write"); 100 | 101 | printf("Press any key to stop the cycle ...\n"); 102 | 103 | getchar(); 104 | 105 | msg.msg_head.opcode = TX_SETUP; 106 | msg.msg_head.can_id = 0x42; 107 | msg.msg_head.flags = SETTIMER|STARTTIMER|CAN_FD_FRAME; 108 | msg.msg_head.nframes = 1; 109 | msg.msg_head.count = 0; 110 | msg.msg_head.ival1.tv_sec = 0; 111 | msg.msg_head.ival1.tv_usec = 0; 112 | msg.msg_head.ival2.tv_sec = 0; 113 | msg.msg_head.ival2.tv_usec = 0; 114 | msg.frame.can_id = 0x42; 115 | msg.frame.len = 16; 116 | U64_DATA(&msg.frame.data[0]) = (__u64) 0xdeadbeefdeadbeefULL; 117 | U64_DATA(&msg.frame.data[8]) = (__u64) 0x123456789ABCDEFULL; 118 | 119 | if (write(s, &msg, sizeof(msg)) < 0) 120 | perror("write"); 121 | 122 | printf("Press any key to close the socket ...\n"); 123 | 124 | getchar(); 125 | 126 | close(s); 127 | 128 | printf("Press any key to end the program ...\n"); 129 | 130 | getchar(); 131 | 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /gw/gwtest.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * A real quick'n'dirty hack to add a netlink CAN gateway entry. 4 | * 5 | * Parts of this code were taken from the iproute source and the original 6 | * vcan.c from Urs Thuermann. 7 | * 8 | * Oliver Hartkopp 2010-02-18 9 | */ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define NLMSG_TAIL(nmsg) \ 27 | ((struct rtattr *)(((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) 28 | 29 | int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, 30 | int alen) 31 | { 32 | int len = RTA_LENGTH(alen); 33 | struct rtattr *rta; 34 | 35 | if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { 36 | fprintf(stderr, "addattr_l: message exceeded bound of %d\n", 37 | maxlen); 38 | return -1; 39 | } 40 | rta = NLMSG_TAIL(n); 41 | rta->rta_type = type; 42 | rta->rta_len = len; 43 | memcpy(RTA_DATA(rta), data, alen); 44 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); 45 | return 0; 46 | } 47 | 48 | int main(int argc, char **argv) 49 | { 50 | int s; 51 | 52 | struct { 53 | struct nlmsghdr n; 54 | struct rtcanmsg r; 55 | char buf[1000]; 56 | 57 | } req; 58 | 59 | struct can_filter filter; 60 | struct sockaddr_nl nladdr; 61 | 62 | struct cgw_frame_mod modmsg; 63 | 64 | u_int32_t src = if_nametoindex("vcan2"); 65 | u_int32_t dst = if_nametoindex("vcan3"); 66 | 67 | s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 68 | 69 | memset(&req, 0, sizeof(req)); 70 | 71 | req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtcanmsg)); 72 | req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; 73 | req.n.nlmsg_type = RTM_NEWROUTE; 74 | req.n.nlmsg_seq = 0; 75 | 76 | req.r.can_family = AF_CAN; 77 | req.r.gwtype = CGW_TYPE_CAN_CAN; 78 | req.r.flags = CGW_FLAGS_CAN_ECHO; 79 | 80 | addattr_l(&req.n, sizeof(req), CGW_SRC_IF, &src, sizeof(src)); 81 | addattr_l(&req.n, sizeof(req), CGW_DST_IF, &dst, sizeof(dst)); 82 | 83 | /* add new attributes here */ 84 | 85 | filter.can_id = 0x400; 86 | filter.can_mask = 0x700; 87 | 88 | addattr_l(&req.n, sizeof(req), CGW_FILTER, &filter, sizeof(filter)); 89 | 90 | if (sizeof(modmsg) != CGW_MODATTR_LEN) { 91 | printf("Problem with packed msg. Use linear copy instead.\n"); 92 | return 1; 93 | } 94 | 95 | modmsg.cf.can_id = 0x555; 96 | modmsg.cf.can_dlc = 5; 97 | *(unsigned long long *)modmsg.cf.data = 0x5555555555555555ULL; 98 | 99 | modmsg.modtype = CGW_MOD_ID; 100 | addattr_l(&req.n, sizeof(req), CGW_MOD_SET, &modmsg, CGW_MODATTR_LEN); 101 | 102 | modmsg.modtype = CGW_MOD_DLC; 103 | addattr_l(&req.n, sizeof(req), CGW_MOD_AND, &modmsg, CGW_MODATTR_LEN); 104 | 105 | modmsg.modtype = CGW_MOD_DATA; 106 | addattr_l(&req.n, sizeof(req), CGW_MOD_XOR, &modmsg, CGW_MODATTR_LEN); 107 | 108 | memset(&nladdr, 0, sizeof(nladdr)); 109 | nladdr.nl_family = AF_NETLINK; 110 | nladdr.nl_pid = 0; 111 | nladdr.nl_groups = 0; 112 | 113 | sendto(s, &req, req.n.nlmsg_len, 0, 114 | (struct sockaddr*)&nladdr, sizeof(nladdr)); 115 | 116 | perror("netlink says "); 117 | close(s); 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /include/linux/can/bcm.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 | /* 3 | * linux/can/bcm.h 4 | * 5 | * Definitions for CAN Broadcast Manager (BCM) 6 | * 7 | * Author: Oliver Hartkopp 8 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of Volkswagen nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * Alternatively, provided that this notice is retained in full, this 24 | * software may be distributed under the terms of the GNU General 25 | * Public License ("GPL") version 2, in which case the provisions of the 26 | * GPL apply INSTEAD OF those given above. 27 | * 28 | * The provided data structures and external interfaces from this code 29 | * are not restricted to be used by modules with a GPL compatible license. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 42 | * DAMAGE. 43 | */ 44 | 45 | #ifndef _UAPI_CAN_BCM_H 46 | #define _UAPI_CAN_BCM_H 47 | 48 | #include 49 | #include 50 | 51 | struct bcm_timeval { 52 | long tv_sec; 53 | long tv_usec; 54 | }; 55 | 56 | /** 57 | * struct bcm_msg_head - head of messages to/from the broadcast manager 58 | * @opcode: opcode, see enum below. 59 | * @flags: special flags, see below. 60 | * @count: number of frames to send before changing interval. 61 | * @ival1: interval for the first @count frames. 62 | * @ival2: interval for the following frames. 63 | * @can_id: CAN ID of frames to be sent or received. 64 | * @nframes: number of frames appended to the message head. 65 | * @frames: array of CAN frames. 66 | */ 67 | struct bcm_msg_head { 68 | __u32 opcode; 69 | __u32 flags; 70 | __u32 count; 71 | struct bcm_timeval ival1, ival2; 72 | canid_t can_id; 73 | __u32 nframes; 74 | struct can_frame frames[]; 75 | }; 76 | 77 | enum { 78 | TX_SETUP = 1, /* create (cyclic) transmission task */ 79 | TX_DELETE, /* remove (cyclic) transmission task */ 80 | TX_READ, /* read properties of (cyclic) transmission task */ 81 | TX_SEND, /* send one CAN frame */ 82 | RX_SETUP, /* create RX content filter subscription */ 83 | RX_DELETE, /* remove RX content filter subscription */ 84 | RX_READ, /* read properties of RX content filter subscription */ 85 | TX_STATUS, /* reply to TX_READ request */ 86 | TX_EXPIRED, /* notification on performed transmissions (count=0) */ 87 | RX_STATUS, /* reply to RX_READ request */ 88 | RX_TIMEOUT, /* cyclic message is absent */ 89 | RX_CHANGED /* updated CAN frame (detected content change) */ 90 | }; 91 | 92 | #define SETTIMER 0x0001 93 | #define STARTTIMER 0x0002 94 | #define TX_COUNTEVT 0x0004 95 | #define TX_ANNOUNCE 0x0008 96 | #define TX_CP_CAN_ID 0x0010 97 | #define RX_FILTER_ID 0x0020 98 | #define RX_CHECK_DLC 0x0040 99 | #define RX_NO_AUTOTIMER 0x0080 100 | #define RX_ANNOUNCE_RESUME 0x0100 101 | #define TX_RESET_MULTI_IDX 0x0200 102 | #define RX_RTR_FRAME 0x0400 103 | #define CAN_FD_FRAME 0x0800 104 | 105 | #endif /* !_UAPI_CAN_BCM_H */ 106 | -------------------------------------------------------------------------------- /include/linux/can/error.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 | /* 3 | * linux/can/error.h 4 | * 5 | * Definitions of the CAN error messages to be filtered and passed to the user. 6 | * 7 | * Author: Oliver Hartkopp 8 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of Volkswagen nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * Alternatively, provided that this notice is retained in full, this 24 | * software may be distributed under the terms of the GNU General 25 | * Public License ("GPL") version 2, in which case the provisions of the 26 | * GPL apply INSTEAD OF those given above. 27 | * 28 | * The provided data structures and external interfaces from this code 29 | * are not restricted to be used by modules with a GPL compatible license. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 42 | * DAMAGE. 43 | */ 44 | 45 | #ifndef _UAPI_CAN_ERROR_H 46 | #define _UAPI_CAN_ERROR_H 47 | 48 | #define CAN_ERR_DLC 8 /* dlc for error message frames */ 49 | 50 | /* error class (mask) in can_id */ 51 | #define CAN_ERR_TX_TIMEOUT 0x00000001U /* TX timeout (by netdevice driver) */ 52 | #define CAN_ERR_LOSTARB 0x00000002U /* lost arbitration / data[0] */ 53 | #define CAN_ERR_CRTL 0x00000004U /* controller problems / data[1] */ 54 | #define CAN_ERR_PROT 0x00000008U /* protocol violations / data[2..3] */ 55 | #define CAN_ERR_TRX 0x00000010U /* transceiver status / data[4] */ 56 | #define CAN_ERR_ACK 0x00000020U /* received no ACK on transmission */ 57 | #define CAN_ERR_BUSOFF 0x00000040U /* bus off */ 58 | #define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */ 59 | #define CAN_ERR_RESTARTED 0x00000100U /* controller restarted */ 60 | #define CAN_ERR_CNT 0x00000200U /* TX error counter / data[6] */ 61 | /* RX error counter / data[7] */ 62 | 63 | /* arbitration lost in bit ... / data[0] */ 64 | #define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */ 65 | /* else bit number in bitstream */ 66 | 67 | /* error status of CAN-controller / data[1] */ 68 | #define CAN_ERR_CRTL_UNSPEC 0x00 /* unspecified */ 69 | #define CAN_ERR_CRTL_RX_OVERFLOW 0x01 /* RX buffer overflow */ 70 | #define CAN_ERR_CRTL_TX_OVERFLOW 0x02 /* TX buffer overflow */ 71 | #define CAN_ERR_CRTL_RX_WARNING 0x04 /* reached warning level for RX errors */ 72 | #define CAN_ERR_CRTL_TX_WARNING 0x08 /* reached warning level for TX errors */ 73 | #define CAN_ERR_CRTL_RX_PASSIVE 0x10 /* reached error passive status RX */ 74 | #define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */ 75 | /* (at least one error counter exceeds */ 76 | /* the protocol-defined level of 127) */ 77 | #define CAN_ERR_CRTL_ACTIVE 0x40 /* recovered to error active state */ 78 | 79 | /* error in CAN protocol (type) / data[2] */ 80 | #define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */ 81 | #define CAN_ERR_PROT_BIT 0x01 /* single bit error */ 82 | #define CAN_ERR_PROT_FORM 0x02 /* frame format error */ 83 | #define CAN_ERR_PROT_STUFF 0x04 /* bit stuffing error */ 84 | #define CAN_ERR_PROT_BIT0 0x08 /* unable to send dominant bit */ 85 | #define CAN_ERR_PROT_BIT1 0x10 /* unable to send recessive bit */ 86 | #define CAN_ERR_PROT_OVERLOAD 0x20 /* bus overload */ 87 | #define CAN_ERR_PROT_ACTIVE 0x40 /* active error announcement */ 88 | #define CAN_ERR_PROT_TX 0x80 /* error occurred on transmission */ 89 | 90 | /* error in CAN protocol (location) / data[3] */ 91 | #define CAN_ERR_PROT_LOC_UNSPEC 0x00 /* unspecified */ 92 | #define CAN_ERR_PROT_LOC_SOF 0x03 /* start of frame */ 93 | #define CAN_ERR_PROT_LOC_ID28_21 0x02 /* ID bits 28 - 21 (SFF: 10 - 3) */ 94 | #define CAN_ERR_PROT_LOC_ID20_18 0x06 /* ID bits 20 - 18 (SFF: 2 - 0 )*/ 95 | #define CAN_ERR_PROT_LOC_SRTR 0x04 /* substitute RTR (SFF: RTR) */ 96 | #define CAN_ERR_PROT_LOC_IDE 0x05 /* identifier extension */ 97 | #define CAN_ERR_PROT_LOC_ID17_13 0x07 /* ID bits 17-13 */ 98 | #define CAN_ERR_PROT_LOC_ID12_05 0x0F /* ID bits 12-5 */ 99 | #define CAN_ERR_PROT_LOC_ID04_00 0x0E /* ID bits 4-0 */ 100 | #define CAN_ERR_PROT_LOC_RTR 0x0C /* RTR */ 101 | #define CAN_ERR_PROT_LOC_RES1 0x0D /* reserved bit 1 */ 102 | #define CAN_ERR_PROT_LOC_RES0 0x09 /* reserved bit 0 */ 103 | #define CAN_ERR_PROT_LOC_DLC 0x0B /* data length code */ 104 | #define CAN_ERR_PROT_LOC_DATA 0x0A /* data section */ 105 | #define CAN_ERR_PROT_LOC_CRC_SEQ 0x08 /* CRC sequence */ 106 | #define CAN_ERR_PROT_LOC_CRC_DEL 0x18 /* CRC delimiter */ 107 | #define CAN_ERR_PROT_LOC_ACK 0x19 /* ACK slot */ 108 | #define CAN_ERR_PROT_LOC_ACK_DEL 0x1B /* ACK delimiter */ 109 | #define CAN_ERR_PROT_LOC_EOF 0x1A /* end of frame */ 110 | #define CAN_ERR_PROT_LOC_INTERM 0x12 /* intermission */ 111 | 112 | /* error status of CAN-transceiver / data[4] */ 113 | /* CANH CANL */ 114 | #define CAN_ERR_TRX_UNSPEC 0x00 /* 0000 0000 */ 115 | #define CAN_ERR_TRX_CANH_NO_WIRE 0x04 /* 0000 0100 */ 116 | #define CAN_ERR_TRX_CANH_SHORT_TO_BAT 0x05 /* 0000 0101 */ 117 | #define CAN_ERR_TRX_CANH_SHORT_TO_VCC 0x06 /* 0000 0110 */ 118 | #define CAN_ERR_TRX_CANH_SHORT_TO_GND 0x07 /* 0000 0111 */ 119 | #define CAN_ERR_TRX_CANL_NO_WIRE 0x40 /* 0100 0000 */ 120 | #define CAN_ERR_TRX_CANL_SHORT_TO_BAT 0x50 /* 0101 0000 */ 121 | #define CAN_ERR_TRX_CANL_SHORT_TO_VCC 0x60 /* 0110 0000 */ 122 | #define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */ 123 | #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */ 124 | 125 | /* data[5] is reserved (do not use) */ 126 | 127 | /* TX error counter / data[6] */ 128 | /* RX error counter / data[7] */ 129 | 130 | /* CAN state thresholds 131 | * 132 | * Error counter Error state 133 | * ----------------------------------- 134 | * 0 - 95 Error-active 135 | * 96 - 127 Error-warning 136 | * 128 - 255 Error-passive 137 | * 256 and greater Bus-off 138 | */ 139 | #define CAN_ERROR_WARNING_THRESHOLD 96 140 | #define CAN_ERROR_PASSIVE_THRESHOLD 128 141 | #define CAN_BUS_OFF_THRESHOLD 256 142 | 143 | #endif /* _UAPI_CAN_ERROR_H */ 144 | -------------------------------------------------------------------------------- /include/linux/can/gw.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 | /* 3 | * linux/can/gw.h 4 | * 5 | * Definitions for CAN frame Gateway/Router/Bridge 6 | * 7 | * Author: Oliver Hartkopp 8 | * Copyright (c) 2011 Volkswagen Group Electronic Research 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of Volkswagen nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * Alternatively, provided that this notice is retained in full, this 24 | * software may be distributed under the terms of the GNU General 25 | * Public License ("GPL") version 2, in which case the provisions of the 26 | * GPL apply INSTEAD OF those given above. 27 | * 28 | * The provided data structures and external interfaces from this code 29 | * are not restricted to be used by modules with a GPL compatible license. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 42 | * DAMAGE. 43 | */ 44 | 45 | #ifndef _UAPI_CAN_GW_H 46 | #define _UAPI_CAN_GW_H 47 | 48 | #include 49 | #include 50 | 51 | struct rtcanmsg { 52 | __u8 can_family; 53 | __u8 gwtype; 54 | __u16 flags; 55 | }; 56 | 57 | /* CAN gateway types */ 58 | enum { 59 | CGW_TYPE_UNSPEC, 60 | CGW_TYPE_CAN_CAN, /* CAN->CAN routing */ 61 | __CGW_TYPE_MAX 62 | }; 63 | 64 | #define CGW_TYPE_MAX (__CGW_TYPE_MAX - 1) 65 | 66 | /* CAN rtnetlink attribute definitions */ 67 | enum { 68 | CGW_UNSPEC, 69 | CGW_MOD_AND, /* CAN frame modification binary AND */ 70 | CGW_MOD_OR, /* CAN frame modification binary OR */ 71 | CGW_MOD_XOR, /* CAN frame modification binary XOR */ 72 | CGW_MOD_SET, /* CAN frame modification set alternate values */ 73 | CGW_CS_XOR, /* set data[] XOR checksum into data[index] */ 74 | CGW_CS_CRC8, /* set data[] CRC8 checksum into data[index] */ 75 | CGW_HANDLED, /* number of handled CAN frames */ 76 | CGW_DROPPED, /* number of dropped CAN frames */ 77 | CGW_SRC_IF, /* ifindex of source network interface */ 78 | CGW_DST_IF, /* ifindex of destination network interface */ 79 | CGW_FILTER, /* specify struct can_filter on source CAN device */ 80 | CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ 81 | CGW_LIM_HOPS, /* limit the number of hops of this specific rule */ 82 | CGW_MOD_UID, /* user defined identifier for modification updates */ 83 | CGW_FDMOD_AND, /* CAN FD frame modification binary AND */ 84 | CGW_FDMOD_OR, /* CAN FD frame modification binary OR */ 85 | CGW_FDMOD_XOR, /* CAN FD frame modification binary XOR */ 86 | CGW_FDMOD_SET, /* CAN FD frame modification set alternate values */ 87 | __CGW_MAX 88 | }; 89 | 90 | #define CGW_MAX (__CGW_MAX - 1) 91 | 92 | #define CGW_FLAGS_CAN_ECHO 0x01 93 | #define CGW_FLAGS_CAN_SRC_TSTAMP 0x02 94 | #define CGW_FLAGS_CAN_IIF_TX_OK 0x04 95 | #define CGW_FLAGS_CAN_FD 0x08 96 | 97 | #define CGW_MOD_FUNCS 4 /* AND OR XOR SET */ 98 | 99 | /* CAN frame elements that are affected by curr. 3 CAN frame modifications */ 100 | #define CGW_MOD_ID 0x01 101 | #define CGW_MOD_DLC 0x02 /* Classical CAN data length code */ 102 | #define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD (plain) data length */ 103 | #define CGW_MOD_DATA 0x04 104 | #define CGW_MOD_FLAGS 0x08 /* CAN FD flags */ 105 | 106 | #define CGW_FRAME_MODS 4 /* ID DLC/LEN DATA FLAGS */ 107 | 108 | #define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS) 109 | 110 | struct cgw_frame_mod { 111 | struct can_frame cf; 112 | __u8 modtype; 113 | } __attribute__((packed)); 114 | 115 | struct cgw_fdframe_mod { 116 | struct canfd_frame cf; 117 | __u8 modtype; 118 | } __attribute__((packed)); 119 | 120 | #define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod) 121 | #define CGW_FDMODATTR_LEN sizeof(struct cgw_fdframe_mod) 122 | 123 | struct cgw_csum_xor { 124 | __s8 from_idx; 125 | __s8 to_idx; 126 | __s8 result_idx; 127 | __u8 init_xor_val; 128 | } __attribute__((packed)); 129 | 130 | struct cgw_csum_crc8 { 131 | __s8 from_idx; 132 | __s8 to_idx; 133 | __s8 result_idx; 134 | __u8 init_crc_val; 135 | __u8 final_xor_val; 136 | __u8 crctab[256]; 137 | __u8 profile; 138 | __u8 profile_data[20]; 139 | } __attribute__((packed)); 140 | 141 | /* length of checksum operation parameters. idx = index in CAN frame data[] */ 142 | #define CGW_CS_XOR_LEN sizeof(struct cgw_csum_xor) 143 | #define CGW_CS_CRC8_LEN sizeof(struct cgw_csum_crc8) 144 | 145 | /* CRC8 profiles (compute CRC for additional data elements - see below) */ 146 | enum { 147 | CGW_CRC8PRF_UNSPEC, 148 | CGW_CRC8PRF_1U8, /* compute one additional u8 value */ 149 | CGW_CRC8PRF_16U8, /* u8 value table indexed by data[1] & 0xF */ 150 | CGW_CRC8PRF_SFFID_XOR, /* (can_id & 0xFF) ^ (can_id >> 8 & 0xFF) */ 151 | __CGW_CRC8PRF_MAX 152 | }; 153 | 154 | #define CGW_CRC8PRF_MAX (__CGW_CRC8PRF_MAX - 1) 155 | 156 | /* 157 | * CAN rtnetlink attribute contents in detail 158 | * 159 | * CGW_XXX_IF (length 4 bytes): 160 | * Sets an interface index for source/destination network interfaces. 161 | * For the CAN->CAN gwtype the indices of _two_ CAN interfaces are mandatory. 162 | * 163 | * CGW_FILTER (length 8 bytes): 164 | * Sets a CAN receive filter for the gateway job specified by the 165 | * struct can_filter described in include/linux/can.h 166 | * 167 | * CGW_MOD_(AND|OR|XOR|SET) (length 17 bytes): 168 | * Specifies a modification that's done to a received CAN frame before it is 169 | * send out to the destination interface. 170 | * 171 | * data used as operator 172 | * affected CAN frame elements 173 | * 174 | * CGW_LIM_HOPS (length 1 byte): 175 | * Limit the number of hops of this specific rule. Usually the received CAN 176 | * frame can be processed as much as 'max_hops' times (which is given at module 177 | * load time of the can-gw module). This value is used to reduce the number of 178 | * possible hops for this gateway rule to a value smaller then max_hops. 179 | * 180 | * CGW_MOD_UID (length 4 bytes): 181 | * Optional non-zero user defined routing job identifier to alter existing 182 | * modification settings at runtime. 183 | * 184 | * CGW_CS_XOR (length 4 bytes): 185 | * Set a simple XOR checksum starting with an initial value into 186 | * data[result-idx] using data[start-idx] .. data[end-idx] 187 | * 188 | * The XOR checksum is calculated like this: 189 | * 190 | * xor = init_xor_val 191 | * 192 | * for (i = from_idx .. to_idx) 193 | * xor ^= can_frame.data[i] 194 | * 195 | * can_frame.data[ result_idx ] = xor 196 | * 197 | * CGW_CS_CRC8 (length 282 bytes): 198 | * Set a CRC8 value into data[result-idx] using a given 256 byte CRC8 table, 199 | * a given initial value and a defined input data[start-idx] .. data[end-idx]. 200 | * Finally the result value is XOR'ed with the final_xor_val. 201 | * 202 | * The CRC8 checksum is calculated like this: 203 | * 204 | * crc = init_crc_val 205 | * 206 | * for (i = from_idx .. to_idx) 207 | * crc = crctab[ crc ^ can_frame.data[i] ] 208 | * 209 | * can_frame.data[ result_idx ] = crc ^ final_xor_val 210 | * 211 | * The calculated CRC may contain additional source data elements that can be 212 | * defined in the handling of 'checksum profiles' e.g. shown in AUTOSAR specs 213 | * like http://www.autosar.org/download/R4.0/AUTOSAR_SWS_E2ELibrary.pdf 214 | * E.g. the profile_data[] may contain additional u8 values (called DATA_IDs) 215 | * that are used depending on counter values inside the CAN frame data[]. 216 | * So far only three profiles have been implemented for illustration. 217 | * 218 | * Remark: In general the attribute data is a linear buffer. 219 | * Beware of sending unpacked or aligned structs! 220 | */ 221 | 222 | #endif /* !_UAPI_CAN_GW_H */ 223 | -------------------------------------------------------------------------------- /include/linux/can/isotp.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 | /* 3 | * linux/can/isotp.h 4 | * 5 | * Definitions for isotp CAN sockets (ISO 15765-2:2016) 6 | * 7 | * Copyright (c) 2020 Volkswagen Group Electronic Research 8 | * All rights reserved. 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 | * 3. Neither the name of Volkswagen nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * Alternatively, provided that this notice is retained in full, this 23 | * software may be distributed under the terms of the GNU General 24 | * Public License ("GPL") version 2, in which case the provisions of the 25 | * GPL apply INSTEAD OF those given above. 26 | * 27 | * The provided data structures and external interfaces from this code 28 | * are not restricted to be used by modules with a GPL compatible license. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 41 | * DAMAGE. 42 | */ 43 | 44 | #ifndef _UAPI_CAN_ISOTP_H 45 | #define _UAPI_CAN_ISOTP_H 46 | 47 | #include 48 | #include 49 | 50 | #define SOL_CAN_ISOTP (SOL_CAN_BASE + CAN_ISOTP) 51 | 52 | /* for socket options affecting the socket (not the global system) */ 53 | 54 | #define CAN_ISOTP_OPTS 1 /* pass struct can_isotp_options */ 55 | 56 | #define CAN_ISOTP_RECV_FC 2 /* pass struct can_isotp_fc_options */ 57 | 58 | /* sockopts to force stmin timer values for protocol regression tests */ 59 | 60 | #define CAN_ISOTP_TX_STMIN 3 /* pass __u32 value in nano secs */ 61 | /* use this time instead of value */ 62 | /* provided in FC from the receiver */ 63 | 64 | #define CAN_ISOTP_RX_STMIN 4 /* pass __u32 value in nano secs */ 65 | /* ignore received CF frames which */ 66 | /* timestamps differ less than val */ 67 | 68 | #define CAN_ISOTP_LL_OPTS 5 /* pass struct can_isotp_ll_options */ 69 | 70 | struct can_isotp_options { 71 | 72 | __u32 flags; /* set flags for isotp behaviour. */ 73 | /* __u32 value : flags see below */ 74 | 75 | __u32 frame_txtime; /* frame transmission time (N_As/N_Ar) */ 76 | /* __u32 value : time in nano secs */ 77 | 78 | __u8 ext_address; /* set address for extended addressing */ 79 | /* __u8 value : extended address */ 80 | 81 | __u8 txpad_content; /* set content of padding byte (tx) */ 82 | /* __u8 value : content on tx path */ 83 | 84 | __u8 rxpad_content; /* set content of padding byte (rx) */ 85 | /* __u8 value : content on rx path */ 86 | 87 | __u8 rx_ext_address; /* set address for extended addressing */ 88 | /* __u8 value : extended address (rx) */ 89 | }; 90 | 91 | struct can_isotp_fc_options { 92 | 93 | __u8 bs; /* blocksize provided in FC frame */ 94 | /* __u8 value : blocksize. 0 = off */ 95 | 96 | __u8 stmin; /* separation time provided in FC frame */ 97 | /* __u8 value : */ 98 | /* 0x00 - 0x7F : 0 - 127 ms */ 99 | /* 0x80 - 0xF0 : reserved */ 100 | /* 0xF1 - 0xF9 : 100 us - 900 us */ 101 | /* 0xFA - 0xFF : reserved */ 102 | 103 | __u8 wftmax; /* max. number of wait frame transmiss. */ 104 | /* __u8 value : 0 = omit FC N_PDU WT */ 105 | }; 106 | 107 | struct can_isotp_ll_options { 108 | 109 | __u8 mtu; /* generated & accepted CAN frame type */ 110 | /* __u8 value : */ 111 | /* CAN_MTU (16) -> standard CAN 2.0 */ 112 | /* CANFD_MTU (72) -> CAN FD frame */ 113 | 114 | __u8 tx_dl; /* tx link layer data length in bytes */ 115 | /* (configured maximum payload length) */ 116 | /* __u8 value : 8,12,16,20,24,32,48,64 */ 117 | /* => rx path supports all LL_DL values */ 118 | 119 | __u8 tx_flags; /* set into struct canfd_frame.flags */ 120 | /* at frame creation: e.g. CANFD_BRS */ 121 | /* Obsolete when the BRS flag is fixed */ 122 | /* by the CAN netdriver configuration */ 123 | }; 124 | 125 | /* flags for isotp behaviour */ 126 | 127 | #define CAN_ISOTP_LISTEN_MODE 0x0001 /* listen only (do not send FC) */ 128 | #define CAN_ISOTP_EXTEND_ADDR 0x0002 /* enable extended addressing */ 129 | #define CAN_ISOTP_TX_PADDING 0x0004 /* enable CAN frame padding tx path */ 130 | #define CAN_ISOTP_RX_PADDING 0x0008 /* enable CAN frame padding rx path */ 131 | #define CAN_ISOTP_CHK_PAD_LEN 0x0010 /* check received CAN frame padding */ 132 | #define CAN_ISOTP_CHK_PAD_DATA 0x0020 /* check received CAN frame padding */ 133 | #define CAN_ISOTP_HALF_DUPLEX 0x0040 /* half duplex error state handling */ 134 | #define CAN_ISOTP_FORCE_TXSTMIN 0x0080 /* ignore stmin from received FC */ 135 | #define CAN_ISOTP_FORCE_RXSTMIN 0x0100 /* ignore CFs depending on rx stmin */ 136 | #define CAN_ISOTP_RX_EXT_ADDR 0x0200 /* different rx extended addressing */ 137 | #define CAN_ISOTP_WAIT_TX_DONE 0x0400 /* wait for tx completion */ 138 | #define CAN_ISOTP_SF_BROADCAST 0x0800 /* 1-to-N functional addressing */ 139 | #define CAN_ISOTP_CF_BROADCAST 0x1000 /* 1-to-N transmission w/o FC */ 140 | #define CAN_ISOTP_DYN_FC_PARMS 0x2000 /* dynamic FC parameters BS/STmin */ 141 | 142 | /* protocol machine default values */ 143 | 144 | #define CAN_ISOTP_DEFAULT_FLAGS 0 145 | #define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00 146 | #define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC /* prevent bit-stuffing */ 147 | #define CAN_ISOTP_DEFAULT_FRAME_TXTIME 50000 /* 50 micro seconds */ 148 | #define CAN_ISOTP_DEFAULT_RECV_BS 0 149 | #define CAN_ISOTP_DEFAULT_RECV_STMIN 0x00 150 | #define CAN_ISOTP_DEFAULT_RECV_WFTMAX 0 151 | 152 | /* 153 | * Remark on CAN_ISOTP_DEFAULT_RECV_* values: 154 | * 155 | * We can strongly assume, that the Linux Kernel implementation of 156 | * CAN_ISOTP is capable to run with BS=0, STmin=0 and WFTmax=0. 157 | * But as we like to be able to behave as a commonly available ECU, 158 | * these default settings can be changed via sockopts. 159 | * For that reason the STmin value is intentionally _not_ checked for 160 | * consistency and copied directly into the flow control (FC) frame. 161 | */ 162 | 163 | /* link layer default values => make use of Classical CAN frames */ 164 | 165 | #define CAN_ISOTP_DEFAULT_LL_MTU CAN_MTU 166 | #define CAN_ISOTP_DEFAULT_LL_TX_DL CAN_MAX_DLEN 167 | #define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0 168 | 169 | /* 170 | * The CAN_ISOTP_DEFAULT_FRAME_TXTIME has become a non-zero value as 171 | * it only makes sense for isotp implementation tests to run without 172 | * a N_As value. As user space applications usually do not set the 173 | * frame_txtime element of struct can_isotp_options the new in-kernel 174 | * default is very likely overwritten with zero when the sockopt() 175 | * CAN_ISOTP_OPTS is invoked. 176 | * To make sure that a N_As value of zero is only set intentional the 177 | * value '0' is now interpreted as 'do not change the current value'. 178 | * When a frame_txtime of zero is required for testing purposes this 179 | * CAN_ISOTP_FRAME_TXTIME_ZERO u32 value has to be set in frame_txtime. 180 | */ 181 | #define CAN_ISOTP_FRAME_TXTIME_ZERO 0xFFFFFFFF 182 | 183 | #endif /* !_UAPI_CAN_ISOTP_H */ 184 | -------------------------------------------------------------------------------- /include/linux/can/j1939.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ 2 | /* 3 | * j1939.h 4 | * 5 | * Copyright (c) 2010-2011 EIA Electronics 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License version 2 as 9 | * published by the Free Software Foundation. 10 | */ 11 | 12 | #ifndef _UAPI_CAN_J1939_H_ 13 | #define _UAPI_CAN_J1939_H_ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #define J1939_MAX_UNICAST_ADDR 0xfd 20 | #define J1939_IDLE_ADDR 0xfe 21 | #define J1939_NO_ADDR 0xff /* == broadcast or no addr */ 22 | #define J1939_NO_NAME 0 23 | #define J1939_PGN_REQUEST 0x0ea00 /* Request PG */ 24 | #define J1939_PGN_ADDRESS_CLAIMED 0x0ee00 /* Address Claimed */ 25 | #define J1939_PGN_ADDRESS_COMMANDED 0x0fed8 /* Commanded Address */ 26 | #define J1939_PGN_PDU1_MAX 0x3ff00 27 | #define J1939_PGN_MAX 0x3ffff 28 | #define J1939_NO_PGN 0x40000 29 | 30 | /* J1939 Parameter Group Number 31 | * 32 | * bit 0-7 : PDU Specific (PS) 33 | * bit 8-15 : PDU Format (PF) 34 | * bit 16 : Data Page (DP) 35 | * bit 17 : Reserved (R) 36 | * bit 19-31 : set to zero 37 | */ 38 | typedef __u32 pgn_t; 39 | 40 | /* J1939 Priority 41 | * 42 | * bit 0-2 : Priority (P) 43 | * bit 3-7 : set to zero 44 | */ 45 | typedef __u8 priority_t; 46 | 47 | /* J1939 NAME 48 | * 49 | * bit 0-20 : Identity Number 50 | * bit 21-31 : Manufacturer Code 51 | * bit 32-34 : ECU Instance 52 | * bit 35-39 : Function Instance 53 | * bit 40-47 : Function 54 | * bit 48 : Reserved 55 | * bit 49-55 : Vehicle System 56 | * bit 56-59 : Vehicle System Instance 57 | * bit 60-62 : Industry Group 58 | * bit 63 : Arbitrary Address Capable 59 | */ 60 | typedef __u64 name_t; 61 | 62 | /* J1939 socket options */ 63 | #define SOL_CAN_J1939 (SOL_CAN_BASE + CAN_J1939) 64 | enum { 65 | SO_J1939_FILTER = 1, /* set filters */ 66 | SO_J1939_PROMISC = 2, /* set/clr promiscuous mode */ 67 | SO_J1939_SEND_PRIO = 3, 68 | SO_J1939_ERRQUEUE = 4, 69 | }; 70 | 71 | enum { 72 | SCM_J1939_DEST_ADDR = 1, 73 | SCM_J1939_DEST_NAME = 2, 74 | SCM_J1939_PRIO = 3, 75 | SCM_J1939_ERRQUEUE = 4, 76 | }; 77 | 78 | enum { 79 | J1939_NLA_PAD, 80 | J1939_NLA_BYTES_ACKED, 81 | J1939_NLA_TOTAL_SIZE, 82 | J1939_NLA_PGN, 83 | J1939_NLA_SRC_NAME, 84 | J1939_NLA_DEST_NAME, 85 | J1939_NLA_SRC_ADDR, 86 | J1939_NLA_DEST_ADDR, 87 | }; 88 | 89 | enum { 90 | J1939_EE_INFO_NONE, 91 | J1939_EE_INFO_TX_ABORT, 92 | J1939_EE_INFO_RX_RTS, 93 | J1939_EE_INFO_RX_DPO, 94 | J1939_EE_INFO_RX_ABORT, 95 | }; 96 | 97 | struct j1939_filter { 98 | name_t name; 99 | name_t name_mask; 100 | pgn_t pgn; 101 | pgn_t pgn_mask; 102 | __u8 addr; 103 | __u8 addr_mask; 104 | }; 105 | 106 | #define J1939_FILTER_MAX 512 /* maximum number of j1939_filter set via setsockopt() */ 107 | 108 | #endif /* !_UAPI_CAN_J1939_H_ */ 109 | -------------------------------------------------------------------------------- /include/linux/can/netlink.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ 2 | /* 3 | * linux/can/netlink.h 4 | * 5 | * Definitions for the CAN netlink interface 6 | * 7 | * Copyright (c) 2009 Wolfgang Grandegger 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the version 2 of the GNU General Public License 11 | * as published by the Free Software Foundation 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | */ 18 | 19 | #ifndef _UAPI_CAN_NETLINK_H 20 | #define _UAPI_CAN_NETLINK_H 21 | 22 | #include 23 | 24 | /* 25 | * CAN bit-timing parameters 26 | * 27 | * For further information, please read chapter "8 BIT TIMING 28 | * REQUIREMENTS" of the "Bosch CAN Specification version 2.0" 29 | * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf. 30 | */ 31 | struct can_bittiming { 32 | __u32 bitrate; /* Bit-rate in bits/second */ 33 | __u32 sample_point; /* Sample point in one-tenth of a percent */ 34 | __u32 tq; /* Time quanta (TQ) in nanoseconds */ 35 | __u32 prop_seg; /* Propagation segment in TQs */ 36 | __u32 phase_seg1; /* Phase buffer segment 1 in TQs */ 37 | __u32 phase_seg2; /* Phase buffer segment 2 in TQs */ 38 | __u32 sjw; /* Synchronisation jump width in TQs */ 39 | __u32 brp; /* Bit-rate prescaler */ 40 | }; 41 | 42 | /* 43 | * CAN hardware-dependent bit-timing constant 44 | * 45 | * Used for calculating and checking bit-timing parameters 46 | */ 47 | struct can_bittiming_const { 48 | char name[16]; /* Name of the CAN controller hardware */ 49 | __u32 tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */ 50 | __u32 tseg1_max; 51 | __u32 tseg2_min; /* Time segment 2 = phase_seg2 */ 52 | __u32 tseg2_max; 53 | __u32 sjw_max; /* Synchronisation jump width */ 54 | __u32 brp_min; /* Bit-rate prescaler */ 55 | __u32 brp_max; 56 | __u32 brp_inc; 57 | }; 58 | 59 | /* 60 | * CAN clock parameters 61 | */ 62 | struct can_clock { 63 | __u32 freq; /* CAN system clock frequency in Hz */ 64 | }; 65 | 66 | /* 67 | * CAN operational and error states 68 | */ 69 | enum can_state { 70 | CAN_STATE_ERROR_ACTIVE = 0, /* RX/TX error count < 96 */ 71 | CAN_STATE_ERROR_WARNING, /* RX/TX error count < 128 */ 72 | CAN_STATE_ERROR_PASSIVE, /* RX/TX error count < 256 */ 73 | CAN_STATE_BUS_OFF, /* RX/TX error count >= 256 */ 74 | CAN_STATE_STOPPED, /* Device is stopped */ 75 | CAN_STATE_SLEEPING, /* Device is sleeping */ 76 | CAN_STATE_MAX 77 | }; 78 | 79 | /* 80 | * CAN bus error counters 81 | */ 82 | struct can_berr_counter { 83 | __u16 txerr; 84 | __u16 rxerr; 85 | }; 86 | 87 | /* 88 | * CAN controller mode 89 | */ 90 | struct can_ctrlmode { 91 | __u32 mask; 92 | __u32 flags; 93 | }; 94 | 95 | #define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ 96 | #define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ 97 | #define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ 98 | #define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ 99 | #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ 100 | #define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ 101 | #define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */ 102 | #define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */ 103 | #define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */ 104 | #define CAN_CTRLMODE_TDC_AUTO 0x200 /* CAN transiver automatically calculates TDCV */ 105 | #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* TDCV is manually set up by user */ 106 | 107 | /* 108 | * CAN device statistics 109 | */ 110 | struct can_device_stats { 111 | __u32 bus_error; /* Bus errors */ 112 | __u32 error_warning; /* Changes to error warning state */ 113 | __u32 error_passive; /* Changes to error passive state */ 114 | __u32 bus_off; /* Changes to bus off state */ 115 | __u32 arbitration_lost; /* Arbitration lost errors */ 116 | __u32 restarts; /* CAN controller re-starts */ 117 | }; 118 | 119 | /* 120 | * CAN netlink interface 121 | */ 122 | enum { 123 | IFLA_CAN_UNSPEC, 124 | IFLA_CAN_BITTIMING, 125 | IFLA_CAN_BITTIMING_CONST, 126 | IFLA_CAN_CLOCK, 127 | IFLA_CAN_STATE, 128 | IFLA_CAN_CTRLMODE, 129 | IFLA_CAN_RESTART_MS, 130 | IFLA_CAN_RESTART, 131 | IFLA_CAN_BERR_COUNTER, 132 | IFLA_CAN_DATA_BITTIMING, 133 | IFLA_CAN_DATA_BITTIMING_CONST, 134 | IFLA_CAN_TERMINATION, 135 | IFLA_CAN_TERMINATION_CONST, 136 | IFLA_CAN_BITRATE_CONST, 137 | IFLA_CAN_DATA_BITRATE_CONST, 138 | IFLA_CAN_BITRATE_MAX, 139 | IFLA_CAN_TDC, 140 | IFLA_CAN_CTRLMODE_EXT, 141 | 142 | /* add new constants above here */ 143 | __IFLA_CAN_MAX, 144 | IFLA_CAN_MAX = __IFLA_CAN_MAX - 1 145 | }; 146 | 147 | /* 148 | * CAN FD Transmitter Delay Compensation (TDC) 149 | * 150 | * Please refer to struct can_tdc_const and can_tdc in 151 | * include/linux/can/bittiming.h for further details. 152 | */ 153 | enum { 154 | IFLA_CAN_TDC_UNSPEC, 155 | IFLA_CAN_TDC_TDCV_MIN, /* u32 */ 156 | IFLA_CAN_TDC_TDCV_MAX, /* u32 */ 157 | IFLA_CAN_TDC_TDCO_MIN, /* u32 */ 158 | IFLA_CAN_TDC_TDCO_MAX, /* u32 */ 159 | IFLA_CAN_TDC_TDCF_MIN, /* u32 */ 160 | IFLA_CAN_TDC_TDCF_MAX, /* u32 */ 161 | IFLA_CAN_TDC_TDCV, /* u32 */ 162 | IFLA_CAN_TDC_TDCO, /* u32 */ 163 | IFLA_CAN_TDC_TDCF, /* u32 */ 164 | 165 | /* add new constants above here */ 166 | __IFLA_CAN_TDC, 167 | IFLA_CAN_TDC_MAX = __IFLA_CAN_TDC - 1 168 | }; 169 | 170 | /* 171 | * IFLA_CAN_CTRLMODE_EXT nest: controller mode extended parameters 172 | */ 173 | enum { 174 | IFLA_CAN_CTRLMODE_UNSPEC, 175 | IFLA_CAN_CTRLMODE_SUPPORTED, /* u32 */ 176 | 177 | /* add new constants above here */ 178 | __IFLA_CAN_CTRLMODE, 179 | IFLA_CAN_CTRLMODE_MAX = __IFLA_CAN_CTRLMODE - 1 180 | }; 181 | 182 | /* u16 termination range: 1..65535 Ohms */ 183 | #define CAN_TERMINATION_DISABLED 0 184 | 185 | #endif /* !_UAPI_CAN_NETLINK_H */ 186 | -------------------------------------------------------------------------------- /include/linux/can/raw.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */ 2 | /* 3 | * linux/can/raw.h 4 | * 5 | * Definitions for raw CAN sockets 6 | * 7 | * Authors: Oliver Hartkopp 8 | * Urs Thuermann 9 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. Neither the name of Volkswagen nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * Alternatively, provided that this notice is retained in full, this 25 | * software may be distributed under the terms of the GNU General 26 | * Public License ("GPL") version 2, in which case the provisions of the 27 | * GPL apply INSTEAD OF those given above. 28 | * 29 | * The provided data structures and external interfaces from this code 30 | * are not restricted to be used by modules with a GPL compatible license. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 42 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 43 | * DAMAGE. 44 | */ 45 | 46 | #ifndef _UAPI_CAN_RAW_H 47 | #define _UAPI_CAN_RAW_H 48 | 49 | #include 50 | 51 | #define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW) 52 | #define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */ 53 | 54 | enum { 55 | SCM_CAN_RAW_ERRQUEUE = 1, 56 | }; 57 | 58 | /* for socket options affecting the socket (not the global system) */ 59 | 60 | enum { 61 | CAN_RAW_FILTER = 1, /* set 0 .. n can_filter(s) */ 62 | CAN_RAW_ERR_FILTER, /* set filter for error frames */ 63 | CAN_RAW_LOOPBACK, /* local loopback (default:on) */ 64 | CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */ 65 | CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */ 66 | CAN_RAW_JOIN_FILTERS, /* all filters must match to trigger */ 67 | CAN_RAW_XL_FRAMES, /* allow CAN XL frames (default:off) */ 68 | CAN_RAW_XL_VCID_OPTS, /* CAN XL VCID configuration options */ 69 | }; 70 | 71 | /* configuration for CAN XL virtual CAN identifier (VCID) handling */ 72 | struct can_raw_vcid_options { 73 | 74 | __u8 flags; /* flags for vcid (filter) behaviour */ 75 | __u8 tx_vcid; /* VCID value set into canxl_frame.prio */ 76 | __u8 rx_vcid; /* VCID value for VCID filter */ 77 | __u8 rx_vcid_mask; /* VCID mask for VCID filter */ 78 | 79 | }; 80 | 81 | /* can_raw_vcid_options.flags for CAN XL virtual CAN identifier handling */ 82 | #define CAN_RAW_XL_VCID_TX_SET 0x01 83 | #define CAN_RAW_XL_VCID_TX_PASS 0x02 84 | #define CAN_RAW_XL_VCID_RX_FILTER 0x04 85 | 86 | #endif /* !_UAPI_CAN_RAW_H */ 87 | -------------------------------------------------------------------------------- /include/linux/can/vxcan.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ 2 | #ifndef _UAPI_CAN_VXCAN_H 3 | #define _UAPI_CAN_VXCAN_H 4 | 5 | enum { 6 | VXCAN_INFO_UNSPEC, 7 | VXCAN_INFO_PEER, 8 | 9 | __VXCAN_INFO_MAX 10 | #define VXCAN_INFO_MAX (__VXCAN_INFO_MAX - 1) 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/linux/errqueue.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | #ifndef _UAPI_LINUX_ERRQUEUE_H 3 | #define _UAPI_LINUX_ERRQUEUE_H 4 | 5 | #include 6 | 7 | struct sock_extended_err { 8 | __u32 ee_errno; 9 | __u8 ee_origin; 10 | __u8 ee_type; 11 | __u8 ee_code; 12 | __u8 ee_pad; 13 | __u32 ee_info; 14 | __u32 ee_data; 15 | }; 16 | 17 | #define SO_EE_ORIGIN_NONE 0 18 | #define SO_EE_ORIGIN_LOCAL 1 19 | #define SO_EE_ORIGIN_ICMP 2 20 | #define SO_EE_ORIGIN_ICMP6 3 21 | #define SO_EE_ORIGIN_TXSTATUS 4 22 | #define SO_EE_ORIGIN_ZEROCOPY 5 23 | #define SO_EE_ORIGIN_TXTIME 6 24 | #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS 25 | 26 | #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) 27 | 28 | #define SO_EE_CODE_ZEROCOPY_COPIED 1 29 | 30 | #define SO_EE_CODE_TXTIME_INVALID_PARAM 1 31 | #define SO_EE_CODE_TXTIME_MISSED 2 32 | 33 | /** 34 | * struct scm_timestamping - timestamps exposed through cmsg 35 | * 36 | * The timestamping interfaces SO_TIMESTAMPING, MSG_TSTAMP_* 37 | * communicate network timestamps by passing this struct in a cmsg with 38 | * recvmsg(). See Documentation/networking/timestamping.txt for details. 39 | */ 40 | struct scm_timestamping { 41 | struct timespec ts[3]; 42 | }; 43 | 44 | /* The type of scm_timestamping, passed in sock_extended_err ee_info. 45 | * This defines the type of ts[0]. For SCM_TSTAMP_SND only, if ts[0] 46 | * is zero, then this is a hardware timestamp and recorded in ts[2]. 47 | */ 48 | enum { 49 | SCM_TSTAMP_SND, /* driver passed skb to NIC, or HW */ 50 | SCM_TSTAMP_SCHED, /* data entered the packet scheduler */ 51 | SCM_TSTAMP_ACK, /* data acknowledged by peer */ 52 | }; 53 | 54 | #endif /* _UAPI_LINUX_ERRQUEUE_H */ 55 | -------------------------------------------------------------------------------- /include/linux/net_tstamp.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | /* 3 | * Userspace API for hardware time stamping of network packets 4 | * 5 | * Copyright (C) 2008,2009 Intel Corporation 6 | * Author: Patrick Ohly 7 | * 8 | */ 9 | 10 | #ifndef _NET_TIMESTAMPING_H 11 | #define _NET_TIMESTAMPING_H 12 | 13 | #include 14 | #include /* for SO_TIMESTAMPING */ 15 | 16 | /* SO_TIMESTAMPING gets an integer bit field comprised of these values */ 17 | enum { 18 | SOF_TIMESTAMPING_TX_HARDWARE = (1<<0), 19 | SOF_TIMESTAMPING_TX_SOFTWARE = (1<<1), 20 | SOF_TIMESTAMPING_RX_HARDWARE = (1<<2), 21 | SOF_TIMESTAMPING_RX_SOFTWARE = (1<<3), 22 | SOF_TIMESTAMPING_SOFTWARE = (1<<4), 23 | SOF_TIMESTAMPING_SYS_HARDWARE = (1<<5), 24 | SOF_TIMESTAMPING_RAW_HARDWARE = (1<<6), 25 | SOF_TIMESTAMPING_OPT_ID = (1<<7), 26 | SOF_TIMESTAMPING_TX_SCHED = (1<<8), 27 | SOF_TIMESTAMPING_TX_ACK = (1<<9), 28 | SOF_TIMESTAMPING_OPT_CMSG = (1<<10), 29 | SOF_TIMESTAMPING_OPT_TSONLY = (1<<11), 30 | SOF_TIMESTAMPING_OPT_STATS = (1<<12), 31 | SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13), 32 | SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14), 33 | 34 | SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW, 35 | SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | 36 | SOF_TIMESTAMPING_LAST 37 | }; 38 | 39 | /* 40 | * SO_TIMESTAMPING flags are either for recording a packet timestamp or for 41 | * reporting the timestamp to user space. 42 | * Recording flags can be set both via socket options and control messages. 43 | */ 44 | #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | \ 45 | SOF_TIMESTAMPING_TX_SOFTWARE | \ 46 | SOF_TIMESTAMPING_TX_SCHED | \ 47 | SOF_TIMESTAMPING_TX_ACK) 48 | 49 | /** 50 | * struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter 51 | * 52 | * @flags: no flags defined right now, must be zero for %SIOCSHWTSTAMP 53 | * @tx_type: one of HWTSTAMP_TX_* 54 | * @rx_filter: one of HWTSTAMP_FILTER_* 55 | * 56 | * %SIOCGHWTSTAMP and %SIOCSHWTSTAMP expect a &struct ifreq with a 57 | * ifr_data pointer to this structure. For %SIOCSHWTSTAMP, if the 58 | * driver or hardware does not support the requested @rx_filter value, 59 | * the driver may use a more general filter mode. In this case 60 | * @rx_filter will indicate the actual mode on return. 61 | */ 62 | struct hwtstamp_config { 63 | int flags; 64 | int tx_type; 65 | int rx_filter; 66 | }; 67 | 68 | /* possible values for hwtstamp_config->tx_type */ 69 | enum hwtstamp_tx_types { 70 | /* 71 | * No outgoing packet will need hardware time stamping; 72 | * should a packet arrive which asks for it, no hardware 73 | * time stamping will be done. 74 | */ 75 | HWTSTAMP_TX_OFF, 76 | 77 | /* 78 | * Enables hardware time stamping for outgoing packets; 79 | * the sender of the packet decides which are to be 80 | * time stamped by setting %SOF_TIMESTAMPING_TX_SOFTWARE 81 | * before sending the packet. 82 | */ 83 | HWTSTAMP_TX_ON, 84 | 85 | /* 86 | * Enables time stamping for outgoing packets just as 87 | * HWTSTAMP_TX_ON does, but also enables time stamp insertion 88 | * directly into Sync packets. In this case, transmitted Sync 89 | * packets will not received a time stamp via the socket error 90 | * queue. 91 | */ 92 | HWTSTAMP_TX_ONESTEP_SYNC, 93 | }; 94 | 95 | /* possible values for hwtstamp_config->rx_filter */ 96 | enum hwtstamp_rx_filters { 97 | /* time stamp no incoming packet at all */ 98 | HWTSTAMP_FILTER_NONE, 99 | 100 | /* time stamp any incoming packet */ 101 | HWTSTAMP_FILTER_ALL, 102 | 103 | /* return value: time stamp all packets requested plus some others */ 104 | HWTSTAMP_FILTER_SOME, 105 | 106 | /* PTP v1, UDP, any kind of event packet */ 107 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, 108 | /* PTP v1, UDP, Sync packet */ 109 | HWTSTAMP_FILTER_PTP_V1_L4_SYNC, 110 | /* PTP v1, UDP, Delay_req packet */ 111 | HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ, 112 | /* PTP v2, UDP, any kind of event packet */ 113 | HWTSTAMP_FILTER_PTP_V2_L4_EVENT, 114 | /* PTP v2, UDP, Sync packet */ 115 | HWTSTAMP_FILTER_PTP_V2_L4_SYNC, 116 | /* PTP v2, UDP, Delay_req packet */ 117 | HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ, 118 | 119 | /* 802.AS1, Ethernet, any kind of event packet */ 120 | HWTSTAMP_FILTER_PTP_V2_L2_EVENT, 121 | /* 802.AS1, Ethernet, Sync packet */ 122 | HWTSTAMP_FILTER_PTP_V2_L2_SYNC, 123 | /* 802.AS1, Ethernet, Delay_req packet */ 124 | HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ, 125 | 126 | /* PTP v2/802.AS1, any layer, any kind of event packet */ 127 | HWTSTAMP_FILTER_PTP_V2_EVENT, 128 | /* PTP v2/802.AS1, any layer, Sync packet */ 129 | HWTSTAMP_FILTER_PTP_V2_SYNC, 130 | /* PTP v2/802.AS1, any layer, Delay_req packet */ 131 | HWTSTAMP_FILTER_PTP_V2_DELAY_REQ, 132 | 133 | /* NTP, UDP, all versions and packet modes */ 134 | HWTSTAMP_FILTER_NTP_ALL, 135 | }; 136 | 137 | /* SCM_TIMESTAMPING_PKTINFO control message */ 138 | struct scm_ts_pktinfo { 139 | __u32 if_index; 140 | __u32 pkt_length; 141 | __u32 reserved[2]; 142 | }; 143 | 144 | /* 145 | * SO_TXTIME gets a struct sock_txtime with flags being an integer bit 146 | * field comprised of these values. 147 | */ 148 | enum txtime_flags { 149 | SOF_TXTIME_DEADLINE_MODE = (1 << 0), 150 | SOF_TXTIME_REPORT_ERRORS = (1 << 1), 151 | 152 | SOF_TXTIME_FLAGS_LAST = SOF_TXTIME_REPORT_ERRORS, 153 | SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) | 154 | SOF_TXTIME_FLAGS_LAST 155 | }; 156 | 157 | struct sock_txtime { 158 | __kernel_clockid_t clockid;/* reference clockid */ 159 | __u32 flags; /* as defined by enum txtime_flags */ 160 | }; 161 | 162 | #endif /* _NET_TIMESTAMPING_H */ 163 | -------------------------------------------------------------------------------- /include/linux/netlink.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | #ifndef _UAPI__LINUX_NETLINK_H 3 | #define _UAPI__LINUX_NETLINK_H 4 | 5 | #include 6 | #include /* for __kernel_sa_family_t */ 7 | #include 8 | 9 | #define NETLINK_ROUTE 0 /* Routing/device hook */ 10 | #define NETLINK_UNUSED 1 /* Unused number */ 11 | #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ 12 | #define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */ 13 | #define NETLINK_SOCK_DIAG 4 /* socket monitoring */ 14 | #define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */ 15 | #define NETLINK_XFRM 6 /* ipsec */ 16 | #define NETLINK_SELINUX 7 /* SELinux event notifications */ 17 | #define NETLINK_ISCSI 8 /* Open-iSCSI */ 18 | #define NETLINK_AUDIT 9 /* auditing */ 19 | #define NETLINK_FIB_LOOKUP 10 20 | #define NETLINK_CONNECTOR 11 21 | #define NETLINK_NETFILTER 12 /* netfilter subsystem */ 22 | #define NETLINK_IP6_FW 13 23 | #define NETLINK_DNRTMSG 14 /* DECnet routing messages */ 24 | #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ 25 | #define NETLINK_GENERIC 16 26 | /* leave room for NETLINK_DM (DM Events) */ 27 | #define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ 28 | #define NETLINK_ECRYPTFS 19 29 | #define NETLINK_RDMA 20 30 | #define NETLINK_CRYPTO 21 /* Crypto layer */ 31 | #define NETLINK_SMC 22 /* SMC monitoring */ 32 | 33 | #define NETLINK_INET_DIAG NETLINK_SOCK_DIAG 34 | 35 | #define MAX_LINKS 32 36 | 37 | struct sockaddr_nl { 38 | __kernel_sa_family_t nl_family; /* AF_NETLINK */ 39 | unsigned short nl_pad; /* zero */ 40 | __u32 nl_pid; /* port ID */ 41 | __u32 nl_groups; /* multicast groups mask */ 42 | }; 43 | 44 | struct nlmsghdr { 45 | __u32 nlmsg_len; /* Length of message including header */ 46 | __u16 nlmsg_type; /* Message content */ 47 | __u16 nlmsg_flags; /* Additional flags */ 48 | __u32 nlmsg_seq; /* Sequence number */ 49 | __u32 nlmsg_pid; /* Sending process port ID */ 50 | }; 51 | 52 | /* Flags values */ 53 | 54 | #define NLM_F_REQUEST 0x01 /* It is request message. */ 55 | #define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */ 56 | #define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */ 57 | #define NLM_F_ECHO 0x08 /* Echo this request */ 58 | #define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */ 59 | #define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */ 60 | 61 | /* Modifiers to GET request */ 62 | #define NLM_F_ROOT 0x100 /* specify tree root */ 63 | #define NLM_F_MATCH 0x200 /* return all matching */ 64 | #define NLM_F_ATOMIC 0x400 /* atomic GET */ 65 | #define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) 66 | 67 | /* Modifiers to NEW request */ 68 | #define NLM_F_REPLACE 0x100 /* Override existing */ 69 | #define NLM_F_EXCL 0x200 /* Do not touch, if it exists */ 70 | #define NLM_F_CREATE 0x400 /* Create, if it does not exist */ 71 | #define NLM_F_APPEND 0x800 /* Add to end of list */ 72 | 73 | /* Modifiers to DELETE request */ 74 | #define NLM_F_NONREC 0x100 /* Do not delete recursively */ 75 | 76 | /* Flags for ACK message */ 77 | #define NLM_F_CAPPED 0x100 /* request was capped */ 78 | #define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */ 79 | 80 | /* 81 | 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL 82 | 4.4BSD CHANGE NLM_F_REPLACE 83 | 84 | True CHANGE NLM_F_CREATE|NLM_F_REPLACE 85 | Append NLM_F_CREATE 86 | Check NLM_F_EXCL 87 | */ 88 | 89 | #define NLMSG_ALIGNTO 4U 90 | #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) 91 | #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) 92 | #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN) 93 | #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) 94 | #define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) 95 | #define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ 96 | (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) 97 | #define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \ 98 | (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \ 99 | (int)((nlh)->nlmsg_len) <= (len)) 100 | #define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) 101 | 102 | #define NLMSG_NOOP 0x1 /* Nothing. */ 103 | #define NLMSG_ERROR 0x2 /* Error */ 104 | #define NLMSG_DONE 0x3 /* End of a dump */ 105 | #define NLMSG_OVERRUN 0x4 /* Data lost */ 106 | 107 | #define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */ 108 | 109 | struct nlmsgerr { 110 | int error; 111 | struct nlmsghdr msg; 112 | /* 113 | * followed by the message contents unless NETLINK_CAP_ACK was set 114 | * or the ACK indicates success (error == 0) 115 | * message length is aligned with NLMSG_ALIGN() 116 | */ 117 | /* 118 | * followed by TLVs defined in enum nlmsgerr_attrs 119 | * if NETLINK_EXT_ACK was set 120 | */ 121 | }; 122 | 123 | /** 124 | * enum nlmsgerr_attrs - nlmsgerr attributes 125 | * @NLMSGERR_ATTR_UNUSED: unused 126 | * @NLMSGERR_ATTR_MSG: error message string (string) 127 | * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original 128 | * message, counting from the beginning of the header (u32) 129 | * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to 130 | * be used - in the success case - to identify a created 131 | * object or operation or similar (binary) 132 | * @__NLMSGERR_ATTR_MAX: number of attributes 133 | * @NLMSGERR_ATTR_MAX: highest attribute number 134 | */ 135 | enum nlmsgerr_attrs { 136 | NLMSGERR_ATTR_UNUSED, 137 | NLMSGERR_ATTR_MSG, 138 | NLMSGERR_ATTR_OFFS, 139 | NLMSGERR_ATTR_COOKIE, 140 | 141 | __NLMSGERR_ATTR_MAX, 142 | NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1 143 | }; 144 | 145 | #define NETLINK_ADD_MEMBERSHIP 1 146 | #define NETLINK_DROP_MEMBERSHIP 2 147 | #define NETLINK_PKTINFO 3 148 | #define NETLINK_BROADCAST_ERROR 4 149 | #define NETLINK_NO_ENOBUFS 5 150 | #ifndef __KERNEL__ 151 | #define NETLINK_RX_RING 6 152 | #define NETLINK_TX_RING 7 153 | #endif 154 | #define NETLINK_LISTEN_ALL_NSID 8 155 | #define NETLINK_LIST_MEMBERSHIPS 9 156 | #define NETLINK_CAP_ACK 10 157 | #define NETLINK_EXT_ACK 11 158 | #define NETLINK_GET_STRICT_CHK 12 159 | 160 | struct nl_pktinfo { 161 | __u32 group; 162 | }; 163 | 164 | struct nl_mmap_req { 165 | unsigned int nm_block_size; 166 | unsigned int nm_block_nr; 167 | unsigned int nm_frame_size; 168 | unsigned int nm_frame_nr; 169 | }; 170 | 171 | struct nl_mmap_hdr { 172 | unsigned int nm_status; 173 | unsigned int nm_len; 174 | __u32 nm_group; 175 | /* credentials */ 176 | __u32 nm_pid; 177 | __u32 nm_uid; 178 | __u32 nm_gid; 179 | }; 180 | 181 | #ifndef __KERNEL__ 182 | enum nl_mmap_status { 183 | NL_MMAP_STATUS_UNUSED, 184 | NL_MMAP_STATUS_RESERVED, 185 | NL_MMAP_STATUS_VALID, 186 | NL_MMAP_STATUS_COPY, 187 | NL_MMAP_STATUS_SKIP, 188 | }; 189 | 190 | #define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO 191 | #define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT) 192 | #define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr)) 193 | #endif 194 | 195 | #define NET_MAJOR 36 /* Major 36 is reserved for networking */ 196 | 197 | enum { 198 | NETLINK_UNCONNECTED = 0, 199 | NETLINK_CONNECTED, 200 | }; 201 | 202 | /* 203 | * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)--> 204 | * +---------------------+- - -+- - - - - - - - - -+- - -+ 205 | * | Header | Pad | Payload | Pad | 206 | * | (struct nlattr) | ing | | ing | 207 | * +---------------------+- - -+- - - - - - - - - -+- - -+ 208 | * <-------------- nlattr->nla_len --------------> 209 | */ 210 | 211 | struct nlattr { 212 | __u16 nla_len; 213 | __u16 nla_type; 214 | }; 215 | 216 | /* 217 | * nla_type (16 bits) 218 | * +---+---+-------------------------------+ 219 | * | N | O | Attribute Type | 220 | * +---+---+-------------------------------+ 221 | * N := Carries nested attributes 222 | * O := Payload stored in network byte order 223 | * 224 | * Note: The N and O flag are mutually exclusive. 225 | */ 226 | #define NLA_F_NESTED (1 << 15) 227 | #define NLA_F_NET_BYTEORDER (1 << 14) 228 | #define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) 229 | 230 | #define NLA_ALIGNTO 4 231 | #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) 232 | #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) 233 | 234 | /* Generic 32 bitflags attribute content sent to the kernel. 235 | * 236 | * The value is a bitmap that defines the values being set 237 | * The selector is a bitmask that defines which value is legit 238 | * 239 | * Examples: 240 | * value = 0x0, and selector = 0x1 241 | * implies we are selecting bit 1 and we want to set its value to 0. 242 | * 243 | * value = 0x2, and selector = 0x2 244 | * implies we are selecting bit 2 and we want to set its value to 1. 245 | * 246 | */ 247 | struct nla_bitfield32 { 248 | __u32 value; 249 | __u32 selector; 250 | }; 251 | 252 | #endif /* _UAPI__LINUX_NETLINK_H */ 253 | -------------------------------------------------------------------------------- /j1939/README.md: -------------------------------------------------------------------------------- 1 | ### SAE J1939 Tests 2 | 3 | J1939 tests are collection of scripts which was written to reproduce 4 | one or another bug. 5 | 6 | ### Requirements 7 | 8 | - j1939cat and j1939acd should be installed on the DUT 9 | - DUT should have at least two CAN interfaces named can0 and can1 10 | connected to each other. Interfaces should be pre-configured 11 | and in the UP state. 12 | -------------------------------------------------------------------------------- /j1939/j1939_ac_100k_dual_can.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | # This test was written to reproduce following bug, where 6 | # remote address was keeping local priv allocated. Even if no other 7 | # local users was keeping the stack. 8 | # To run this test DUT should have at least two CAN interfaces named can0 9 | # and can1. 10 | # 11 | # ========================= 12 | # WARNING: held lock freed! 13 | # 5.1.0-00164-g683bec30accc-dirty #410 Not tainted 14 | # ------------------------- 15 | # j1939acd/10810 is freeing memory e8ced000-e8cedfff, with a lock still held there! 16 | # ca540dc3 (&priv->lock#4){++--}, at: j1939_ac_recv+0x9c/0x1cc 17 | # 6 locks held by j1939acd/10810: 18 | # #0: 8cae1b05 (sb_writers#6){.+.+}, at: vfs_write+0xb0/0x184 19 | # #1: 61f77435 (&sb->s_type->i_mutex_key#10){+.+.}, at: generic_file_write_iter+0x50/0x20c 20 | # #2: 724fe4e2 (rcu_read_lock){....}, at: get_mem_cgroup_from_mm+0x34/0x35c 21 | # #3: 724fe4e2 (rcu_read_lock){....}, at: netif_receive_skb_internal+0x78/0x3d4 22 | # #4: 724fe4e2 (rcu_read_lock){....}, at: can_receive+0x94/0x1d0 23 | # #5: ca540dc3 (&priv->lock#4){++--}, at: j1939_ac_recv+0x9c/0x1cc 24 | # 25 | # stack backtrace: 26 | # CPU: 0 PID: 10810 Comm: j1939acd Not tainted 5.1.0-00164-g683bec30accc-dirty #410 27 | # Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) 28 | # Backtrace: 29 | # [] (dump_backtrace) from [] (show_stack+0x20/0x24) 30 | # r7:c15cc630 r6:00000000 r5:60010193 r4:c15cc630 31 | # [] (show_stack) from [] (dump_stack+0xa0/0xcc) 32 | # [] (dump_stack) from [] (debug_check_no_locks_freed+0x110/0x12c) 33 | # r9:e8ced008 r8:e8cedfff r7:20010193 r6:e91cb180 r5:e8ced000 r4:e91cb7c8 34 | # [] (debug_check_no_locks_freed) from [] (kfree+0x2e8/0x430) 35 | # r8:60010113 r7:ebc950a0 r6:e8ced000 r5:c0b34cc4 r4:e8001700 36 | # [] (kfree) from [] (j1939_priv_put+0xa8/0xb0) 37 | # r9:e8ced008 r8:e9254200 r7:e8ced000 r6:e9872840 r5:e86f0000 r4:e8ced000 38 | # [] (j1939_priv_put) from [] (j1939_ecu_put+0x64/0x68) 39 | # r5:e8ced000 r4:e9254200 40 | # [] (j1939_ecu_put) from [] (j1939_ac_recv+0x160/0x1cc) 41 | # r5:00000000 r4:11223340 42 | # [] (j1939_ac_recv) from [] (j1939_can_recv+0x118/0x144) 43 | # r10:e9bbb9fc r9:0000012b r8:e86f08c0 r7:e9872240 r6:e8ced008 r5:e8ced000 44 | # r4:e9872840 r3:e9bba000 45 | # [] (j1939_can_recv) from [] (can_rcv_filter+0xfc/0x21c) 46 | # r7:e9872240 r6:98eefffe r5:00000001 r4:e80311b0 47 | # [] (can_rcv_filter) from [] (can_receive+0x130/0x1d0) 48 | # r9:0000012b r8:00000000 r7:e86f0000 r6:c15b00c0 r5:e8951040 r4:e9872240 49 | # [] (can_receive) from [] (can_rcv+0x8c/0x94) 50 | 51 | set -e 52 | 53 | CAN0=${1:-can0} 54 | CAN1=${2:-can1} 55 | 56 | dmesg -c > /dev/null 57 | 58 | echo "generate random data for the test" 59 | dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 60 | 61 | echo "start j1939acd and j1939cat on ${CAN0}" 62 | j1939acd -r 100,80-120 -c /tmp/11223344.j1939acd 11223344 ${CAN0} & 63 | PID_JACD0=$! 64 | echo $PID_JACD0 65 | sleep 2 66 | j1939cat ${CAN0}:,,0x11223344 -r > /tmp/blup & 67 | PID_JCAT0=$! 68 | echo $PID_JCAT0 69 | 70 | echo "start j1939acd and j1939cat on ${CAN1}" 71 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN1} & 72 | sleep 2 73 | j1939cat -i /tmp/test_100k ${CAN1}:,,0x11223340 :,,0x11223344 74 | sleep 3 75 | 76 | echo "kill all users on ${CAN0}" 77 | # At this step all local users will be removed. All address caches should 78 | # be dropped as well. 79 | kill $PID_JACD0 80 | kill $PID_JCAT0 81 | echo "kill all users on ${CAN1}" 82 | # If stack is buggy, kernel will explode somewhere here. 83 | killall j1939acd 84 | 85 | if dmesg | grep -i backtra; then 86 | echo "test failed" 87 | exit 1 88 | fi 89 | -------------------------------------------------------------------------------- /j1939/j1939_ac_100k_local0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 11 | 12 | echo "start rx j1939acd and j1939cat on ${CAN0}" 13 | j1939acd -r 100,80-120 -c /tmp/11223344.j1939acd 11223344 ${CAN0} & 14 | PID_JACD0=$! 15 | echo $PID_JACD0 16 | sleep 2 17 | j1939cat ${CAN0}:,,0x11223344 -r > /tmp/blup & 18 | PID_JCAT0=$! 19 | echo $PID_JCAT0 20 | 21 | echo "start tx j1939acd and j1939cat on ${CAN0}" 22 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN0} & 23 | PID_JACD1=$! 24 | sleep 2 25 | j1939cat -i /tmp/test_100k ${CAN0}:,,0x11223340 :,,0x11223344 26 | sleep 2 27 | 28 | echo "kill all users on ${CAN0}" 29 | kill $PID_JACD0 30 | kill $PID_JCAT0 31 | kill $PID_JACD1 32 | 33 | cmp /tmp/test_100k /tmp/blup 34 | 35 | exit $? 36 | -------------------------------------------------------------------------------- /j1939/j1939_ac_1k_bam_local0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2020 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | echo "generate random data for the test" 11 | dd if=/dev/urandom of=/tmp/test_1k bs=1K count=1 12 | 13 | j1939cat ${CAN0}:,0x12300 -B -r > /tmp/blup & 14 | PID_JCAT0=$! 15 | echo $PID_JCAT0 16 | 17 | echo "start tx j1939acd and j1939cat on ${CAN0}" 18 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN0} & 19 | PID_JACD1=$! 20 | sleep 2 21 | j1939cat -B -i /tmp/test_1k ${CAN0}:,,0x11223340 :,0x12300 22 | sleep 2 23 | 24 | echo "kill all users on ${CAN0}" 25 | kill $PID_JCAT0 26 | kill $PID_JACD1 27 | 28 | cmp /tmp/test_1k /tmp/blup 29 | exit $? 30 | -------------------------------------------------------------------------------- /j1939/j1939_ac_1k_local0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | echo "generate random data for the test" 11 | dd if=/dev/urandom of=/tmp/test_1k bs=1K count=1 12 | 13 | echo "start rx j1939acd and j1939cat on ${CAN0}" 14 | j1939acd -r 100,80-120 -c /tmp/11223344.j1939acd 11223344 ${CAN0} & 15 | PID_JACD0=$! 16 | echo $PID_JACD0 17 | sleep 2 18 | j1939cat ${CAN0}:,,0x11223344 -r > /tmp/blup & 19 | PID_JCAT0=$! 20 | echo $PID_JCAT0 21 | 22 | echo "start tx j1939acd and j1939cat on ${CAN0}" 23 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN0} & 24 | PID_JACD1=$! 25 | sleep 2 26 | j1939cat -i /tmp/test_1k ${CAN0}:,,0x11223340 :,,0x11223344 27 | sleep 2 28 | 29 | echo "kill all users on ${CAN0}" 30 | kill $PID_JACD0 31 | kill $PID_JCAT0 32 | kill $PID_JACD1 33 | 34 | cmp /tmp/test_1k /tmp/blup 35 | 36 | exit $? 37 | -------------------------------------------------------------------------------- /j1939/j1939_ac_1m_local0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | echo "generate random data for the test" 11 | dd if=/dev/urandom of=/tmp/test_1m bs=1M count=1 12 | 13 | echo "start rx j1939acd and j1939cat on ${CAN0}" 14 | j1939acd -r 100,80-120 -c /tmp/11223344.j1939acd 11223344 ${CAN0} & 15 | PID_JACD0=$! 16 | echo $PID_JACD0 17 | sleep 2 18 | j1939cat ${CAN0}:,,0x11223344 -r > /tmp/blup & 19 | PID_JCAT0=$! 20 | echo $PID_JCAT0 21 | 22 | echo "start tx j1939acd and j1939cat on ${CAN0}" 23 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN0} & 24 | PID_JACD1=$! 25 | sleep 2 26 | j1939cat -i /tmp/test_1m ${CAN0}:,,0x11223340 :,,0x11223344 27 | sleep 2 28 | 29 | echo "kill all users on ${CAN0}" 30 | kill $PID_JACD0 31 | kill $PID_JCAT0 32 | kill $PID_JACD1 33 | 34 | cmp /tmp/test_1m /tmp/blup 35 | 36 | exit $? 37 | -------------------------------------------------------------------------------- /j1939/j1939_ac_8b_local0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | echo "generate random data for the test" 11 | dd if=/dev/urandom of=/tmp/test_8b bs=8 count=1 12 | 13 | echo "start rx j1939acd and j1939cat on ${CAN0}" 14 | j1939acd -r 100,80-120 -c /tmp/11223344.j1939acd 11223344 ${CAN0} & 15 | PID_JACD0=$! 16 | echo $PID_JACD0 17 | sleep 2 18 | j1939cat ${CAN0}:,,0x11223344 -r > /tmp/blup & 19 | PID_JCAT0=$! 20 | echo $PID_JCAT0 21 | 22 | echo "start tx j1939acd and j1939cat on ${CAN0}" 23 | j1939acd -r 100,80-120 -c /tmp/11223340.j1939acd 11223340 ${CAN0} & 24 | PID_JACD1=$! 25 | sleep 2 26 | j1939cat -i /tmp/test_8b ${CAN0}:,,0x11223340 :,,0x11223344 27 | sleep 2 28 | 29 | echo "kill all users on ${CAN0}" 30 | kill $PID_JACD0 31 | kill $PID_JCAT0 32 | kill $PID_JACD1 33 | 34 | cmp /tmp/test_8b /tmp/blup 35 | 36 | exit $? 37 | -------------------------------------------------------------------------------- /j1939/j1939_multisock_dualack_100k.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 11 | 12 | dmesg -c > /dev/null 13 | 14 | j1939cat ${CAN0}:0x90 -r > /dev/null & 15 | j1939cat ${CAN1}:0x90 -r > /dev/null & 16 | 17 | for i in `seq 1 100`; do 18 | echo "start round $i" 19 | j1939cat -i /tmp/test_100k -R 100 ${CAN0}:0x80 :0x90,0x12300 & 20 | done 21 | 22 | killall j1939cat 23 | 24 | if dmesg | grep -i backtra; then 25 | echo "test failed" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /j1939/j1939_multisock_dualack_1k.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | dd if=/dev/urandom of=/tmp/test_1k bs=1K count=1 11 | 12 | dmesg -c > /dev/null 13 | 14 | j1939cat ${CAN0}:0x90 -r > /dev/null & 15 | j1939cat ${CAN1}:0x90 -r > /dev/null & 16 | 17 | for i in `seq 1 100`; do 18 | echo "start round $i" 19 | j1939cat -i /tmp/test_1k -R 100 ${CAN0}:0x80 :0x90,0x12300 & 20 | done 21 | 22 | killall j1939cat 23 | 24 | if dmesg | grep -i backtra; then 25 | echo "test failed" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /j1939/j1939_multisock_timeout_100k.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # Copyright (c) 2019 Oleksij Rempel 4 | 5 | set -e 6 | 7 | CAN0=${1:-can0} 8 | CAN1=${2:-can1} 9 | 10 | dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 11 | 12 | dmesg -c > /dev/null 13 | 14 | for i in `seq 1 100`; do 15 | echo "start round $i" 16 | j1939cat -i /tmp/test_100k -R 100 ${CAN0}:0x80 :0x90,0x12300 & 17 | done 18 | 19 | if dmesg | grep -i backtra; then 20 | echo "test failed" 21 | exit 1 22 | fi 23 | -------------------------------------------------------------------------------- /j1939/run_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | for f in j1939*.sh; do 6 | echo "##############################################" 7 | pre=$(lsmod | awk '/^can_j1939/ { print $3 }') 8 | pre=${pre:-0} 9 | echo "run: $f" 10 | ./$f "${@}" 11 | echo "done: $f" 12 | post=$(lsmod | awk '/^can_j1939/ { print $3 }') 13 | if lsmod | grep can_j1939 && [ $pre -ne $post ]; then 14 | echo "module usage: before start: $pre" 15 | echo " after finish: $post" 16 | exit 1 17 | fi 18 | echo "##############################################" 19 | done 20 | -------------------------------------------------------------------------------- /lib/lib.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * lib.h - library include for command line tools 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #ifndef CAN_UTILS_LIB_H 46 | #define CAN_UTILS_LIB_H 47 | 48 | #include 49 | 50 | /* buffer sizes for CAN frame string representations */ 51 | 52 | #define CL_ID (sizeof("12345678##1")) 53 | #define CL_DATA sizeof(".AA") 54 | #define CL_BINDATA sizeof(".10101010") 55 | 56 | /* CAN FD ASCII hex short representation with DATA_SEPERATORs */ 57 | #define CL_CFSZ (2*CL_ID + 64*CL_DATA) 58 | 59 | /* CAN FD ASCII hex long representation with binary output */ 60 | #define CL_LONGCFSZ (2*CL_ID + sizeof(" [255] ") + (64*CL_BINDATA)) 61 | 62 | /* CAN DLC to real data length conversion helpers especially for CAN FD */ 63 | 64 | /* get data length from can_dlc with sanitized can_dlc */ 65 | unsigned char can_dlc2len(unsigned char can_dlc); 66 | 67 | /* map the sanitized data length to an appropriate data length code */ 68 | unsigned char can_len2dlc(unsigned char len); 69 | 70 | unsigned char asc2nibble(char c); 71 | /* 72 | * Returns the decimal value of a given ASCII hex character. 73 | * 74 | * While 0..9, a..f, A..F are valid ASCII hex characters. 75 | * On invalid characters the value 16 is returned for error handling. 76 | */ 77 | 78 | int hexstring2data(char *arg, unsigned char *data, int maxdlen); 79 | /* 80 | * Converts a given ASCII hex string to a (binary) byte string. 81 | * 82 | * A valid ASCII hex string consists of an even number of up to 16 chars. 83 | * Leading zeros '00' in the ASCII hex string are interpreted. 84 | * 85 | * Examples: 86 | * 87 | * "1234" => data[0] = 0x12, data[1] = 0x34 88 | * "001234" => data[0] = 0x00, data[1] = 0x12, data[2] = 0x34 89 | * 90 | * Return values: 91 | * 0 = success 92 | * 1 = error (in length or the given characters are no ASCII hex characters) 93 | * 94 | * Remark: The not written data[] elements are initialized with zero. 95 | * 96 | */ 97 | 98 | int parse_canframe(char *cs, struct canfd_frame *cf); 99 | /* 100 | * Transfers a valid ASCII string decribing a CAN frame into struct canfd_frame. 101 | * 102 | * CAN 2.0 frames 103 | * - string layout #{R{len}|data} 104 | * - {data} has 0 to 8 hex-values that can (optionally) be separated by '.' 105 | * - {len} can take values from 0 to 8 and can be omitted if zero 106 | * - return value on successful parsing: CAN_MTU 107 | * 108 | * CAN FD frames 109 | * - string layout ##{data} 110 | * - a single ASCII Hex value (0 .. F) which defines canfd_frame.flags 111 | * - {data} has 0 to 64 hex-values that can (optionally) be separated by '.' 112 | * - return value on successful parsing: CANFD_MTU 113 | * 114 | * Return value on detected problems: 0 115 | * 116 | * can have 3 (standard frame format) or 8 (extended frame format) 117 | * hexadecimal chars 118 | * 119 | * 120 | * Examples: 121 | * 122 | * 123# -> standard CAN-Id = 0x123, len = 0 123 | * 12345678# -> extended CAN-Id = 0x12345678, len = 0 124 | * 123#R -> standard CAN-Id = 0x123, len = 0, RTR-frame 125 | * 123#R0 -> standard CAN-Id = 0x123, len = 0, RTR-frame 126 | * 123#R7 -> standard CAN-Id = 0x123, len = 7, RTR-frame 127 | * 7A1#r -> standard CAN-Id = 0x7A1, len = 0, RTR-frame 128 | * 129 | * 123#00 -> standard CAN-Id = 0x123, len = 1, data[0] = 0x00 130 | * 123#1122334455667788 -> standard CAN-Id = 0x123, len = 8 131 | * 123#11.22.33.44.55.66.77.88 -> standard CAN-Id = 0x123, len = 8 132 | * 123#11.2233.44556677.88 -> standard CAN-Id = 0x123, len = 8 133 | * 32345678#112233 -> error frame with CAN_ERR_FLAG (0x2000000) set 134 | * 135 | * 123##0112233 -> CAN FD frame standard CAN-Id = 0x123, flags = 0, len = 3 136 | * 123##1112233 -> CAN FD frame, flags = CANFD_BRS, len = 3 137 | * 123##2112233 -> CAN FD frame, flags = CANFD_ESI, len = 3 138 | * 123##3 -> CAN FD frame, flags = (CANFD_ESI | CANFD_BRS), len = 0 139 | * ^^ 140 | * CAN FD extension to handle the canfd_frame.flags content 141 | * 142 | * Simple facts on this compact ASCII CAN frame representation: 143 | * 144 | * - 3 digits: standard frame format 145 | * - 8 digits: extendend frame format OR error frame 146 | * - 8 digits with CAN_ERR_FLAG (0x2000000) set: error frame 147 | * - an error frame is never a RTR frame 148 | * - CAN FD frames do not have a RTR bit 149 | */ 150 | 151 | void fprint_canframe(FILE *stream , struct canfd_frame *cf, char *eol, int sep, int maxdlen); 152 | void sprint_canframe(char *buf , struct canfd_frame *cf, int sep, int maxdlen); 153 | /* 154 | * Creates a CAN frame hexadecimal output in compact format. 155 | * The CAN data[] is separated by '.' when sep != 0. 156 | * 157 | * The type of the CAN frame (CAN 2.0 / CAN FD) is specified by maxdlen: 158 | * maxdlen = 8 -> CAN2.0 frame 159 | * maxdlen = 64 -> CAN FD frame 160 | * 161 | * 12345678#112233 -> extended CAN-Id = 0x12345678, len = 3, data, sep = 0 162 | * 12345678#R -> extended CAN-Id = 0x12345678, RTR, len = 0 163 | * 12345678#R5 -> extended CAN-Id = 0x12345678, RTR, len = 5 164 | * 123#11.22.33.44.55.66.77.88 -> standard CAN-Id = 0x123, dlc = 8, sep = 1 165 | * 32345678#112233 -> error frame with CAN_ERR_FLAG (0x2000000) set 166 | * 123##0112233 -> CAN FD frame standard CAN-Id = 0x123, flags = 0, len = 3 167 | * 123##2112233 -> CAN FD frame, flags = CANFD_ESI, len = 3 168 | * 169 | * Examples: 170 | * 171 | * fprint_canframe(stdout, &frame, "\n", 0); // with eol to STDOUT 172 | * fprint_canframe(stderr, &frame, NULL, 0); // no eol to STDERR 173 | * 174 | */ 175 | 176 | #define CANLIB_VIEW_ASCII 0x1 177 | #define CANLIB_VIEW_BINARY 0x2 178 | #define CANLIB_VIEW_SWAP 0x4 179 | #define CANLIB_VIEW_ERROR 0x8 180 | #define CANLIB_VIEW_INDENT_SFF 0x10 181 | 182 | #define SWAP_DELIMITER '`' 183 | 184 | void fprint_long_canframe(FILE *stream , struct canfd_frame *cf, char *eol, int view, int maxdlen); 185 | void sprint_long_canframe(char *buf , struct canfd_frame *cf, int view, int maxdlen); 186 | /* 187 | * Creates a CAN frame hexadecimal output in user readable format. 188 | * 189 | * The type of the CAN frame (CAN 2.0 / CAN FD) is specified by maxdlen: 190 | * maxdlen = 8 -> CAN2.0 frame 191 | * maxdlen = 64 -> CAN FD frame 192 | * 193 | * 12345678 [3] 11 22 33 -> extended CAN-Id = 0x12345678, dlc = 3, data 194 | * 12345678 [0] remote request -> extended CAN-Id = 0x12345678, RTR 195 | * 14B0DC51 [8] 4A 94 E8 2A EC 58 55 62 'J..*.XUb' -> (with ASCII output) 196 | * 20001111 [7] C6 23 7B 32 69 98 3C ERRORFRAME -> (CAN_ERR_FLAG set) 197 | * 12345678 [03] 11 22 33 -> CAN FD with extended CAN-Id = 0x12345678, dlc = 3 198 | * 199 | * 123 [3] 11 22 33 -> CANLIB_VIEW_INDENT_SFF == 0 200 | * 123 [3] 11 22 33 -> CANLIB_VIEW_INDENT_SFF == set 201 | * 202 | * Examples: 203 | * 204 | * // CAN FD frame with eol to STDOUT 205 | * fprint_long_canframe(stdout, &frame, "\n", 0, CANFD_MAX_DLEN); 206 | * 207 | * // CAN 2.0 frame without eol to STDERR 208 | * fprint_long_canframe(stderr, &frame, NULL, 0, CAN_MAX_DLEN); 209 | * 210 | */ 211 | 212 | void snprintf_can_error_frame(char *buf, size_t len, const struct canfd_frame *cf, 213 | const char *sep); 214 | /* 215 | * Creates a CAN error frame output in user readable format. 216 | */ 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /lib/terminal.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of Volkswagen nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * Alternatively, provided that this notice is retained in full, this 19 | * software may be distributed under the terms of the GNU General 20 | * Public License ("GPL") version 2, in which case the provisions of the 21 | * GPL apply INSTEAD OF those given above. 22 | * 23 | * The provided data structures and external interfaces from this code 24 | * are not restricted to be used by modules with a GPL compatible license. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 37 | * DAMAGE. 38 | * 39 | * Send feedback to 40 | * 41 | */ 42 | 43 | #ifndef TERMINAL_H 44 | #define TERMINAL_H 45 | 46 | /* reset to default */ 47 | 48 | #define ATTRESET "\33[0m" 49 | 50 | /* attributes */ 51 | 52 | #define ATTBOLD "\33[1m" 53 | #define ATTUNDERLINE "\33[4m" 54 | #define ATTBLINK "\33[5m" 55 | #define ATTINVERSE "\33[7m" 56 | #define ATTINVISIBLE "\33[8m" 57 | 58 | /* foreground colors */ 59 | 60 | #define FGBLACK "\33[30m" 61 | #define FGRED "\33[31m" 62 | #define FGGREEN "\33[32m" 63 | #define FGYELLOW "\33[33m" 64 | #define FGBLUE "\33[34m" 65 | #define FGMAGENTA "\33[35m" 66 | #define FGCYAN "\33[36m" 67 | #define FGWHITE "\33[37m" 68 | 69 | /* background colors */ 70 | 71 | #define BGBLACK "\33[40m" 72 | #define BGRED "\33[41m" 73 | #define BGGREEN "\33[42m" 74 | #define BGYELLOW "\33[43m" 75 | #define BGBLUE "\33[44m" 76 | #define BGMAGENTA "\33[45m" 77 | #define BGCYAN "\33[46m" 78 | #define BGWHITE "\33[47m" 79 | 80 | /* cursor */ 81 | 82 | #define CSR_HOME "\33[H" 83 | #define CSR_UP "\33[A" 84 | #define CSR_DOWN "\33[B" 85 | #define CSR_RIGHT "\33[C" 86 | #define CSR_LEFT "\33[D" 87 | 88 | #define CSR_HIDE "\33[?25l" 89 | #define CSR_SHOW "\33[?25h" 90 | 91 | /* clear screen */ 92 | 93 | #define CLR_SCREEN "\33[2J" 94 | 95 | #endif /* TERMINAL_H */ 96 | -------------------------------------------------------------------------------- /netlayer/test_netlayer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 3 | # 4 | # testscript to check CAN filters and CAN frame flow in Linux network layer 5 | # 6 | # 7 | 8 | if [ $(id -ru) -ne 0 ]; then 9 | echo You need to be root to execute these tests 10 | exit 1 11 | fi 12 | 13 | # load needed CAN networklayer modules 14 | modprobe -f can 15 | modprobe -f can_raw 16 | 17 | # ensure the vcan driver to perform the ECHO on driver level 18 | modprobe -r vcan 19 | modprobe -f vcan echo=1 20 | 21 | VCAN=vcan0 22 | 23 | # create virtual CAN device 24 | ip link add name $VCAN type vcan || exit 1 25 | ifconfig $VCAN up 26 | 27 | # check precondition for CAN frame flow test 28 | HAS_ECHO=`ip link show $VCAN | grep -c ECHO` 29 | 30 | if [ $HAS_ECHO -ne 1 ] 31 | then 32 | return 1 33 | fi 34 | 35 | # test of CAN filters on af_can.c 36 | ./tst-filter $VCAN || return 1 37 | 38 | # test of CAN frame flow down to the netdevice and up again 39 | ./tst-rcv-own-msgs $VCAN || return 1 40 | 41 | echo --- 42 | echo "CAN networklayer tests succeeded." 43 | echo --- 44 | 45 | return 0 46 | -------------------------------------------------------------------------------- /netlayer/tst-filter-master.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-filter-master.c 4 | * 5 | * Copyright (c) 2008 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | int main(int argc, char **argv) 59 | { 60 | int s; 61 | struct sockaddr_can addr; 62 | struct can_filter rfilter; 63 | struct can_frame frame; 64 | int testcase; 65 | int nbytes; 66 | 67 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 68 | perror("socket"); 69 | return 1; 70 | } 71 | 72 | addr.can_family = AF_CAN; 73 | addr.can_ifindex = if_nametoindex("vcan0"); 74 | 75 | rfilter.can_id = 0xFA; /* receive only the filter ack */ 76 | rfilter.can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; 77 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); 78 | 79 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 80 | perror("bind"); 81 | return 1; 82 | } 83 | 84 | /* send testcases 0 .. 17 and a terminating 18 to quit */ 85 | for (testcase = 0; testcase < 19; testcase++) { 86 | 87 | printf("Sending testcase %2d ... ", testcase); 88 | frame.can_id = 0x0F; 89 | frame.can_dlc = 1; 90 | frame.data[0] = testcase; 91 | 92 | if (write(s, &frame, sizeof(frame)) < 0) { 93 | perror("write"); 94 | exit(1); 95 | } 96 | 97 | /* wait for ACK from server */ 98 | if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { 99 | perror("read"); 100 | exit(1); 101 | } 102 | 103 | if (nbytes < sizeof(struct can_frame)) { 104 | fprintf(stderr, "read: incomplete CAN frame\n"); 105 | exit(1); 106 | } 107 | 108 | if ((frame.can_id != 0xFA) || (frame.can_dlc != 1) || 109 | (frame.data[0] != testcase)) { 110 | fprintf(stderr, "\nWrong answer from server!\n"); 111 | exit(1); 112 | } 113 | 114 | printf("acked. "); 115 | if (testcase > 17) 116 | break; 117 | 118 | /* interactive mode, when there is any commandline option */ 119 | if (argc == 2) { 120 | printf("[press enter] "); 121 | getchar(); 122 | } 123 | 124 | printf("Sending patterns ... "); 125 | 126 | frame.can_dlc = 0; 127 | 128 | frame.can_id = 0x123; 129 | if (write(s, &frame, sizeof(frame)) < 0) { 130 | perror("write"); 131 | exit(1); 132 | } 133 | frame.can_id = (0x123 | CAN_RTR_FLAG); 134 | if (write(s, &frame, sizeof(frame)) < 0) { 135 | perror("write"); 136 | exit(1); 137 | } 138 | frame.can_id = (0x123 | CAN_EFF_FLAG); 139 | if (write(s, &frame, sizeof(frame)) < 0) { 140 | perror("write"); 141 | exit(1); 142 | } 143 | frame.can_id = (0x123 | CAN_EFF_FLAG | CAN_RTR_FLAG); 144 | if (write(s, &frame, sizeof(frame)) < 0) { 145 | perror("write"); 146 | exit(1); 147 | } 148 | 149 | printf("ok\n"); 150 | } 151 | 152 | printf("Filtertest done.\n"); 153 | 154 | close(s); 155 | return 0; 156 | } 157 | -------------------------------------------------------------------------------- /netlayer/tst-filter-server.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-filter-server.c 4 | * 5 | * Copyright (c) 2008 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | #define ID 0x123 59 | #define FIL 0x7FF 60 | #define EFF CAN_EFF_FLAG 61 | #define RTR CAN_RTR_FLAG 62 | 63 | canid_t calc_id(int testcase) 64 | { 65 | canid_t id = ID; 66 | 67 | if (testcase & 1) 68 | id |= EFF; 69 | if (testcase & 2) 70 | id |= RTR; 71 | 72 | return id; 73 | } 74 | 75 | canid_t calc_mask(int testcase) 76 | { 77 | canid_t mask = FIL; 78 | 79 | if (testcase > 15) 80 | return (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG); 81 | 82 | if (testcase & 4) 83 | mask |= EFF; 84 | if (testcase & 8) 85 | mask |= RTR; 86 | 87 | return mask; 88 | } 89 | 90 | int main(int argc, char **argv) 91 | { 92 | fd_set rdfs; 93 | int s, t; 94 | struct sockaddr_can addr; 95 | struct can_filter rfilter; 96 | struct can_frame frame; 97 | int testcase = 0; 98 | int nbytes, ret; 99 | 100 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 101 | perror("socket"); 102 | return 1; 103 | } 104 | if ((t = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 105 | perror("socket"); 106 | return 1; 107 | } 108 | 109 | addr.can_family = AF_CAN; 110 | addr.can_ifindex = if_nametoindex("vcan0"); 111 | 112 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 113 | perror("bind"); 114 | return 1; 115 | } 116 | if (bind(t, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 117 | perror("bind"); 118 | return 1; 119 | } 120 | 121 | rfilter.can_id = 0xF; /* receive only the filter requests */ 122 | rfilter.can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; 123 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); 124 | 125 | /* disable default receive filter on the test socket */ 126 | setsockopt(t, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); 127 | 128 | while (1) { 129 | 130 | FD_ZERO(&rdfs); 131 | FD_SET(s, &rdfs); 132 | FD_SET(t, &rdfs); 133 | 134 | if ((ret = select(t+1, &rdfs, NULL, NULL, NULL)) < 0) { 135 | perror("select"); 136 | break; 137 | } 138 | 139 | if (FD_ISSET(s, &rdfs)) { 140 | 141 | if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { 142 | perror("read"); 143 | exit(1); 144 | } 145 | 146 | if (nbytes < sizeof(struct can_frame)) { 147 | fprintf(stderr, "read: incomplete CAN frame\n"); 148 | exit(1); 149 | } 150 | 151 | if ((frame.can_id != 0xF) || (frame.can_dlc != 1)) { 152 | fprintf(stderr, "\nWrong request from master!\n"); 153 | exit(1); 154 | } 155 | 156 | testcase = frame.data[0]; 157 | 158 | if (testcase < 18) { 159 | rfilter.can_id = calc_id(testcase); 160 | rfilter.can_mask = calc_mask(testcase); 161 | setsockopt(t, SOL_CAN_RAW, CAN_RAW_FILTER, 162 | &rfilter, sizeof(rfilter)); 163 | 164 | printf("testcase %2d : can_id = 0x%08X can_mask = 0x%08X\n", 165 | testcase, rfilter.can_id, rfilter.can_mask); 166 | } 167 | 168 | frame.can_id = 0xFA; /* filter ack */ 169 | 170 | if (write(s, &frame, sizeof(frame)) < 0) { 171 | perror("write"); 172 | exit(1); 173 | } 174 | 175 | if (testcase > 17) 176 | break; 177 | } 178 | 179 | if (FD_ISSET(t, &rdfs)) { 180 | 181 | if ((nbytes = read(t, &frame, sizeof(struct can_frame))) < 0) { 182 | perror("read"); 183 | exit(1); 184 | } 185 | 186 | if (nbytes < sizeof(struct can_frame)) { 187 | fprintf(stderr, "read: incomplete CAN frame\n"); 188 | exit(1); 189 | } 190 | 191 | printf ("%08X\n", frame.can_id); 192 | } 193 | } 194 | 195 | printf("testcase %2d : Filtertest done.\n", testcase); 196 | 197 | close(s); 198 | close(t); 199 | 200 | return 0; 201 | } 202 | -------------------------------------------------------------------------------- /netlayer/tst-filter-server.result: -------------------------------------------------------------------------------- 1 | testcase 0 : can_id = 0x00000123 can_mask = 0x000007FF 2 | 00000123 3 | 40000123 4 | 80000123 5 | C0000123 6 | testcase 1 : can_id = 0x80000123 can_mask = 0x000007FF 7 | 00000123 8 | 40000123 9 | 80000123 10 | C0000123 11 | testcase 2 : can_id = 0x40000123 can_mask = 0x000007FF 12 | 00000123 13 | 40000123 14 | 80000123 15 | C0000123 16 | testcase 3 : can_id = 0xC0000123 can_mask = 0x000007FF 17 | 00000123 18 | 40000123 19 | 80000123 20 | C0000123 21 | testcase 4 : can_id = 0x00000123 can_mask = 0x800007FF 22 | 00000123 23 | 40000123 24 | testcase 5 : can_id = 0x80000123 can_mask = 0x800007FF 25 | 80000123 26 | C0000123 27 | testcase 6 : can_id = 0x40000123 can_mask = 0x800007FF 28 | 00000123 29 | 40000123 30 | testcase 7 : can_id = 0xC0000123 can_mask = 0x800007FF 31 | 80000123 32 | C0000123 33 | testcase 8 : can_id = 0x00000123 can_mask = 0x400007FF 34 | 00000123 35 | 80000123 36 | testcase 9 : can_id = 0x80000123 can_mask = 0x400007FF 37 | 00000123 38 | 80000123 39 | testcase 10 : can_id = 0x40000123 can_mask = 0x400007FF 40 | 40000123 41 | C0000123 42 | testcase 11 : can_id = 0xC0000123 can_mask = 0x400007FF 43 | 40000123 44 | C0000123 45 | testcase 12 : can_id = 0x00000123 can_mask = 0xC00007FF 46 | 00000123 47 | testcase 13 : can_id = 0x80000123 can_mask = 0xC00007FF 48 | 80000123 49 | testcase 14 : can_id = 0x40000123 can_mask = 0xC00007FF 50 | 40000123 51 | testcase 15 : can_id = 0xC0000123 can_mask = 0xC00007FF 52 | C0000123 53 | testcase 16 : can_id = 0x00000123 can_mask = 0xDFFFFFFF 54 | 00000123 55 | testcase 17 : can_id = 0x80000123 can_mask = 0xDFFFFFFF 56 | 80000123 57 | testcase 18 : Filtertest done. 58 | -------------------------------------------------------------------------------- /netlayer/tst-filter.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-filter.c 4 | * 5 | * Copyright (c) 2011 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define ID 0x123 60 | #define TC 18 /* # of testcases */ 61 | 62 | const int rx_res[TC] = {4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1}; 63 | const int rxbits_res[TC] = {4369, 4369, 4369, 4369, 17, 4352, 17, 4352, 257, 257, 4112, 4112, 1, 256, 16, 4096, 1, 256}; 64 | 65 | canid_t calc_id(int testcase) 66 | { 67 | canid_t id = ID; 68 | 69 | if (testcase & 1) 70 | id |= CAN_EFF_FLAG; 71 | if (testcase & 2) 72 | id |= CAN_RTR_FLAG; 73 | 74 | return id; 75 | } 76 | 77 | canid_t calc_mask(int testcase) 78 | { 79 | canid_t mask = CAN_SFF_MASK; 80 | 81 | if (testcase > 15) 82 | return (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG); 83 | 84 | if (testcase & 4) 85 | mask |= CAN_EFF_FLAG; 86 | if (testcase & 8) 87 | mask |= CAN_RTR_FLAG; 88 | 89 | return mask; 90 | } 91 | 92 | int main(int argc, char **argv) 93 | { 94 | fd_set rdfs; 95 | struct timeval tv; 96 | int s; 97 | struct sockaddr_can addr; 98 | struct can_filter rfilter; 99 | struct can_frame frame; 100 | int testcase; 101 | int have_rx; 102 | int rx; 103 | int rxbits, rxbitval; 104 | int ret; 105 | int recv_own_msgs = 1; 106 | 107 | /* check command line options */ 108 | if (argc != 2) { 109 | fprintf(stderr, "Usage: %s \n", argv[0]); 110 | return 1; 111 | } 112 | 113 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 114 | perror("socket"); 115 | return 1; 116 | } 117 | 118 | addr.can_family = AF_CAN; 119 | addr.can_ifindex = if_nametoindex(argv[1]); 120 | 121 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, 122 | &recv_own_msgs, sizeof(recv_own_msgs)); 123 | 124 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 125 | perror("bind"); 126 | return 1; 127 | } 128 | 129 | printf("---\n"); 130 | 131 | for (testcase = 0; testcase < TC; testcase++) { 132 | 133 | rfilter.can_id = calc_id(testcase); 134 | rfilter.can_mask = calc_mask(testcase); 135 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, 136 | &rfilter, sizeof(rfilter)); 137 | 138 | printf("testcase %2d filters : can_id = 0x%08X can_mask = 0x%08X\n", 139 | testcase, rfilter.can_id, rfilter.can_mask); 140 | 141 | printf("testcase %2d sending patterns ... ", testcase); 142 | 143 | frame.can_dlc = 1; 144 | frame.data[0] = testcase; 145 | 146 | frame.can_id = ID; 147 | if (write(s, &frame, sizeof(frame)) < 0) { 148 | perror("write"); 149 | exit(1); 150 | } 151 | frame.can_id = (ID | CAN_RTR_FLAG); 152 | if (write(s, &frame, sizeof(frame)) < 0) { 153 | perror("write"); 154 | exit(1); 155 | } 156 | frame.can_id = (ID | CAN_EFF_FLAG); 157 | if (write(s, &frame, sizeof(frame)) < 0) { 158 | perror("write"); 159 | exit(1); 160 | } 161 | frame.can_id = (ID | CAN_EFF_FLAG | CAN_RTR_FLAG); 162 | if (write(s, &frame, sizeof(frame)) < 0) { 163 | perror("write"); 164 | exit(1); 165 | } 166 | 167 | printf("ok\n"); 168 | 169 | have_rx = 1; 170 | rx = 0; 171 | rxbits = 0; 172 | 173 | while (have_rx) { 174 | 175 | have_rx = 0; 176 | FD_ZERO(&rdfs); 177 | FD_SET(s, &rdfs); 178 | tv.tv_sec = 0; 179 | tv.tv_usec = 50000; /* 50ms timeout */ 180 | 181 | ret = select(s+1, &rdfs, NULL, NULL, &tv); 182 | if (ret < 0) { 183 | perror("select"); 184 | exit(1); 185 | } 186 | 187 | if (FD_ISSET(s, &rdfs)) { 188 | have_rx = 1; 189 | ret = read(s, &frame, sizeof(struct can_frame)); 190 | if (ret < 0) { 191 | perror("read"); 192 | exit(1); 193 | } 194 | if ((frame.can_id & CAN_SFF_MASK) != ID) { 195 | fprintf(stderr, "received wrong can_id!\n"); 196 | exit(1); 197 | } 198 | if (frame.data[0] != testcase) { 199 | fprintf(stderr, "received wrong testcase!\n"); 200 | exit(1); 201 | } 202 | 203 | /* test & calc rxbits */ 204 | rxbitval = 1 << ((frame.can_id & (CAN_EFF_FLAG|CAN_RTR_FLAG|CAN_ERR_FLAG)) >> 28); 205 | 206 | /* only receive a rxbitval once */ 207 | if ((rxbits & rxbitval) == rxbitval) { 208 | fprintf(stderr, "received rxbitval %d twice!\n", rxbitval); 209 | exit(1); 210 | } 211 | rxbits |= rxbitval; 212 | rx++; 213 | 214 | printf("testcase %2d rx : can_id = 0x%08X rx = %d rxbits = %d\n", 215 | testcase, frame.can_id, rx, rxbits); 216 | } 217 | } 218 | /* rx timed out -> check the received results */ 219 | if (rx_res[testcase] != rx) { 220 | fprintf(stderr, "wrong rx value in testcase %d : %d (expected %d)\n", 221 | testcase, rx, rx_res[testcase]); 222 | exit(1); 223 | } 224 | if (rxbits_res[testcase] != rxbits) { 225 | fprintf(stderr, "wrong rxbits value in testcase %d : %d (expected %d)\n", 226 | testcase, rxbits, rxbits_res[testcase]); 227 | exit(1); 228 | } 229 | printf("testcase %2d ok\n---\n", testcase); 230 | } 231 | 232 | close(s); 233 | 234 | return 0; 235 | } 236 | -------------------------------------------------------------------------------- /netlayer/tst-packet.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-packet.c - send and receive CAN frames via PF_PACKET sockets 4 | * 5 | * Remark: The sending of CAN frames via PF_PACKET does not work for 6 | * virtual CAN devices (vcan) as the packet type is not set to 7 | * PACKET_LOOPBACK by the packet socket, so you'll never get something 8 | * back (btw the outgoing vcan packet counters are updated correctly). 9 | * 10 | * Copyright (c) 2002-2009 Volkswagen Group Electronic Research 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions 15 | * are met: 16 | * 1. Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * 2. Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * 3. Neither the name of Volkswagen nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * Alternatively, provided that this notice is retained in full, this 26 | * software may be distributed under the terms of the GNU General 27 | * Public License ("GPL") version 2, in which case the provisions of the 28 | * GPL apply INSTEAD OF those given above. 29 | * 30 | * The provided data structures and external interfaces from this code 31 | * are not restricted to be used by modules with a GPL compatible license. 32 | * 33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 36 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 37 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 38 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 39 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 40 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 41 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 42 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 44 | * DAMAGE. 45 | * 46 | * Send feedback to 47 | * 48 | */ 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include /* for htons() */ 60 | 61 | #include 62 | #include /* for ETH_P_CAN */ 63 | #include /* for struct can_frame */ 64 | 65 | int main(int argc, char **argv) 66 | { 67 | int s; 68 | struct can_frame frame; 69 | int nbytes, i; 70 | static struct sockaddr_ll sll; 71 | char *ifname = "vcan2"; 72 | int ifindex; 73 | int opt; 74 | int send_one_frame = 0; 75 | 76 | while ((opt = getopt(argc, argv, "i:s")) != -1) { 77 | switch (opt) { 78 | 79 | case 'i': 80 | ifname = optarg; 81 | break; 82 | 83 | case 's': 84 | send_one_frame = 1; 85 | break; 86 | 87 | default: 88 | fprintf(stderr, "Unknown option %c\n", opt); 89 | break; 90 | } 91 | } 92 | 93 | s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_CAN)); 94 | if (s < 0) { 95 | perror("socket"); 96 | return 1; 97 | } 98 | 99 | if (strcmp(ifname, "any") == 0) 100 | ifindex = 0; 101 | else 102 | ifindex = if_nametoindex(ifname); 103 | 104 | sll.sll_family = AF_PACKET; 105 | sll.sll_ifindex = ifindex; 106 | sll.sll_protocol = htons(ETH_P_CAN); 107 | 108 | if (bind(s, (struct sockaddr *)&sll, sizeof(sll)) < 0) { 109 | perror("bind"); 110 | return 1; 111 | } 112 | 113 | if(send_one_frame) { 114 | 115 | frame.can_id = 0x123; 116 | frame.can_dlc = 2; 117 | frame.data[0] = 0x11; 118 | frame.data[1] = 0x22; 119 | 120 | nbytes = write(s, &frame, sizeof(struct can_frame)); 121 | if (nbytes < 0) { 122 | perror("write"); 123 | return 1; 124 | } 125 | if (nbytes != sizeof(struct can_frame)) { 126 | perror("write_len"); 127 | return 1; 128 | } 129 | } 130 | 131 | while (1) { 132 | 133 | if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { 134 | perror("read"); 135 | return 1; 136 | } else if (nbytes < sizeof(struct can_frame)) { 137 | fprintf(stderr, "read: incomplete CAN frame\n"); 138 | return 1; 139 | } else { 140 | if (frame.can_id & CAN_EFF_FLAG) 141 | printf("%8X ", frame.can_id & CAN_EFF_MASK); 142 | else 143 | printf("%3X ", frame.can_id & CAN_SFF_MASK); 144 | 145 | printf("[%d] ", frame.can_dlc); 146 | 147 | for (i = 0; i < frame.can_dlc; i++) { 148 | printf("%02X ", frame.data[i]); 149 | } 150 | if (frame.can_id & CAN_RTR_FLAG) 151 | printf("remote request"); 152 | printf("\n"); 153 | fflush(stdout); 154 | } 155 | } 156 | 157 | close(s); 158 | 159 | return 0; 160 | } 161 | -------------------------------------------------------------------------------- /netlayer/tst-proc.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-proc.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | #define MAX_RAW 800 60 | 61 | int main(int argc, char **argv) 62 | { 63 | int s[MAX_RAW]; 64 | struct sockaddr_can addr; 65 | int i,numsock; 66 | 67 | if (argc != 2) { 68 | fprintf(stderr, "Error: Wrong number of arguments. Try %s .\n", argv[0]); 69 | exit(1); 70 | } 71 | 72 | numsock = atoi(argv[1]); 73 | 74 | if (numsock >= MAX_RAW) { 75 | fprintf(stderr, "Error: more than %d sockets to open (see #define MAX_RAW).\n", MAX_RAW); 76 | exit(1); 77 | } 78 | 79 | printf("\ncreating %d raw sockets ... ", numsock); 80 | 81 | if (numsock) { 82 | for (i=0; i < numsock; i++) { 83 | if ((s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 84 | perror("socket"); 85 | return 1; 86 | } 87 | 88 | addr.can_family = PF_CAN; 89 | addr.can_ifindex = if_nametoindex("vcan2"); 90 | 91 | if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) { 92 | perror("connect"); 93 | return 1; 94 | } 95 | } 96 | } 97 | 98 | printf("done.\n"); 99 | 100 | printf("Waiting for keyboard input ..."); 101 | 102 | getchar(); 103 | 104 | printf("closing %d raw sockets ... ", numsock); 105 | 106 | if (numsock) 107 | for (i=0; i < numsock; i++) 108 | close(s[i]); 109 | 110 | printf("done.\n\n"); 111 | 112 | return 0; 113 | 114 | } 115 | -------------------------------------------------------------------------------- /netlayer/tst-rcv-own-msgs.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-rcv-own-msgs.c 4 | * 5 | * Copyright (c) 2010 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | 60 | #define max(a,b) (a > b ? a : b) 61 | 62 | struct rxs { 63 | int s; 64 | int t; 65 | }; 66 | 67 | struct rxs test_sockets(int s, int t, canid_t can_id) 68 | { 69 | fd_set rdfs; 70 | struct timeval tv; 71 | int m = max(s,t)+1; 72 | int have_rx = 1; 73 | struct can_frame frame; 74 | struct rxs rx; 75 | int ret; 76 | 77 | frame.can_id = can_id; 78 | frame.can_dlc = 0; 79 | if (write(s, &frame, sizeof(frame)) < 0) { 80 | perror("write"); 81 | exit(1); 82 | } 83 | 84 | rx.s = rx.t = 0; 85 | 86 | while (have_rx) { 87 | 88 | FD_ZERO(&rdfs); 89 | FD_SET(s, &rdfs); 90 | FD_SET(t, &rdfs); 91 | tv.tv_sec = 0; 92 | tv.tv_usec = 50000; /* 50ms timeout */ 93 | have_rx = 0; 94 | 95 | ret = select(m, &rdfs, NULL, NULL, &tv); 96 | if (ret < 0) { 97 | perror("select"); 98 | exit(1); 99 | } 100 | 101 | if (FD_ISSET(s, &rdfs)) { 102 | 103 | have_rx = 1; 104 | ret = read(s, &frame, sizeof(struct can_frame)); 105 | if (ret < 0) { 106 | perror("read"); 107 | exit(1); 108 | } 109 | if (frame.can_id != can_id) { 110 | fprintf(stderr, "received wrong can_id!\n"); 111 | exit(1); 112 | } 113 | rx.s++; 114 | } 115 | 116 | if (FD_ISSET(t, &rdfs)) { 117 | 118 | have_rx = 1; 119 | ret = read(t, &frame, sizeof(struct can_frame)); 120 | if (ret < 0) { 121 | perror("read"); 122 | exit(1); 123 | } 124 | if (frame.can_id != can_id) { 125 | fprintf(stderr, "received wrong can_id!\n"); 126 | exit(1); 127 | } 128 | rx.t++; 129 | } 130 | } 131 | 132 | /* timeout */ 133 | 134 | return rx; 135 | } 136 | 137 | void setopts(int s, int loopback, int recv_own_msgs) 138 | { 139 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, 140 | &loopback, sizeof(loopback)); 141 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, 142 | &recv_own_msgs, sizeof(recv_own_msgs)); 143 | 144 | printf("check loopback %d recv_own_msgs %d ... ", 145 | loopback, recv_own_msgs); 146 | } 147 | 148 | 149 | int main(int argc, char **argv) 150 | { 151 | int s, t; 152 | struct sockaddr_can addr; 153 | struct rxs rx; 154 | 155 | /* check command line options */ 156 | if (argc != 2) { 157 | fprintf(stderr, "Usage: %s \n", argv[0]); 158 | return 1; 159 | } 160 | 161 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 162 | perror("socket"); 163 | return 1; 164 | } 165 | if ((t = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 166 | perror("socket"); 167 | return 1; 168 | } 169 | 170 | addr.can_ifindex = if_nametoindex(argv[1]); 171 | addr.can_family = AF_CAN; 172 | 173 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 174 | perror("bind"); 175 | return 1; 176 | } 177 | if (bind(t, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 178 | perror("bind"); 179 | return 1; 180 | } 181 | 182 | printf("Starting PF_CAN frame flow test.\n"); 183 | printf("checking socket default settings ... "); 184 | rx = test_sockets(s, t, 0x340); 185 | if (rx.s == 0 && rx.t == 1) 186 | printf("ok.\n"); 187 | else { 188 | printf("failure!\n"); 189 | return 1; 190 | } 191 | 192 | /* check loopback 0 recv_own_msgs 0 */ 193 | setopts(s, 0, 0); 194 | rx = test_sockets(s, t, 0x341); 195 | if (rx.s == 0 && rx.t == 0) 196 | printf("ok.\n"); 197 | else { 198 | printf("failure!\n"); 199 | return 1; 200 | } 201 | 202 | /* check loopback 0 recv_own_msgs 1 */ 203 | setopts(s, 0, 1); 204 | rx = test_sockets(s, t, 0x342); 205 | if (rx.s == 0 && rx.t == 0) 206 | printf("ok.\n"); 207 | else { 208 | printf("failure!\n"); 209 | return 1; 210 | } 211 | 212 | /* check loopback 1 recv_own_msgs 0 */ 213 | setopts(s, 1, 0); 214 | rx = test_sockets(s, t, 0x343); 215 | if (rx.s == 0 && rx.t == 1) 216 | printf("ok.\n"); 217 | else { 218 | printf("failure!\n"); 219 | return 1; 220 | } 221 | 222 | /* check loopback 1 recv_own_msgs 1 */ 223 | setopts(s, 1, 1); 224 | rx = test_sockets(s, t, 0x344); 225 | if (rx.s == 1 && rx.t == 1) 226 | printf("ok.\n"); 227 | else { 228 | printf("failure!\n"); 229 | return 1; 230 | } 231 | 232 | printf("PF_CAN frame flow test was successful.\n"); 233 | 234 | close(s); 235 | close(t); 236 | 237 | return 0; 238 | } 239 | -------------------------------------------------------------------------------- /raw/canecho.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * canecho.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | #include 59 | 60 | extern int optind, opterr, optopt; 61 | 62 | static int s = -1; 63 | static int running = 1; 64 | 65 | void print_usage(char *prg) 66 | { 67 | fprintf(stderr, "Usage: %s [can-interface]\n", prg); 68 | } 69 | 70 | void sigterm(int signo) 71 | { 72 | printf("got signal %d\n", signo); 73 | running = 0; 74 | } 75 | 76 | int main(int argc, char **argv) 77 | { 78 | int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW; 79 | int opt; 80 | struct sockaddr_can addr; 81 | struct can_frame frame; 82 | int nbytes, i; 83 | int verbose = 0; 84 | 85 | signal(SIGTERM, sigterm); 86 | signal(SIGHUP, sigterm); 87 | 88 | while ((opt = getopt(argc, argv, "f:t:p:v")) != -1) { 89 | switch (opt) { 90 | case 'f': 91 | family = atoi(optarg); 92 | break; 93 | 94 | case 't': 95 | type = atoi(optarg); 96 | break; 97 | 98 | case 'p': 99 | proto = atoi(optarg); 100 | break; 101 | 102 | case 'v': 103 | verbose = 1; 104 | break; 105 | 106 | case '?': 107 | break; 108 | 109 | default: 110 | fprintf(stderr, "Unknown option %c\n", opt); 111 | break; 112 | } 113 | } 114 | 115 | if (optind == argc) { 116 | print_usage(basename(argv[0])); 117 | exit(0); 118 | } 119 | 120 | printf("interface = %s, family = %d, type = %d, proto = %d\n", 121 | argv[optind], family, type, proto); 122 | if ((s = socket(family, type, proto)) < 0) { 123 | perror("socket"); 124 | return 1; 125 | } 126 | 127 | addr.can_family = family; 128 | addr.can_ifindex = if_nametoindex(argv[optind]); 129 | 130 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 131 | perror("bind"); 132 | return 1; 133 | } 134 | 135 | while (running) { 136 | if ((nbytes = read(s, &frame, sizeof(frame))) < 0) { 137 | perror("read"); 138 | return 1; 139 | } 140 | if (verbose) { 141 | printf("%03X: ", frame.can_id & CAN_EFF_MASK); 142 | if (frame.can_id & CAN_RTR_FLAG) { 143 | printf("remote request"); 144 | } else { 145 | printf("[%d]", frame.can_dlc); 146 | for (i = 0; i < frame.can_dlc; i++) { 147 | printf(" %02X", frame.data[i]); 148 | } 149 | } 150 | printf("\n"); 151 | } 152 | frame.can_id++; 153 | if (write(s, &frame, sizeof(frame)) < 0) { 154 | perror("write"); 155 | exit(1); 156 | } 157 | } 158 | 159 | return 0; 160 | } 161 | -------------------------------------------------------------------------------- /raw/canpump.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * canpump.c - reduced CAN data logger using recvmmsg() syscall 4 | * 5 | * Copyright (c) 2014 Oliver Hartkopp 6 | * 7 | * contains portions of candump.c and the recvmmsg(8) man page 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the version 2 of the GNU General Public License 11 | * as published by the Free Software Foundation 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * Send feedback to 19 | * 20 | */ 21 | 22 | #define _GNU_SOURCE 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #include "lib.h" 38 | 39 | #define ANYDEV "any" /* name of interface to receive from any CAN interface */ 40 | #define MAXIFNAMES 30 /* size of receive name index to omit ioctls */ 41 | 42 | /* we only support one socket */ 43 | static __u32 dropcnt; 44 | static __u32 last_dropcnt; 45 | 46 | static char devname[MAXIFNAMES][IFNAMSIZ+1]; 47 | static int dindex[MAXIFNAMES]; 48 | static int max_devname_len; /* to prevent frazzled device name output */ 49 | 50 | int idx2dindex(int ifidx, int socket) { 51 | 52 | int i; 53 | struct ifreq ifr; 54 | 55 | for (i=0; i < MAXIFNAMES; i++) { 56 | if (dindex[i] == ifidx) 57 | return i; 58 | } 59 | 60 | /* create new interface index cache entry */ 61 | 62 | /* remove index cache zombies first */ 63 | for (i=0; i < MAXIFNAMES; i++) { 64 | if (dindex[i]) { 65 | ifr.ifr_ifindex = dindex[i]; 66 | if (ioctl(socket, SIOCGIFNAME, &ifr) < 0) 67 | dindex[i] = 0; 68 | } 69 | } 70 | 71 | for (i=0; i < MAXIFNAMES; i++) 72 | if (!dindex[i]) /* free entry */ 73 | break; 74 | 75 | if (i == MAXIFNAMES) { 76 | fprintf(stderr, "Interface index cache only supports %d interfaces.\n", 77 | MAXIFNAMES); 78 | exit(1); 79 | } 80 | 81 | dindex[i] = ifidx; 82 | 83 | ifr.ifr_ifindex = ifidx; 84 | if (ioctl(socket, SIOCGIFNAME, &ifr) < 0) 85 | perror("SIOCGIFNAME"); 86 | 87 | if (max_devname_len < strlen(ifr.ifr_name)) 88 | max_devname_len = strlen(ifr.ifr_name); 89 | 90 | strcpy(devname[i], ifr.ifr_name); 91 | 92 | #ifdef DEBUG 93 | printf("new index %d (%s)\n", i, devname[i]); 94 | #endif 95 | 96 | return i; 97 | } 98 | 99 | #define VLEN 20 100 | 101 | int main(int argc, char **argv) 102 | { 103 | int s; /* can raw socket */ 104 | int enable_sockopt = 1; 105 | struct sockaddr_can addr; 106 | struct sockaddr_can addrs[VLEN]; 107 | 108 | char ctrlmsgs[VLEN][CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))]; 109 | struct cmsghdr *cmsg; 110 | 111 | struct canfd_frame frames[VLEN]; 112 | struct iovec iovecs[VLEN]; 113 | struct mmsghdr mmsghdrs[VLEN]; 114 | 115 | char buf[CL_CFSZ]; /* max length */ 116 | int nframes, maxdlen, idx, i; 117 | struct timeval tv = { 0, 0 }; 118 | 119 | /* check command line options */ 120 | if (argc != 2) { 121 | fprintf(stderr, "Usage: %s .\n", argv[0]); 122 | return 1; 123 | } 124 | 125 | /* open socket */ 126 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 127 | perror("socket"); 128 | return 1; 129 | } 130 | 131 | addr.can_family = AF_CAN; 132 | 133 | if (strcmp(ANYDEV, argv[1])) 134 | addr.can_ifindex = if_nametoindex(argv[1]); 135 | else 136 | addr.can_ifindex = 0; /* any can interface */ 137 | 138 | /* try to switch the socket into CAN FD mode */ 139 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_sockopt, sizeof(enable_sockopt)); 140 | 141 | if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &enable_sockopt, sizeof(enable_sockopt)) < 0) { 142 | perror("setsockopt SO_TIMESTAMP"); 143 | return 1; 144 | } 145 | 146 | if (setsockopt(s, SOL_SOCKET, SO_RXQ_OVFL, &enable_sockopt, sizeof(enable_sockopt)) < 0) { 147 | perror("setsockopt SO_RXQ_OVFL not supported by your Linux Kernel"); 148 | /* continue without dropmonitor */ 149 | } 150 | 151 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 152 | perror("bind"); 153 | return 1; 154 | } 155 | 156 | /* these settings are static and can be held out of the hot path */ 157 | memset(frames, 0, sizeof(frames)); 158 | memset(addrs, 0, sizeof(addrs)); 159 | memset(iovecs, 0, sizeof(iovecs)); 160 | memset(mmsghdrs, 0, sizeof(mmsghdrs)); 161 | for (i = 0; i < VLEN; i++) { 162 | iovecs[i].iov_base = &frames[i]; 163 | // iovecs[i].iov_len = BUFSIZE; 164 | mmsghdrs[i].msg_hdr.msg_name= &addrs[i]; 165 | mmsghdrs[i].msg_hdr.msg_iov = &iovecs[i]; 166 | mmsghdrs[i].msg_hdr.msg_iovlen = 1; 167 | mmsghdrs[i].msg_hdr.msg_control = &ctrlmsgs[i]; 168 | } 169 | 170 | // iov.iov_base = &frame; 171 | // msg.msg_name = &addr; 172 | // msg.msg_iov = &iov; 173 | // msg.msg_iovlen = 1; 174 | // msg.msg_control = &ctrlmsg; 175 | 176 | nframes = VLEN; 177 | 178 | while (1) { 179 | 180 | /* these settings may be modified by recvmsg() */ 181 | for (i = 0; i < nframes; i++) { 182 | iovecs[i].iov_len = sizeof(frames[0]); 183 | mmsghdrs[i].msg_hdr.msg_namelen = sizeof(addrs[0]); 184 | mmsghdrs[i].msg_hdr.msg_controllen = sizeof(ctrlmsgs[0]); 185 | mmsghdrs[i].msg_hdr.msg_flags = 0; 186 | } 187 | 188 | // iov.iov_len = sizeof(frame); 189 | // msg.msg_namelen = sizeof(addr); 190 | // msg.msg_controllen = sizeof(ctrlmsg); 191 | // msg.msg_flags = 0; 192 | 193 | nframes = recvmmsg(s, mmsghdrs, VLEN, MSG_WAITFORONE, NULL); 194 | if (nframes < 0) { 195 | perror("recvmmsg()"); 196 | return 1; 197 | } 198 | 199 | for (i = 0; i < nframes; i++) { 200 | 201 | if ((size_t)mmsghdrs[i].msg_len == CAN_MTU) 202 | maxdlen = CAN_MAX_DLEN; 203 | else if ((size_t)mmsghdrs[i].msg_len == CANFD_MTU) 204 | maxdlen = CANFD_MAX_DLEN; 205 | else { 206 | fprintf(stderr, "read: incomplete CAN frame\n"); 207 | return 1; 208 | } 209 | 210 | for (cmsg = CMSG_FIRSTHDR(&mmsghdrs[i].msg_hdr); 211 | cmsg && (cmsg->cmsg_level == SOL_SOCKET); 212 | cmsg = CMSG_NXTHDR(&mmsghdrs[i].msg_hdr,cmsg)) { 213 | if (cmsg->cmsg_type == SO_TIMESTAMP) 214 | tv = *(struct timeval *)CMSG_DATA(cmsg); 215 | else if (cmsg->cmsg_type == SO_RXQ_OVFL) 216 | dropcnt = *(__u32 *)CMSG_DATA(cmsg); 217 | } 218 | 219 | /* check for (unlikely) dropped frames on this specific socket */ 220 | if (dropcnt != last_dropcnt) { 221 | 222 | __u32 drops; 223 | 224 | if (dropcnt > last_dropcnt) 225 | drops = dropcnt - last_dropcnt; 226 | else 227 | drops = UINT32_MAX - last_dropcnt + dropcnt; 228 | 229 | printf("DROPCOUNT: dropped %d CAN frame%s (total drops %d)\n", 230 | drops, (drops > 1)?"s":"", dropcnt); 231 | 232 | last_dropcnt = dropcnt; 233 | } 234 | 235 | idx = idx2dindex(addrs[i].can_ifindex, s); 236 | 237 | /* print CAN frame in log file style to stdout */ 238 | sprint_canframe(buf, &frames[i], 0, maxdlen); 239 | #if 1 240 | printf("(%010ld.%06ld) %*s %s\n", 241 | tv.tv_sec, tv.tv_usec, 242 | max_devname_len, devname[idx], buf); 243 | #else 244 | printf("(%010ld.%06ld) %*s %s ((%dv%d))\n", 245 | tv.tv_sec, tv.tv_usec, 246 | max_devname_len, devname[idx], buf, i+1, nframes); 247 | #endif 248 | fflush(stdout); 249 | } 250 | } 251 | 252 | close(s); 253 | 254 | return 0; 255 | } 256 | -------------------------------------------------------------------------------- /raw/tst-err.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-err.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | int main(int argc, char **argv) 61 | { 62 | int s; 63 | struct sockaddr_can addr; 64 | struct can_filter rfilter; 65 | struct can_frame frame; 66 | can_err_mask_t err_mask = CAN_ERR_MASK; /* all */ 67 | int nbytes; 68 | char *ifname = "vcan2"; 69 | int opt; 70 | struct timeval tv; 71 | 72 | while ((opt = getopt(argc, argv, "i:m:")) != -1) { 73 | switch (opt) { 74 | case 'i': 75 | ifname = optarg; 76 | break; 77 | case 'm': 78 | err_mask = strtoul(optarg, (char **)NULL, 16); 79 | break; 80 | default: 81 | fprintf(stderr, "Unknown option %c\n", opt); 82 | break; 83 | } 84 | } 85 | 86 | 87 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 88 | perror("socket"); 89 | return 1; 90 | } 91 | 92 | rfilter.can_id = CAN_INV_FILTER; /* no normal CAN frames */ 93 | rfilter.can_mask = 0; /* all: INV(all) == nothing */ 94 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); 95 | 96 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask)); 97 | 98 | addr.can_family = AF_CAN; 99 | addr.can_ifindex = if_nametoindex(ifname); 100 | 101 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 102 | perror("bind"); 103 | return 1; 104 | } 105 | 106 | while (1) { 107 | 108 | if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { 109 | perror("read"); 110 | return 1; 111 | } else if (nbytes < sizeof(struct can_frame)) { 112 | fprintf(stderr, "read: incomplete CAN frame\n"); 113 | return 1; 114 | } else { 115 | if (ioctl(s, SIOCGSTAMP, &tv) < 0) 116 | perror("SIOCGSTAMP"); 117 | else 118 | printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec); 119 | 120 | if (frame.can_id & CAN_ERR_BUSOFF) 121 | printf("(bus off) "); 122 | 123 | if (frame.can_id & CAN_ERR_TX_TIMEOUT) 124 | printf("(tx timeout) "); 125 | 126 | if (frame.can_id & CAN_ERR_ACK) 127 | printf("(ack) "); 128 | 129 | if (frame.can_id & CAN_ERR_LOSTARB) { 130 | printf("(lost arb)"); 131 | if (frame.data[0]) 132 | printf("[%d]", frame.data[0]); 133 | printf(" "); 134 | } 135 | 136 | if (frame.can_id & CAN_ERR_CRTL) { 137 | printf("(crtl)"); 138 | if (frame.data[1] & CAN_ERR_CRTL_RX_OVERFLOW) 139 | printf("[RX buffer overflow]"); 140 | if (frame.data[1] & CAN_ERR_CRTL_TX_OVERFLOW) 141 | printf("[TX buffer overflow]"); 142 | if (frame.data[1] & CAN_ERR_CRTL_RX_WARNING) 143 | printf("[RX warning]"); 144 | if (frame.data[1] & CAN_ERR_CRTL_TX_WARNING) 145 | printf("[TX warning]"); 146 | printf(" "); 147 | } 148 | 149 | /* to be continued */ 150 | 151 | printf("\n"); 152 | fflush(stdout); 153 | } 154 | } 155 | 156 | close(s); 157 | 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /raw/tst-raw-filter.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-raw-filter.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | #define MAXFILTERS 32 59 | 60 | int main(int argc, char **argv) 61 | { 62 | int s; 63 | struct sockaddr_can addr; 64 | struct can_filter rfilter[MAXFILTERS]; 65 | struct can_frame frame; 66 | int nbytes, i; 67 | struct ifreq ifr; 68 | char *ifname = "any"; 69 | int opt; 70 | int peek = 0; 71 | int nfilters = 0; 72 | int deflt = 0; 73 | 74 | while ((opt = getopt(argc, argv, "i:p:f:d")) != -1) { 75 | switch (opt) { 76 | case 'i': /* specify different interface than default */ 77 | ifname = optarg; 78 | break; 79 | case 'p': /* MSG_PEEK 'p' times before consuming the frame */ 80 | peek = atoi(optarg); 81 | break; 82 | case 'd': /* use default settings from CAN_RAW socket */ 83 | deflt = 1; 84 | break; 85 | case 'f': /* add this filter can_id:can_mask */ 86 | if (nfilters >= MAXFILTERS) { 87 | fputs("too many filters\n", stderr); 88 | break; 89 | } 90 | rfilter[nfilters].can_id = strtoul(strtok(optarg, ":"), NULL, 16); 91 | rfilter[nfilters].can_mask = strtoul(strtok(NULL, ":"), NULL, 16); 92 | nfilters++; 93 | break; 94 | default: 95 | fprintf(stderr, "Unknown option %c\n", opt); 96 | break; 97 | } 98 | } 99 | 100 | 101 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 102 | perror("socket"); 103 | return 1; 104 | } 105 | 106 | if (deflt) { 107 | printf("%s: using CAN_RAW socket default filter.\n", argv[0]); 108 | } else { 109 | printf("%s: setting %d CAN filter(s).\n", argv[0], nfilters); 110 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, 111 | sizeof(*rfilter) * nfilters); 112 | } 113 | 114 | if (strcmp(ifname, "any") == 0) 115 | addr.can_ifindex = 0; 116 | else 117 | addr.can_ifindex = if_nametoindex(ifname); 118 | 119 | addr.can_family = AF_CAN; 120 | 121 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 122 | perror("bind"); 123 | return 1; 124 | } 125 | 126 | while (1) { 127 | socklen_t len = sizeof(addr); 128 | int flags; 129 | 130 | if (peek && peek--) 131 | flags = MSG_PEEK; 132 | else 133 | flags = 0; 134 | 135 | nbytes = recvfrom(s, &frame, sizeof(struct can_frame), 136 | flags, (struct sockaddr*)&addr, &len); 137 | if (nbytes < 0) { 138 | perror("read"); 139 | return 1; 140 | } else if (nbytes < sizeof(struct can_frame)) { 141 | fprintf(stderr, "read: incomplete CAN frame from iface %d\n", 142 | addr.can_ifindex); 143 | return 1; 144 | } else { 145 | ifr.ifr_ifindex = addr.can_ifindex; 146 | ioctl(s, SIOCGIFNAME, &ifr); 147 | printf(" %-5s ", ifr.ifr_name); 148 | if (frame.can_id & CAN_EFF_FLAG) 149 | printf("%8X ", frame.can_id & CAN_EFF_MASK); 150 | else 151 | printf("%3X ", frame.can_id & CAN_SFF_MASK); 152 | 153 | printf("[%d] ", frame.can_dlc); 154 | 155 | for (i = 0; i < frame.can_dlc; i++) { 156 | printf("%02X ", frame.data[i]); 157 | } 158 | if (frame.can_id & CAN_RTR_FLAG) 159 | printf("remote request"); 160 | if (flags & MSG_PEEK) 161 | printf(" (MSG_PEEK)"); 162 | printf("\n"); 163 | fflush(stdout); 164 | } 165 | } 166 | 167 | close(s); 168 | 169 | return 0; 170 | } 171 | -------------------------------------------------------------------------------- /raw/tst-raw-sendto.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-raw-sendto.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | int main(int argc, char **argv) 59 | { 60 | int s; 61 | struct sockaddr_can addr; 62 | struct can_frame frame; 63 | char *ifname = "vcan2"; 64 | int opt; 65 | 66 | while ((opt = getopt(argc, argv, "i:")) != -1) { 67 | switch (opt) { 68 | case 'i': 69 | ifname = optarg; 70 | break; 71 | default: 72 | fprintf(stderr, "Unknown option %c\n", opt); 73 | break; 74 | } 75 | } 76 | 77 | 78 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 79 | perror("socket"); 80 | return 1; 81 | } 82 | 83 | addr.can_family = AF_CAN; 84 | addr.can_ifindex = 0; /* bind to all interfaces */ 85 | 86 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 87 | perror("bind"); 88 | return 1; 89 | } 90 | 91 | 92 | /* fill CAN frame */ 93 | frame.can_id = 0x123; 94 | frame.can_dlc = 3; 95 | frame.data[0] = 0x11; 96 | frame.data[1] = 0x22; 97 | frame.data[2] = 0x33; 98 | 99 | addr.can_family = AF_CAN; 100 | addr.can_ifindex = if_nametoindex(ifname); /* send via this interface */ 101 | 102 | sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr)); 103 | 104 | close(s); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /raw/tst-raw-sockopt.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-raw-sockopt.c 4 | * 5 | * Copyright (c) 2020 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | #define MAXFILTERS 32 59 | #define FSZ ((socklen_t)sizeof(struct can_filter)) 60 | 61 | #define MAXSZ (MAXFILTERS * FSZ) 62 | 63 | #define RIGHTSZ (16 * FSZ) /* filters set by setsockopt */ 64 | #define LESSSZ (10 * FSZ) /* getsockopt test with smaller buffer */ 65 | #define MORESZ (20 * FSZ) /* getsockopt test with bigger buffer */ 66 | 67 | int main(int argc, char **argv) 68 | { 69 | int s; 70 | struct can_filter rfilter[MAXFILTERS]; 71 | int ret; 72 | socklen_t optlen; 73 | 74 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 75 | perror("socket"); 76 | return 1; 77 | } 78 | 79 | /* no need to bind the socket to an interface for this test */ 80 | 81 | errno = 0; 82 | ret = setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, RIGHTSZ); 83 | printf("setsockopt: write %u byte -> %s\n", RIGHTSZ, strerror(errno)); 84 | 85 | if (ret < 0) { 86 | printf("setsockopt: Unexpected error %s\n", strerror(errno)); 87 | return 1; 88 | } 89 | 90 | /* provide a buffer that has exactly the needed space */ 91 | optlen = RIGHTSZ; 92 | errno = 0; 93 | ret = getsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, &optlen); 94 | printf("getsockopt1: read %u byte into %u byte buffer -> %s\n", RIGHTSZ, RIGHTSZ, strerror(errno)); 95 | 96 | if (optlen != RIGHTSZ) 97 | printf("getsockopt1: optlen %u expected %u\n", optlen, RIGHTSZ); 98 | 99 | if (ret < 0) { 100 | printf("getsockopt1: Unexpected error %s\n", strerror(errno)); 101 | return 1; 102 | } 103 | 104 | /* provide a buffer that has more space than needed */ 105 | optlen = MORESZ; 106 | errno = 0; 107 | ret = getsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, &optlen); 108 | printf("getsockopt2: read %u byte into %u byte buffer -> %s\n", RIGHTSZ, MORESZ, strerror(errno)); 109 | 110 | if (optlen != RIGHTSZ) 111 | printf("getsockopt2: optlen %u expected %u\n", optlen, RIGHTSZ); 112 | 113 | if (ret < 0) { 114 | printf("getsockopt2: Unexpected error %s\n", strerror(errno)); 115 | return 1; 116 | } 117 | 118 | /* provide a buffer that has less space than needed */ 119 | optlen = LESSSZ; 120 | errno = 0; 121 | ret = getsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, &optlen); 122 | printf("getsockopt3: read %u byte into %u byte buffer -> %s\n", RIGHTSZ, LESSSZ, strerror(errno)); 123 | 124 | /* old behaviour: the kernel silently truncated the filterset to LESSSZ */ 125 | if (ret == 0) { 126 | if (optlen != LESSSZ) { 127 | /* the buffer should be filled up completely */ 128 | printf("getsockopt3: optlen %u expected %u\n", optlen, LESSSZ); 129 | return 1; 130 | } 131 | 132 | /* the kernel silently truncated the filterset to LESSSZ */ 133 | printf("getsockopt3: buffer too small for filter but no error\n"); 134 | return 1; 135 | } 136 | 137 | /* does the kernel support ERANGE to provide the needed length? */ 138 | if (errno != ERANGE) { 139 | /* No. Then print the unexpected error (potentially -EFAULT) */ 140 | printf("getsockopt3: Unexpected error %s\n", strerror(errno)); 141 | return 1; 142 | } 143 | 144 | /* -ERANGE -> the needed length was returned in optlen */ 145 | if (optlen != RIGHTSZ) { 146 | /* the kernel should have returned RIGHTSZ in optlen */ 147 | printf("getsockopt3: optlen %u expected %u\n", optlen, RIGHTSZ); 148 | return 1; 149 | } 150 | 151 | /* retry with returned optlen value */ 152 | errno = 0; 153 | ret = getsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, &optlen); 154 | printf("getsockopt4: read %u byte into %u byte buffer -> %s\n", RIGHTSZ, RIGHTSZ, strerror(errno)); 155 | 156 | if (optlen != RIGHTSZ) 157 | printf("getsockopt4: optlen %u expected %u\n", optlen, RIGHTSZ); 158 | 159 | if (ret < 0) { 160 | printf("getsockopt4: Unexpected error %s\n", strerror(errno)); 161 | return 1; 162 | } 163 | 164 | close(s); 165 | 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /raw/tst-raw-sockopt.txt: -------------------------------------------------------------------------------- 1 | The behaviour of getsockopt() for CAN_RAW_FILTER has been improved to provide 2 | the needed buffer length for the CAN_RAW filter set in userspace. 3 | 4 | The former reaction from the kernel when a buffer was provided that was not 5 | able to contain the existing filter set was to silently truncate the filter 6 | set to the given buffer: 7 | 8 | $ raw/tst-raw-sockopt 9 | setsockopt: write 128 byte -> Success 10 | getsockopt1: read 128 byte into 128 byte buffer -> Success 11 | getsockopt2: read 128 byte into 160 byte buffer -> Success 12 | getsockopt3: read 128 byte into 80 byte buffer -> Success 13 | getsockopt3: buffer too small for filter but no error 14 | 15 | The improved reaction from the kernel when a buffer was provided that was not 16 | able to contain the existing filter set is to return '-1', set the errno to 17 | ERANGE and to provide the needed buffer size in the optlen variable. 18 | This allows to retry the getsockopt() syscall with a valid buffer size: 19 | 20 | $ raw/tst-raw-sockopt 21 | setsockopt: write 128 byte -> Success 22 | getsockopt1: read 128 byte into 128 byte buffer -> Success 23 | getsockopt2: read 128 byte into 160 byte buffer -> Success 24 | getsockopt3: read 128 byte into 80 byte buffer -> Numerical result out of range 25 | getsockopt4: read 128 byte into 128 byte buffer -> Success 26 | 27 | The patch below implements the improvement and can be applied to all 28 | Linux kernels since mainline upstream (2.6.25). 29 | 30 | From c473ea36b003ef7ac0468087cef687daac4ddbba Mon Sep 17 00:00:00 2001 31 | From: Oliver Hartkopp 32 | Date: Wed, 16 Dec 2020 18:18:22 +0100 33 | Subject: [PATCH] can: raw: return -ERANGE when filterset does not fit into user space buffer 34 | 35 | Multiple filters (struct can_filter) can be set with the setsockopt() 36 | function, which was originally intended as a write-only operation. 37 | 38 | As getsockopt() also provides a CAN_RAW_FILTER option to read back the 39 | given filters, the caller has to provide an appropriate user space buffer. 40 | In the case this buffer is too small the getsockopt() silently truncates 41 | the filter information and gives no information about the needed space. 42 | This is safe but not convenient for the programmer. 43 | 44 | In net/core/sock.c the SO_PEERGROUPS sockopt had a similar requirement 45 | and solved it by returning -ERANGE in the case that the provided data 46 | does not fit into the given user space buffer and fills the required size 47 | into optlen, so that the caller can retry with a matching buffer length. 48 | 49 | This patch adopts this approach for CAN_RAW_FILTER getsockopt(). 50 | 51 | Reported-by: Phillip Schichtel 52 | Signed-off-by: Oliver Hartkopp 53 | --- 54 | net/can/raw.c | 16 ++++++++++++---- 55 | 1 file changed, 12 insertions(+), 4 deletions(-) 56 | 57 | diff --git a/net/can/raw.c b/net/can/raw.c 58 | index 6ec8aa1d0da4..37b47a39a3ed 100644 59 | --- a/net/can/raw.c 60 | +++ b/net/can/raw.c 61 | @@ -663,14 +663,22 @@ static int raw_getsockopt(struct socket *sock, int level, int optname, 62 | case CAN_RAW_FILTER: 63 | lock_sock(sk); 64 | if (ro->count > 0) { 65 | int fsize = ro->count * sizeof(struct can_filter); 66 | 67 | - if (len > fsize) 68 | - len = fsize; 69 | - if (copy_to_user(optval, ro->filter, len)) 70 | - err = -EFAULT; 71 | + /* user space buffer to small for filter list? */ 72 | + if (len < fsize) { 73 | + /* return -ERANGE and needed space in optlen */ 74 | + err = -ERANGE; 75 | + if (put_user(fsize, optlen)) 76 | + err = -EFAULT; 77 | + } else { 78 | + if (len > fsize) 79 | + len = fsize; 80 | + if (copy_to_user(optval, ro->filter, len)) 81 | + err = -EFAULT; 82 | + } 83 | } else { 84 | len = 0; 85 | } 86 | release_sock(sk); 87 | 88 | -- 89 | 2.29.2 90 | 91 | -------------------------------------------------------------------------------- /raw/tst-raw.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 | /* 3 | * tst-raw.c 4 | * 5 | * Copyright (c) 2002-2007 Volkswagen Group Electronic Research 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of Volkswagen nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * Alternatively, provided that this notice is retained in full, this 21 | * software may be distributed under the terms of the GNU General 22 | * Public License ("GPL") version 2, in which case the provisions of the 23 | * GPL apply INSTEAD OF those given above. 24 | * 25 | * The provided data structures and external interfaces from this code 26 | * are not restricted to be used by modules with a GPL compatible license. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 39 | * DAMAGE. 40 | * 41 | * Send feedback to 42 | * 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | #include 57 | #include 58 | 59 | int main(int argc, char **argv) 60 | { 61 | int s; 62 | struct sockaddr_can addr; 63 | struct can_filter rfilter[4]; 64 | struct can_frame frame; 65 | int nbytes, i; 66 | char *ifname = "vcan2"; 67 | int opt; 68 | struct timeval tv; 69 | 70 | /* sockopt test */ 71 | int loopback = 0; 72 | int set_loopback = 0; 73 | int recv_own_msgs = 0; 74 | int set_recv_own_msgs = 0; 75 | int send_one_frame = 0; 76 | int ignore_errors = 0; 77 | 78 | while ((opt = getopt(argc, argv, "i:l:r:se")) != -1) { 79 | switch (opt) { 80 | 81 | case 'i': 82 | ifname = optarg; 83 | break; 84 | 85 | case 'l': 86 | loopback = atoi(optarg); 87 | set_loopback = 1; 88 | break; 89 | 90 | case 'r': 91 | recv_own_msgs = atoi(optarg); 92 | set_recv_own_msgs = 1; 93 | break; 94 | 95 | case 's': 96 | send_one_frame = 1; 97 | break; 98 | 99 | case 'e': 100 | ignore_errors = 1; 101 | break; 102 | 103 | default: 104 | fprintf(stderr, "Unknown option %c\n", opt); 105 | break; 106 | } 107 | } 108 | 109 | 110 | if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { 111 | perror("socket"); 112 | return 1; 113 | } 114 | 115 | rfilter[0].can_id = 0x123; 116 | rfilter[0].can_mask = CAN_SFF_MASK; 117 | rfilter[1].can_id = 0x200; 118 | rfilter[1].can_mask = 0x700; 119 | rfilter[2].can_id = 0x80123456; 120 | rfilter[2].can_mask = 0x1FFFF000; 121 | rfilter[3].can_id = 0x80333333; 122 | rfilter[3].can_mask = CAN_EFF_MASK; 123 | 124 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); 125 | 126 | if(set_loopback) 127 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback)); 128 | 129 | if(set_recv_own_msgs) 130 | setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs, sizeof(recv_own_msgs)); 131 | 132 | addr.can_family = AF_CAN; 133 | addr.can_ifindex = if_nametoindex(ifname); 134 | 135 | if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 136 | perror("bind"); 137 | return 1; 138 | } 139 | 140 | if(send_one_frame) { 141 | 142 | frame.can_id = 0x123; 143 | frame.can_dlc = 2; 144 | frame.data[0] = 0x11; 145 | frame.data[1] = 0x22; 146 | 147 | nbytes = write(s, &frame, sizeof(struct can_frame)); 148 | } 149 | 150 | while (1) { 151 | 152 | if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) { 153 | perror("read"); 154 | if (!ignore_errors) 155 | return 1; 156 | } else if (nbytes < sizeof(struct can_frame)) { 157 | fprintf(stderr, "read: incomplete CAN frame\n"); 158 | return 1; 159 | } else { 160 | if (ioctl(s, SIOCGSTAMP, &tv) < 0) 161 | perror("SIOCGSTAMP"); 162 | else 163 | printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec); 164 | 165 | if (frame.can_id & CAN_EFF_FLAG) 166 | printf("%8X ", frame.can_id & CAN_EFF_MASK); 167 | else 168 | printf("%3X ", frame.can_id & CAN_SFF_MASK); 169 | 170 | printf("[%d] ", frame.can_dlc); 171 | 172 | for (i = 0; i < frame.can_dlc; i++) { 173 | printf("%02X ", frame.data[i]); 174 | } 175 | if (frame.can_id & CAN_RTR_FLAG) 176 | printf("remote request"); 177 | printf("\n"); 178 | fflush(stdout); 179 | } 180 | } 181 | 182 | close(s); 183 | 184 | return 0; 185 | } 186 | --------------------------------------------------------------------------------