#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"
/**
unsigned short eth_listen_port;
};
-struct cegw_nlmsg
+struct cegw_nlmsg
{
struct nlmsghdr nh;
struct rtmsg rt;
unsigned int cegw_errno = 0;
-enum
+enum
{
CEGW_ERR_UNKNOWN,
CEGW_ERR_IF_UNSPEC,
}
/**
- * 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
{
req->nh.nlmsg_type = RTM_GETROUTE;
req->nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
-
+
return 0;
}
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; /* ? */
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 )
}
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 );