]> rtime.felk.cvut.cz Git - can-eth-gw.git/blobdiff - utils/cegw/cegw.c
canethgw micsdevice
[can-eth-gw.git] / utils / cegw / cegw.c
index fc91a9ce48a9672b38f2001ba9be5bf7eefe205c..73726346e291b69096afb0dcedd4c5a606dd9e18 100644 (file)
 #include <linux/can.h>
 #include <linux/types.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
 #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 );