X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-eth-gw.git/blobdiff_plain/5e832b957fdc026b489fe085ebbe8630eb36183b..865c5c312215747448f7edf9318d2c6bf0c16d6d:/utils/cegw/cegw.c diff --git a/utils/cegw/cegw.c b/utils/cegw/cegw.c index fc91a9c..7372634 100644 --- a/utils/cegw/cegw.c +++ b/utils/cegw/cegw.c @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include #include "canethgw.h" /** @@ -45,7 +49,7 @@ struct cegw_data unsigned short eth_listen_port; }; -struct cegw_nlmsg +struct cegw_nlmsg { struct nlmsghdr nh; struct rtmsg rt; @@ -62,7 +66,7 @@ struct list_item unsigned int cegw_errno = 0; -enum +enum { CEGW_ERR_UNKNOWN, CEGW_ERR_IF_UNSPEC, @@ -108,7 +112,7 @@ static void perr( char* s ) } /** - * read_addrport - parses @in for eth address. + * read_addrport - parses @in for eth address. * Valid input is e.g. udp@127.0.0.1:10502 or can@vcan0. * * @param[in] in string to search in @@ -266,7 +270,7 @@ inline static int cegw_list( struct cegw_nlmsg* req, struct cegw_data* d ) { req->nh.nlmsg_type = RTM_GETROUTE; req->nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - + return 0; } @@ -323,40 +327,94 @@ int main( int argc, char* argv[] ) struct rtattr* rta; int len; struct list_item li; - int gw_can_sock = 0; - int gw_eth_sock = 0; - struct sockaddr_in gw_eth_addr; - struct sockaddr_can gw_can_addr; - struct in_addr addr; - - memset( &d, 0, sizeof(d) ); - /* create sockets for gateway */ - gw_eth_sock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); - gw_can_sock = socket( PF_CAN, SOCK_RAW, CAN_RAW ); + /**/ + int fd; - if( gw_eth_sock == -1 ) - fprintf( stderr, "error: udp socket for gw creation failed\n" ); - if( gw_can_sock == -1 ) - fprintf( stderr, "error: can socket for gw creation failed\n" ); + fd = open( "/dev/cegw", O_RDONLY ); + if( fd == -1 ) + { + fprintf( stderr, "error: could not open device file\n" ); + return -1; + } - gw_eth_addr.sin_family = AF_INET; - gw_eth_addr.sin_port = htons( 10501 ); - gw_eth_addr.sin_addr.s_addr = INADDR_ANY; + ioctl( fd, CEGW_IOCTL_CAN_SOCK, 8 ); + close( fd ); + return 0; - gw_can_addr.can_family = AF_CAN; - gw_can_addr.can_ifindex = 0; + memset( &d, 0, sizeof(d) ); - if( bind( gw_eth_sock, (struct sockaddr*)&gw_eth_addr, sizeof(gw_eth_addr) ) != 0 ) - fprintf( stderr, "error: eth binding\n" ); - if( bind( gw_can_sock, (struct sockaddr*)&gw_can_addr, sizeof(gw_can_addr) ) ) - fprintf( stderr, "error: can binding\n" ); + struct option long_opt[] = + { + { "add" , 0, NULL, 'A' }, + { "flush" , 0, NULL, 'F' }, + { "list" , 0, NULL, 'L' }, + { "listen", 1, NULL, 'l' }, + { 0, 0, 0, 0 } + }; + + while( 1 ) + { + opt = getopt_long( argc, argv, "AFLl:s:d:", long_opt, NULL ); + if( opt == -1 ) + break; - printf( "sockets created (%i,%i)\n", gw_can_sock, gw_eth_sock ); + switch( opt ) + { + case 'A': + cmd |= CEGW_CMD_ADD; + break; + case 'F': + cmd |= CEGW_CMD_FLUSH; + break; + case 'L': + cmd |= CEGW_CMD_LIST; + break; + case 'l': + cmd |= CEGW_CMD_LISTEN; + if( (optstr = read_iftype( optarg, &tmp )) == NULL ) + { + perr( "'--listen'" ); + return -1; + } + if( tmp != IF_ETH_UDP ) + { + perr( "'--listen' expects udp interface" ); + return -1; + } + if( read_addrport( optstr, &d.eth_listen_addr, &d.eth_listen_port ) ) + { + perr( "'--listen'" ); + return -1; + } + break; + case 's': + if( read_if( optarg, &d.src_if, &d ) != 0 ) + { + perr( "'-s'" ); + return -1; + } + break; + case 'd': + if( read_if( optarg, &d.dst_if, &d ) != 0 ) + { + perr( "'-d'" ); + return -1; + } + break; + case '?': + return -1; + break; + default: + perr( "unknown option" ); + return -1; + break; + } + } /* prepare netlink message */ req.nh.nlmsg_len = NLMSG_LENGTH( sizeof(struct rtmsg) ); - req.nh.nlmsg_type = RTM_NEWROUTE; + //req.nh.nlmsg_type; req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; req.nh.nlmsg_seq = 0; req.nh.nlmsg_pid = 0; /* ? */ @@ -364,27 +422,50 @@ int main( int argc, char* argv[] ) memset( &req.rt, 0, sizeof(req.rt) ); req.rt.rtm_family = AF_CAN; - addattr32( &req.nh, sizeof(req), CEGW_CAN_SOCK, gw_can_sock ); - addattr32( &req.nh, sizeof(req), CEGW_ETH_SOCK, gw_eth_sock ); - addattr32( &req.nh, sizeof(req), CEGW_CAN_IFINDEX, if_nametoindex("vcan0") ); + switch( cmd ) + { + case 0: + perr( "command not specified" ); + return -1; + break; + case CEGW_CMD_ADD: + if( cegw_add( &req, &d ) != 0 ) + { + perr( "'--add'" ); + return -1; + } + break; + case CEGW_CMD_FLUSH: + cegw_flush( &req, &d ); + break; + case CEGW_CMD_LIST: + cegw_list( &req, &d ); + break; + case CEGW_CMD_LISTEN: + cegw_listen( &req, &d ); + break; + default: + perr( "command mismatch" ); + break; + } /* send over netlink socket */ s = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE ); /* chck */ - + memset( &nladdr, 0, sizeof(nladdr) ); nladdr.nl_family = AF_NETLINK; nladdr.nl_pad = 0; nladdr.nl_pid = 0; nladdr.nl_groups = 0; - err = sendto( s, &req, req.nh.nlmsg_len, 0, + err = sendto( s, &req, req.nh.nlmsg_len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr) ); if( err < 0 ) { perror( "netlink sendto" ); return -1; } - + /* recv */ rsize = recv( s, &rxbuf, sizeof(rxbuf), 0 ); if( rsize < 0 ) @@ -394,14 +475,6 @@ int main( int argc, char* argv[] ) } nlh = (struct nlmsghdr*)rxbuf; - /* REMOVE */ - sleep( 2 ); - //printf( "closing sockets\n" ); - //shutdown( gw_eth_sock, SHUT_RDWR ); - shutdown( gw_can_sock, SHUT_RDWR ); - //close( gw_can_sock ); - //close( gw_eth_sock ); - if( nlh->nlmsg_type == NLMSG_ERROR ) { rte = (struct nlmsgerr*)NLMSG_DATA( nlh );