1 /**************************************************************************/
2 /* CAN user space gateway for performance benchmarks */
3 /* Copyright (C) 2013, 2014 Michal Sojka, DCE, FEE, CTU Prague */
5 /**************************************************************************/
8 #include <sys/socket.h>
10 #include <sys/ioctl.h>
19 #define STRINGIFY(val) #val
20 #define TOSTRING(val) STRINGIFY(val)
21 #define CHECK(cmd) ({ int ret = (cmd); if (ret == -1) { perror(#cmd " line " TOSTRING(__LINE__)); exit(1); }; ret; })
24 char *devout = "can1";
25 enum { READ, RECVMMSG } in_method = READ;
26 enum { WRITE } out_method = WRITE;
29 #define VERBOSE(format, ...) do { if (!quiet) fprintf(stderr, format, ##__VA_ARGS__); } while (0)
34 int (*in_fn)(struct in_ctx *ctx, struct can_frame *cf);
40 int (*out_fn)(struct out_ctx *ctx, struct can_frame *cf);
43 int in_read(struct in_ctx *ctx, struct can_frame *cf)
45 int ret = read(ctx->s, cf, sizeof(*cf));
46 if (ret != sizeof(*cf)) {
53 void init_read(struct in_ctx *ctx)
56 struct sockaddr_can addr;
59 s = CHECK(socket(PF_CAN, SOCK_RAW, CAN_RAW));
61 strcpy(ifr.ifr_name, devin);
62 if (-1 == ioctl(s, SIOCGIFINDEX, &ifr)) {
67 addr.can_family = AF_CAN;
68 addr.can_ifindex = ifr.ifr_ifindex;
70 CHECK(bind(s, (struct sockaddr *)&addr, sizeof(addr)));
76 int out_write(struct out_ctx *ctx, struct can_frame *cf)
78 int ret = write(ctx->s, cf, sizeof(*cf));
79 if (ret != sizeof(*cf)) {
86 void init_write(struct out_ctx *ctx)
89 struct sockaddr_can addr;
92 s = CHECK(socket(PF_CAN, SOCK_RAW, CAN_RAW));
94 strcpy(ifr.ifr_name, devout);
95 if (-1 == ioctl(s, SIOCGIFINDEX, &ifr)) {
100 addr.can_family = AF_CAN;
101 addr.can_ifindex = ifr.ifr_ifindex;
103 CHECK(bind(s, (struct sockaddr *)&addr, sizeof(addr)));
106 ctx->out_fn = out_write;
109 void init_in(struct in_ctx *in)
112 case READ: init_read(in); break;
114 fprintf(stderr, "Unknown \"in method\" %d\n", in_method);
119 int in(struct in_ctx *ctx, struct can_frame *cf)
121 return ctx->in_fn(ctx, cf);
124 void init_out(struct out_ctx *out)
126 switch (out_method) {
127 case WRITE: init_write(out); break;
129 fprintf(stderr, "Unknown \"out method\" %d\n", out_method);
134 int out(struct out_ctx *ctx, struct can_frame *cf)
136 return ctx->out_fn(ctx, cf);
148 VERBOSE("UGW started");
152 oc.from_in = ic.for_out;
158 int main(int argc, char *argv[])
162 while ((opt = getopt(argc, argv, "q")) != -1) {
168 fprintf(stderr, "Usage: %s [in_interface out_interface]\n",
175 devin = argv[optind];
177 devout = argv[optind+1];