]> rtime.felk.cvut.cz Git - can-eth-gw.git/commitdiff
userspace canethgw cmdline options improvement
authorRadek Matejka <radek.matejka@gmail.com>
Wed, 8 Aug 2012 16:21:25 +0000 (18:21 +0200)
committerRadek Matejka <radek.matejka@gmail.com>
Wed, 8 Aug 2012 16:21:25 +0000 (18:21 +0200)
Caneth command line options are modified to be compatible with other
parts of the canethgw suite.

user/Makefile
user/canethgw.c

index aea5dbc6f9f7227e49e3daa899806ff3a12caf80..e1a42603efd21ea61058a4a56f6bd041b1210f56 100644 (file)
@@ -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
+
index 5331a55accda111d530ac79558a5a61133c244d6..3197edbec70209265dc1f916c3c0be4c24473062 100644 (file)
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <netinet/in.h>
 #include <signal.h>
+#include <getopt.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <linux/can.h>
 #include <linux/can/raw.h>
 #include <poll.h>
+#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;
 }