]> rtime.felk.cvut.cz Git - can-eth-gw.git/blobdiff - utils/cegw/cegw.c
set udp listening address
[can-eth-gw.git] / utils / cegw / cegw.c
similarity index 69%
rename from utils/cangw/cegw.c
rename to utils/cegw/cegw.c
index 52336277333e7c8233cae20f5c8953c76275f02a..275d6592ff91864c9707ce0acf1787efa68b6c29 100644 (file)
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <libgen.h>
 #include <string.h>
-#include <unistd.h>
+#include <getopt.h>
 #include <errno.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <arpa/inet.h>
-#include <gw.h>
+#include <linux/can.h>
+#include <linux/types.h>
+#include "canethgw.h"
 
 /**
  * ToDo
- * - refactor error messages
- * */
+ * [ ] refactor error messages
+ * [ ] start/stop listening
+ * [ ] remove routing job
+ * [ ] recv netlink reponse
+ * 
+ */
+
+#define CMD_STOP_LISTEN    1
+#define CMD_START_LISTEN   2
+#define CMD_ADD_RULE       4
 
 enum {
        IF_UNDEF,
@@ -23,6 +33,15 @@ enum {
        IF_ETH_UDP
 };
 
+
+/**
+ * parses @in for eth address, valid input is 
+ * e.g. udp@127.0.0.1:10502 or can@vcan0
+ *
+ * @param[out] addr ip address
+ * @param[out] port transport layer port
+ * @return 0 on success
+ */
 int read_addr_port( char* in, struct in_addr* addr, unsigned short* port )
 {
        char* delim = NULL;
@@ -83,7 +102,7 @@ int main( int argc, char* argv[] )
        int src_if = 0, dst_if = 0;
        int can_ifidx = 0;
        int tmp = 0;
-       int have_listen = 0;
+       int cmd = 0;
        struct in_addr eth_addr;
        unsigned short eth_port;
        struct in_addr eth_listen_addr;
@@ -92,6 +111,13 @@ int main( int argc, char* argv[] )
        char opt;
        struct sockaddr_nl nladdr;
        int err = 0;
+
+       struct option long_opt[] =
+       {
+               { "start-listen", 1, NULL, 'l' },
+               { "stop-listen" , 1, NULL, 'k' },
+               { 0, 0, 0, 0 }
+       };
        
        struct {
                struct nlmsghdr nh;
@@ -99,11 +125,16 @@ int main( int argc, char* argv[] )
                char buf[600]; /* enough? */
        } req;
        
-       while( (opt = getopt( argc, argv, "As:d:l:" )) != -1 )
+       while( 1 )
        {
+               opt = getopt_long( argc, argv, "As:d:", long_opt, NULL );
+               if( opt == -1 )
+                       break;
+
                switch( opt )
                {
                        case 's':
+                               cmd |= CMD_ADD_RULE;
                                if( (optstr = read_iftype( optarg, &src_if )) == NULL )
                                {
                                        fprintf( stderr, "error: bad input format\n" );
@@ -126,6 +157,7 @@ int main( int argc, char* argv[] )
                                }
                                break;
                        case 'd':
+                               cmd |= CMD_ADD_RULE;
                                if( (optstr = read_iftype( optarg, &dst_if )) == NULL )
                                {
                                        fprintf( stderr, "error: bad input format\n" );
@@ -147,6 +179,7 @@ int main( int argc, char* argv[] )
                                }
                                break;
                        case 'l':
+                               cmd |= CMD_START_LISTEN;
                                if( (optstr = read_iftype( optarg, &tmp )) == NULL )
                                {
                                        fprintf( stderr, "error: -l bad input format\n" );
@@ -162,6 +195,11 @@ int main( int argc, char* argv[] )
                                }
                                        
                                read_addr_port( optstr, &eth_listen_addr, &eth_listen_port ); /*chk*/
+                       case 'k':
+                               cmd |= CMD_STOP_LISTEN;
+                               break;
+                       case '?':
+                               break;
                        default:
                                fprintf( stderr, "error: unknown option\n" );
                        break;
@@ -169,15 +207,18 @@ int main( int argc, char* argv[] )
        }
 
        /* 2. do check on arguments */
-       if( (src_if == 0 || dst_if == 0) || (src_if == dst_if) )
+       if( cmd & CMD_ADD_RULE )
        {
-               fprintf( stderr, "error: source or destination not specified\n" );
-               return -1;
-       }
+               if( (src_if == 0 || dst_if == 0) || (src_if == dst_if) )
+               {
+                       fprintf( stderr, "error: source or destination not specified\n" );
+                       return -1;
+               }
        
-       if( src_if == dst_if )
-       {
-               fprintf( stderr, "error: source and destination same interface type\n" );
+               if( src_if == dst_if )
+               {
+                       fprintf( stderr, "error: source and destination same interface type\n" );
+               }
        }
        
        /* 3. prepare netlink message */
@@ -188,26 +229,31 @@ int main( int argc, char* argv[] )
        req.nh.nlmsg_pid   = 0; /* ? */
        
        req.rtcan.can_family = AF_CAN;
-       req.rtcan.gwtype = (src_if == IF_CAN) ? CGW_TYPE_CAN_ETH_UDP : CGW_TYPE_ETH_CAN_UDP;
        req.rtcan.flags = 0;
-       
-       addattr_l( &req.nh, sizeof(req), CGW_CAN_IF, &can_ifidx, sizeof(can_ifidx) );
-       switch( req.rtcan.gwtype )
+
+       if( cmd & CMD_ADD_RULE )
        {
-               case CGW_TYPE_CAN_ETH_UDP:
-                       addattr_l( &req.nh, sizeof(req), CGW_ETH_IP, &eth_addr, sizeof(eth_addr) );
-                       addattr_l( &req.nh, sizeof(req), CGW_ETH_PORT, &eth_port, sizeof(eth_port) );
-                       break;
-               case CGW_TYPE_ETH_CAN_UDP:
-                       break;
-               default:
-                       break;
+               req.rtcan.gwtype = (src_if == IF_CAN) ? CGW_TYPE_CAN_ETH_UDP : CGW_TYPE_ETH_CAN_UDP;
+               addattr_l( &req.nh, sizeof(req), CGW_CAN_IF, &can_ifidx, sizeof(can_ifidx) );
+               switch( req.rtcan.gwtype )
+               {
+                       case CGW_TYPE_CAN_ETH_UDP:
+                               addattr_l( &req.nh, sizeof(req), CGW_ETH_IP, &eth_addr, sizeof(eth_addr) );
+                               addattr_l( &req.nh, sizeof(req), CGW_ETH_PORT, &eth_port, sizeof(eth_port) );
+                               break;
+                       case CGW_TYPE_ETH_CAN_UDP:
+                               break;
+                       default:
+                               break;
+               }
        }
        
-       if( have_listen )
+       if( cmd & CMD_START_LISTEN )
        {
+               req.rtcan.gwtype = CGW_TYPE_CONFIG;
                addattr_l( &req.nh, sizeof(req), CGW_LISTEN_IP, &eth_listen_addr, sizeof(eth_listen_addr) );
                addattr_l( &req.nh, sizeof(req), CGW_LISTEN_PORT, &eth_listen_port, sizeof(eth_listen_port) );
+               printf( "start listen: %x, %hu\n", eth_listen_addr, eth_listen_port );
        }
        
        /* 4. send over netlink socket */
@@ -232,3 +278,4 @@ int main( int argc, char* argv[] )
 syntax_error:
        return -1;
 }
+