1 #include "gw.h" /* override */
3 #include <linux/module.h>
4 #include <linux/kernel.h>
5 #include <linux/kthread.h>
6 #include <linux/sched.h>
7 #include <linux/delay.h>
8 #include <linux/wait.h>
9 #include <linux/netdevice.h>
10 #include <linux/socket.h>
11 #include <linux/net.h>
12 #include <linux/can/core.h>
13 #include <linux/can.h>
14 #include <net/rtnetlink.h>
17 MODULE_LICENSE( "GPL" );
19 static struct task_struct* eth_to_can, * can_to_eth;
20 static struct socket* udp_sock;
21 static struct socket* can_sock;
22 static struct net_device* can_dev;
24 /***********************
26 ***********************/
28 static int gw_udp_recv( void* data )
35 vec.iov_len = sizeof(cf);
41 mh.msg_control = NULL;
42 mh.msg_controllen = 0;
47 if( kthread_should_stop() ) /* up() ?, recv is blocking */
49 kernel_recvmsg( udp_sock, &mh, &vec, 1, sizeof(cf), 0 ); /* todo: handle error */
50 printk( "received udp msg_id:%d\n", cf.can_id );
57 static void gw_udp_send( struct can_frame* cf )
60 struct sockaddr_in addr;
63 addr.sin_family = AF_INET;
64 addr.sin_port = htons( 10502 );
65 addr.sin_addr.s_addr = 0x0100007f;
68 mh.msg_namelen = sizeof( addr );
69 mh.msg_control = NULL;
70 mh.msg_controllen = 0;
74 vec.iov_len = sizeof( *cf );
76 kernel_sendmsg( udp_sock, &mh, &vec, 1, sizeof( *cf ) );
79 /***********************
81 ***********************/
83 static int gw_can_recv( void* data )
91 mh.msg_control = NULL;
92 mh.msg_controllen = 0;
96 vec.iov_len = sizeof( cf );
100 if( kthread_should_stop() ) /**/
102 kernel_recvmsg( can_sock, &mh, &vec, 1, sizeof( cf ), 0 );
103 printk( "received can msg_id:%d\n", cf.can_id );
110 static void gw_can_send( struct can_frame* cf )
117 mh.msg_control = NULL;
118 mh.msg_controllen = 0;
122 vec.iov_len = sizeof( *cf );
124 kernel_sendmsg( can_sock, &mh, &vec, 1, sizeof( *cf ) );
129 static int cgw_create_job( struct sk_buff* skb, struct nlmsghdr* nlh,
132 struct nlattr* tb[ CGW_MAX+1 ];
137 if (nlmsg_len(nlh) < sizeof(*r))
141 if (r->can_family != AF_CAN)
142 return -EPFNOSUPPORT;
144 /* so far we only support CAN -> CAN routings */
145 if (r->gwtype == CGW_TYPE_CAN_ETH)
146 printk( KERN_INFO "canethgw: TYPE_CAN_ETH" );
150 err = nlmsg_parse( nlh, sizeof( struct rtcanmsg ), tb, CGW_MAX, NULL );
154 printk( KERN_INFO "src port:%u\n", *(u16*)nla_data( tb[CGW_SRC_PORT] ) );
155 printk( KERN_INFO "dest port:%u\n", *(u16*)nla_data( tb[CGW_DST_PORT] ) );
160 /***********************
162 ***********************/
164 static int __init cangw_init( void )
166 struct sockaddr_in udp_addr;
167 struct sockaddr_can can_addr;
170 /* 1. create can socket and bind to it */
171 can_dev = dev_get_by_name( &init_net, "vcan0" ); /* net ns?, release counter! */
172 if( can_dev == NULL )
174 printk( KERN_ERR "error: vcan0 not found\n" );
177 ifidx = can_dev->ifindex;
180 if( sock_create_kern( PF_CAN, SOCK_RAW, CAN_RAW, &can_sock) != 0 )
182 printk( KERN_ERR "error: can_sock creation failed\n" );
186 can_addr.can_family = AF_CAN;
187 can_addr.can_ifindex = ifidx;
189 if( can_sock->ops->bind( can_sock, (struct sockaddr*) &can_addr, sizeof(can_addr) ) != 0 )
191 printk( KERN_ERR "can_sock bind failed\n" );
195 /* 2. create udp socket and bind to it */
196 if( sock_create_kern( PF_INET, SOCK_DGRAM, IPPROTO_UDP, &udp_sock ) != 0 )
198 printk( "error: udp_sock creation failed\n" );
199 sock_release( can_sock );
203 udp_addr.sin_family = AF_INET;
204 udp_addr.sin_port = htons( 10501 );
205 udp_addr.sin_addr.s_addr = INADDR_ANY;
207 if( udp_sock->ops->bind( udp_sock, (struct sockaddr*)&udp_addr, sizeof( udp_addr ) ) != 0 ) /* ref impl ?!? */
209 printk( "error: binding failed\n" );
210 sock_release( udp_sock );
211 sock_release( can_sock );
215 /* 3. subscribe to netlink */
216 //if( __rtnl_register( PF_CAN, RTM_GETROUTE, ) != 0 )
217 __rtnl_register( PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, NULL );
218 //__rtnl_register( PF_CAN, RTM_DELROUTE, )
221 eth_to_can = kthread_run( gw_udp_recv, NULL, "cangw" );
222 can_to_eth = kthread_run( gw_can_recv, NULL, "cangw" );
225 if( sock_create_kern( AF_CAN, SOCK_RAW, CAN_RAW, &can_sock ) != 0 )
227 printk( "error: can_sock creation failed\n" );
234 static void __exit cangw_exit( void )
236 sock_release( udp_sock );
237 sock_release( can_sock );
239 printk( "cangw: exit\n" );
240 //kthread_stop( ts );
243 module_init( cangw_init );
244 module_exit( cangw_exit );