From: Radek Matejka Date: Wed, 8 Aug 2012 16:21:25 +0000 (+0200) Subject: userspace canethgw cmdline options improvement X-Git-Url: https://rtime.felk.cvut.cz/gitweb/can-eth-gw.git/commitdiff_plain/b2f135001bba8699fe410d53924527bdbc267b27 userspace canethgw cmdline options improvement Caneth command line options are modified to be compatible with other parts of the canethgw suite. --- diff --git a/user/Makefile b/user/Makefile index aea5dbc..e1a4260 100644 --- a/user/Makefile +++ b/user/Makefile @@ -1,4 +1,5 @@ PROGRAM=canethgw all: - gcc -Wall -o ${PROGRAM} canethgw.c + gcc -Wall -o${PROGRAM} -I../utils/common/include/ canethgw.c ../utils/common/cegwerr.c ../utils/common/readif.c + diff --git a/user/canethgw.c b/user/canethgw.c index 5331a55..3197edb 100644 --- a/user/canethgw.c +++ b/user/canethgw.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -13,14 +14,27 @@ #include #include #include +#include "readif.h" +#include "cegwerr.h" + +/** + * ToDo: + * [ ] print usage + */ +//#define GW_DEBUG +#ifdef GW_DEBUG +#define printdbg(x) printf(x) +#else +#define printdbg(x) +#endif #define GW_POLL_ETH 0 #define GW_POLL_CAN 1 -/**/ -#define GW_IF_BIT 1 -#define GW_SRC_PORT_BIT 2 -#define GW_DEST_PORT_BIT 4 -#define GW_FILTER_BIT 8 + +#define GW_FLAG_SRC 1 +#define GW_FLAG_DST 2 +#define GW_FLAG_LISTEN 4 +#define GW_FLAG_FILTER 8 unsigned int opt_flag = 0; int sock_udp; @@ -29,12 +43,12 @@ struct can_filter flt; struct sockaddr_in udp_dest; /** - * + * filter_check * @return true if frame should be dropped */ bool filter_check( struct can_frame* cf ) { - if( !(opt_flag & GW_FILTER_BIT) ) + if( !(opt_flag & GW_FLAG_FILTER) ) return false; return ( (cf->can_id & flt.can_mask) == (flt.can_id & flt.can_mask) ); @@ -43,17 +57,18 @@ bool filter_check( struct can_frame* cf ) void send_to_can() { struct can_frame cf; + read( sock_udp, &cf, sizeof(cf) ); - if( !filter_check( &cf ) ) + if( filter_check( &cf ) ) { - printf( "filter: drop\n" ); + printdbg( "filter: drop\n" ); return; } write( sock_can, &cf, sizeof(cf) ); - printf( "sending to can\n" ); + printdbg( "eth -> can\n" ); } void send_to_eth() @@ -62,15 +77,15 @@ void send_to_eth() read( sock_can, &cf, sizeof(cf) ); - if( !filter_check( &cf ) ) + if( filter_check( &cf ) ) { - printf( "filter: drop\n" ); + printdbg( "filter: drop\n" ); return; } sendto( sock_udp, &cf, sizeof(cf), 0, (struct sockaddr*) &udp_dest, sizeof(udp_dest) ); - printf( "sending to eth\n" ); + printdbg( "can -> eth\n" ); } void signal_exit( int sig ) @@ -86,98 +101,136 @@ int main( int argc, char* argv[] ) { struct sockaddr_in udp_addr; struct sockaddr_can can_addr; - struct ifreq ifr; struct pollfd pfd[2]; int polret; int opt; - int src_port = 0, dest_port = 0; + struct cegw_if ceif[2], iflisten; + struct cegw_if* ifcan,* ifeth; flt.can_id = 0; flt.can_mask = 0; - while( (opt = getopt( argc, argv, "s:d:f:i:" )) != -1 ) + struct option longopt[] = + { + {"listen", 1, NULL, 'l'}, + { 0, 0, 0, 0 } + }; + + while( (opt = getopt_long( argc, argv, "s:d:l:f:i:", longopt, NULL )) != -1 ) { switch( opt ) { case 's': - src_port = atoi( optarg ); - opt_flag |= GW_SRC_PORT_BIT; + if( read_if(optarg, &ceif[0]) != 0 ) + { + perr( "'-s'" ); + return -1; + } + opt_flag |= GW_FLAG_SRC; break; case 'd': - dest_port = atoi( optarg ); - opt_flag |= GW_DEST_PORT_BIT; + if( read_if(optarg, &ceif[1]) != 0 ) + { + perr( "'-d'" ); + return -1; + } + opt_flag |= GW_FLAG_DST; + break; + case 'l': + if( read_if(optarg, &iflisten) != 0 ) + { + perr( "'-l'" ); + return -1; + } + if( iflisten.type != IF_ETH_UDP ) + { + perr( "'-l' udp interface expected" ); + return -1; + } + opt_flag |= GW_FLAG_LISTEN; break; case 'f': if( sscanf( optarg, "%x:%x", &flt.can_id, &flt.can_mask ) != 2 ) { - fprintf( stderr, "error:\ - bad filter format\n"); - goto gw_error; + perr( "bad filter format"); + return -1; } - opt_flag |= GW_FILTER_BIT; + opt_flag |= GW_FLAG_FILTER; break; - case 'i': - ifr.ifr_ifindex = if_nametoindex( optarg ); - if( ifr.ifr_ifindex == 0 ) - { - fprintf( stderr, "error: if_nametoindex\n" ); - goto gw_error; - } - opt_flag |= GW_IF_BIT; + case '?': + return -1; break; } } - if( !((opt_flag & GW_SRC_PORT_BIT) && (opt_flag & GW_DEST_PORT_BIT) - && (opt_flag & GW_DEST_PORT_BIT)) ) + if( !((opt_flag & GW_FLAG_SRC) && (opt_flag & GW_FLAG_DST) + && (opt_flag & GW_FLAG_LISTEN)) ) + { + perr( "'s', 'd' and 'l' are mandatory" ); + /* ToDo: usage? */ + return -1; + } + + if( !(ceif[0].type == IF_CAN && ceif[1].type == IF_ETH_UDP) && + !(ceif[0].type == IF_ETH_UDP && ceif[1].type == IF_CAN ) ) { - fprintf( stdout, "bad usage, example -i vcan0 -s 10501 -d 10502 -f 007:00000007\n" ); + perr( "'-s' and '-d' should be different interface type" ); return -1; } + if( ceif[0].type == IF_CAN ) + { + ifcan = &ceif[0]; + ifeth = &ceif[1]; + } else + { + ifcan = &ceif[1]; + ifeth = &ceif[0]; + } + signal( SIGINT, signal_exit ); /* prepare udp destination */ udp_dest.sin_family = AF_INET; - udp_dest.sin_addr.s_addr = inet_addr("127.0.0.1"); - udp_dest.sin_port = htons(dest_port); + udp_dest.sin_port = htons(ifeth->eth.port); + udp_dest.sin_addr = ifeth->eth.ip; /* udp socket */ sock_udp = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); if( sock_udp < 0 ) { - fprintf( stderr, "error: socket(), udp\n" ); - goto gw_error; + perr( "udp socket creation failed" ); + return -1; } udp_addr.sin_family = AF_INET; - udp_addr.sin_port = htons(src_port); - udp_addr.sin_addr.s_addr = INADDR_ANY; + udp_addr.sin_port = htons(iflisten.eth.port); + udp_addr.sin_addr = iflisten.eth.ip; if( bind( sock_udp, (struct sockaddr*) &udp_addr, sizeof(udp_addr) ) < 0 ) { - fprintf( stderr, "error: bind(), udp\n" ); + perr( "udp socket binding failed" ); close( sock_udp ); - goto gw_error; + return -1; } /* can socket */ sock_can = socket( PF_CAN, SOCK_RAW, CAN_RAW ); if( sock_can < 0 ) { - fprintf( stderr, "error: socket(), can\n"); + perr( "can socket creation failed"); close( sock_can ); - goto gw_error; + return -1; } can_addr.can_family = AF_CAN; - can_addr.can_ifindex = ifr.ifr_ifindex; + can_addr.can_ifindex = ifcan->can.ifindex; if( bind( sock_can, (struct sockaddr*) &can_addr, sizeof(can_addr) ) < 0 ) { - fprintf( stderr, "error: bind(), can" ); - goto gw_error; + perr( "can socket binding failed" ); + return -1; } /* poll */ @@ -189,14 +242,18 @@ int main( int argc, char* argv[] ) pfd[GW_POLL_CAN].events = POLLIN | POLLPRI; pfd[GW_POLL_CAN].revents = 0; - while(1) + printf( "canethgw is running\n" ); + + while( 1 ) { - printf( "polling\n" ); + printdbg( "polling\n" ); polret = poll( pfd, 2, -1 ); - if( polret <= 0 ) + if( polret < 0 ) { - fprintf( stderr, "error: poll returned 0\n" ); - goto gw_clean; + perr( "poll(..) failed" ); + close( sock_udp ); + close( sock_can ); + return -1; } if( pfd[GW_POLL_ETH].revents != 0 ) @@ -213,10 +270,5 @@ int main( int argc, char* argv[] ) } return 0; -gw_clean: - close( sock_udp ); - close( sock_can ); -gw_error: - return -1; }