X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-eth-gw.git/blobdiff_plain/7050a3d312c33d88ff213905c4b15eb6d6bb4e5c..dce17269d3f87a7d632e735b0d72d887e8974ae2:/utils/cegw/cegw.c diff --git a/utils/cegw/cegw.c b/utils/cegw/cegw.c deleted file mode 100644 index 67953fe..0000000 --- a/utils/cegw/cegw.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright: (c) 2012 Czech Technical University in Prague - * - * Authors: - * Radek Matějka - * Michal Sojka - * - * Funded by: Volkswagen Group Research - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -unsigned int cegw_errno = 0; - -static const char help_msg[] = "usage:\n" - " %s [,filter]* : :\n" - " [list of additional udp recipients :]\n" - "example:\n" - " %s can0 192.168.0.1:10501 192.168.0.4:980 192.168.0.7:1160\n\n" - " Executing this command will set the gateway so that it will\n" - " listen for udp messages on 192.168.0.1:10501 and send them\n" - " to can0. Simultaneously, it will send all messages from can0\n" - " to 192.168.0.4:980 and 192.168.0.7:1160 via udp. The message is\n" - " therefore cloned. Notice that there can be more udp recipients.\n" - " The can filter is specified in the same way as in candump utility.\n"; - -struct addrinfo hints = { - .ai_socktype = SOCK_DGRAM -}; - -/** - * readsockaddr - parses @in for eth address. - * Valid input is e.g. 127.0.0.1:10502. If parsing fails - * the cause is stored in cegw_errno. Please note that - * the function modifies content of arg. - * - * @param[in] arg hostname:port string - * @param[out] addr filled sockaddr_in structure - * @return 0 on success, -1 otherwise - */ -int readsockaddr(char *arg, struct sockaddr *addr, int ai_family) -{ - int ret; - char *delim; - struct addrinfo *res; - - delim = strchr(arg, ':'); - - if (delim == NULL) { - fprintf(stderr, "expected ':' (:)"); - exit(1); - } - - *delim = '\0'; - delim++; - - hints.ai_family = ai_family; - - ret = getaddrinfo(arg, delim, &hints, &res); - if (ret != 0) { - fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret)); - exit(1); - } - - memcpy(addr, res->ai_addr, res->ai_addrlen); - - freeaddrinfo(res); - return 0; -} - -/** - * readfilter - reads can filter definition from nptr - */ -int readfilter(char *nptr, struct can_filter **filter, int *out_numfilter, can_err_mask_t *err_mask) -{ - char *ptr; - int numfilter; - struct can_filter *rfilter; - - numfilter = 0; - ptr = nptr; - while (ptr) { - numfilter++; - ptr++; /* hop behind the ',' */ - ptr = strchr(ptr, ','); /* exit condition */ - } - - rfilter = malloc(numfilter * sizeof(*rfilter)); - if (!rfilter) { - fprintf(stderr, "filter malloc failed"); - exit(1); - } - - numfilter = 0; - *err_mask = 0; - - while (nptr) { - - ptr = nptr+1; /* hop behind the ',' */ - nptr = strchr(ptr, ','); /* update exit condition */ - - if (sscanf(ptr, "%x:%x", - &rfilter[numfilter].can_id, - &rfilter[numfilter].can_mask) == 2) { - rfilter[numfilter].can_mask &= ~CAN_ERR_FLAG; - numfilter++; - } else if (sscanf(ptr, "%x~%x", - &rfilter[numfilter].can_id, - &rfilter[numfilter].can_mask) == 2) { - rfilter[numfilter].can_id |= CAN_INV_FILTER; - rfilter[numfilter].can_mask &= ~CAN_ERR_FLAG; - numfilter++; - } else if (sscanf(ptr, "#%x", err_mask) != 1) { - fprintf(stderr, "filter parsing failed"); - exit(1); - } - } - - *filter = rfilter; - *out_numfilter = numfilter; - return 0; -} - -int main(int argc, char *argv[]) -{ - int i; - int fd; - int tmpi; - int dstcnt; - char *nptr; - int numfilter = 0; - int udp_sock, can_sock; - int addrlen; - can_err_mask_t err_mask = 0; - struct sockaddr_can can_addr; - struct sockaddr *dst = NULL; - struct cegw_ioctl *gwctl = NULL; - struct can_filter *filter = NULL; - - /* udp_addr can store both - in and in6 addresses */ - struct sockaddr_in6 udp6_addr; - struct sockaddr *udp_addr = (struct sockaddr *) &udp6_addr; - - - if (argc == 1 || (argc == 2 && strcmp(argv[1], "-h") == 0)) { - printf(help_msg, argv[0], argv[0]); - return 0; - } - - if (argc < 4) { - fprintf(stderr, "not enough arguments\n"); - printf(help_msg, argv[0], argv[0]); - return 1; - } - - dstcnt = argc-3; - - for (i=1; isa_family) { - case AF_INET: - addrlen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - addrlen = sizeof(struct sockaddr_in6); - break; - default: - fprintf(stderr, "unexpected sockaddr family"); - break; - } - gwctl = (struct cegw_ioctl*)malloc(sizeof(*gwctl) + dstcnt*addrlen); - break; - default: /* udp destination */ - dst = (struct sockaddr *)(gwctl->udp_dst + (i-3)*addrlen); - readsockaddr(argv[i], dst, udp_addr->sa_family); - - break; - } - } - - /* prepare udp socket */ - udp_sock = socket(udp_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP); - if (udp_sock == -1) { - perror("udp socket(..)"); - return 1; - } - - if (bind(udp_sock, udp_addr, addrlen) != 0) { - perror("bind(udp)"); - return 1; - } - - /* prepare can socket */ - can_sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); - if (can_sock == -1) { - perror("can socket(..)"); - return 1; - } - - if (bind(can_sock, (struct sockaddr *)&can_addr, sizeof(struct sockaddr_can)) != 0) { - perror("bind(can)"); - return 1; - } - - /* can filter */ - if (nptr) - readfilter(nptr, &filter, &numfilter, &err_mask); - - if (err_mask) - setsockopt(can_sock, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, - &err_mask, sizeof(err_mask)); - - if (numfilter) - setsockopt(can_sock, SOL_CAN_RAW, CAN_RAW_FILTER, - filter, numfilter * sizeof(struct can_filter)); - free(filter); - - /* send it to kernel gateway */ - fd = open("/dev/canethgw", O_RDONLY); - if (fd == -1) { - perror("/dev/canethgw"); - return 1; - } - - gwctl->can_sock = can_sock; - gwctl->udp_sock = udp_sock; - gwctl->udp_dstcnt = dstcnt; - gwctl->udp_addrlen = addrlen; - - if (ioctl(fd, CEGW_IOCTL_START, gwctl) != 0) { - perror("ioctl"); - return 1; - } - printf("gateway successfully set and running\n"); - free(gwctl); - - /* sleep until someone kills me */ - pause(); - - return 0; -}