1 /**************************************************************/
2 /* CAN system calls example */
3 /* Author: Michal Sojka, Czech Technical University in Prague */
4 /* License: Public domain */
5 /**************************************************************/
15 #include <sys/socket.h>
16 #include <linux/if_packet.h>
17 #include <net/ethernet.h> /* the L2 protocols */
18 #include <sys/ioctl.h>
19 #include <arpa/inet.h>
23 #define FRAME_SIZE 128
24 #define BLOCK_SIZE 4096
26 #define FRAME_NR (BLOCK_NR*(BLOCK_SIZE/FRAME_SIZE))
32 int init_mmap_socket(const char *dev)
35 struct sockaddr_ll addr;
38 sock = CHECK(socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)));
41 CHECK(setsockopt(sock, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)));
42 socklen_t len = sizeof(hdrlen);
43 CHECK(getsockopt(sock, SOL_PACKET, PACKET_HDRLEN, &hdrlen, &len));
45 strncpy (ifr.ifr_name, dev, sizeof(ifr.ifr_name));
46 CHECK(ioctl(sock, SIOCGIFINDEX, &ifr));
48 addr.sll_family = AF_PACKET;
49 addr.sll_protocol = htons(ETH_P_ALL);
50 addr.sll_ifindex = ifr.ifr_ifindex;
52 CHECK(bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll)));
54 struct tpacket_req req = {
55 .tp_block_size = BLOCK_SIZE,
56 .tp_frame_size = FRAME_SIZE,
57 .tp_block_nr = BLOCK_NR,
58 .tp_frame_nr = FRAME_NR,
60 CHECK(setsockopt(sock, SOL_PACKET, PACKET_RX_RING, (char *)&req, sizeof(req)));
62 rx_ring_buffer = (char*)CHECKPTR(mmap(0, BLOCK_SIZE*BLOCK_NR, PROT_READ|PROT_WRITE, MAP_SHARED, sock, 0));
68 void can_rx_mmap(int sock)
70 volatile struct tpacket2_hdr *hdr = rx_ring_buffer + current*FRAME_SIZE;
72 while (hdr->tp_status == TP_STATUS_KERNEL) {
73 struct pollfd pfd = {.fd = sock, .revents = 0,
74 .events = POLLIN|POLLRDNORM|POLLERR };
75 /* Wait for a message to arrive. If the task wake-up
76 * overhead is too high, poll() can be commented out
77 * and the application will busy-wait here. */
78 CHECK(poll(&pfd, 1, -1));
81 struct can_frame *cf = (void*)hdr + hdr->tp_mac;
82 printf("Frame #%d received\n", current);
84 hdr->tp_status = 0; /* Mark the frame as processed */
86 current = (current + 1) % FRAME_NR;
89 int main(int argc, char *argv[])
94 dev = candump_parse_args(argc, argv);
96 sock = init_mmap_socket(dev);