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;
25 struct can_filter filter;
33 struct in_addr dst_addr;
34 unsigned short dst_port;
44 struct can_filter filter;
47 struct in_addr dst_addr;
48 unsigned short dst_port;
51 /* list entry for CAN gateways jobs */
53 struct hlist_node list;
58 /* CAN frame data source */
59 struct net_device *dev;
62 /* CAN frame data destination */
63 struct net_device *dev;
66 struct can_can_gw ccgw;
72 /***********************
74 ***********************/
76 static int gw_udp_recv( void* data )
83 vec.iov_len = sizeof(cf);
89 mh.msg_control = NULL;
90 mh.msg_controllen = 0;
95 if( kthread_should_stop() ) /* up() ?, recv is blocking */
97 kernel_recvmsg( udp_sock, &mh, &vec, 1, sizeof(cf), 0 ); /* todo: handle error */
98 printk( "received udp msg_id:%d\n", cf.can_id );
105 static void gw_udp_send( struct can_frame* cf )
108 struct sockaddr_in addr;
111 addr.sin_family = AF_INET;
112 addr.sin_port = htons( 10502 );
113 addr.sin_addr.s_addr = 0x0100007f;
116 mh.msg_namelen = sizeof( addr );
117 mh.msg_control = NULL;
118 mh.msg_controllen = 0;
122 vec.iov_len = sizeof( *cf );
124 kernel_sendmsg( udp_sock, &mh, &vec, 1, sizeof( *cf ) );
127 /***********************
129 ***********************/
131 static int gw_can_recv( void* data )
139 mh.msg_control = NULL;
140 mh.msg_controllen = 0;
144 vec.iov_len = sizeof( cf );
148 if( kthread_should_stop() ) /**/
150 kernel_recvmsg( can_sock, &mh, &vec, 1, sizeof( cf ), 0 );
151 printk( "received can msg_id:%d\n", cf.can_id );
158 static void gw_can_send( struct can_frame* cf )
165 mh.msg_control = NULL;
166 mh.msg_controllen = 0;
170 vec.iov_len = sizeof( *cf );
172 kernel_sendmsg( can_sock, &mh, &vec, 1, sizeof( *cf ) );
177 static int cgw_create_job( struct sk_buff* skb, struct nlmsghdr* nlh,
180 struct nlattr* tb[ CGW_MAX+1 ];
185 if (nlmsg_len(nlh) < sizeof(*r))
189 if (r->can_family != AF_CAN)
190 return -EPFNOSUPPORT;
192 /* so far we only support CAN -> CAN routings */
193 if (r->gwtype == CGW_TYPE_CAN_ETH_UDP)
194 printk( KERN_INFO "canethgw: TYPE_CAN_ETH" );
198 err = nlmsg_parse( nlh, sizeof( struct rtcanmsg ), tb, CGW_MAX, NULL );
202 printk( KERN_INFO "can:%d\n", *(u16*)nla_data( tb[CGW_CAN_IF] ) );
203 printk( KERN_INFO "eth addr:%x\n", *(u16*)nla_data( tb[CGW_ETH_IP] ) );
204 printk( KERN_INFO "eth port:%hu\n", *(u16*)nla_data( tb[CGW_ETH_PORT] ) );
209 /***********************
211 ***********************/
213 static int __init cangw_init( void )
215 struct sockaddr_in udp_addr;
216 struct sockaddr_can can_addr;
219 /* 1. create can socket and bind to it */
220 can_dev = dev_get_by_name( &init_net, "vcan0" ); /* net ns?, release counter! */
221 if( can_dev == NULL )
223 printk( KERN_ERR "error: vcan0 not found\n" );
226 ifidx = can_dev->ifindex;
229 if( sock_create_kern( PF_CAN, SOCK_RAW, CAN_RAW, &can_sock) != 0 )
231 printk( KERN_ERR "error: can_sock creation failed\n" );
235 can_addr.can_family = AF_CAN;
236 can_addr.can_ifindex = ifidx;
238 if( can_sock->ops->bind( can_sock, (struct sockaddr*) &can_addr, sizeof(can_addr) ) != 0 )
240 printk( KERN_ERR "can_sock bind failed\n" );
244 /* 2. create udp socket and bind to it */
245 if( sock_create_kern( PF_INET, SOCK_DGRAM, IPPROTO_UDP, &udp_sock ) != 0 )
247 printk( "error: udp_sock creation failed\n" );
248 sock_release( can_sock );
252 udp_addr.sin_family = AF_INET;
253 udp_addr.sin_port = htons( 10501 );
254 udp_addr.sin_addr.s_addr = INADDR_ANY;
256 if( udp_sock->ops->bind( udp_sock, (struct sockaddr*)&udp_addr, sizeof( udp_addr ) ) != 0 ) /* ref impl ?!? */
258 printk( "error: binding failed\n" );
259 sock_release( udp_sock );
260 sock_release( can_sock );
264 /* 3. subscribe to netlink */
265 //if( __rtnl_register( PF_CAN, RTM_GETROUTE, ) != 0 )
266 __rtnl_register( PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, NULL );
267 //__rtnl_register( PF_CAN, RTM_DELROUTE, )
270 eth_to_can = kthread_run( gw_udp_recv, NULL, "cangw" );
271 can_to_eth = kthread_run( gw_can_recv, NULL, "cangw" );
274 if( sock_create_kern( AF_CAN, SOCK_RAW, CAN_RAW, &can_sock ) != 0 )
276 printk( "error: can_sock creation failed\n" );
283 static void __exit cangw_exit( void )
285 sock_release( udp_sock );
286 sock_release( can_sock );
288 printk( "cangw: exit\n" );
289 //kthread_stop( ts );
292 module_init( cangw_init );
293 module_exit( cangw_exit );