6 #include <netinet/in.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <arpa/inet.h>
14 #include <linux/can.h>
15 #include <linux/can/raw.h>
31 #define printdbg(x) printf(x)
41 #define GW_FLAG_LISTEN 4
42 #define GW_FLAG_FILTER 8
44 unsigned int opt_flag = 0;
47 struct can_filter flt;
48 struct sockaddr_in udp_dest;
52 * @return true if frame should be dropped
54 bool filter_check( struct can_frame* cf )
56 if( !(opt_flag & GW_FLAG_FILTER) )
59 return ( (cf->can_id & flt.can_mask) == (flt.can_id & flt.can_mask) );
66 read( sock_udp, &cf, sizeof(cf) );
68 if( filter_check( &cf ) )
70 printdbg( "filter: drop\n" );
74 write( sock_can, &cf, sizeof(cf) );
76 printdbg( "eth -> can\n" );
83 read( sock_can, &cf, sizeof(cf) );
85 if( filter_check( &cf ) )
87 printdbg( "filter: drop\n" );
91 sendto( sock_udp, &cf, sizeof(cf), 0, (struct sockaddr*) &udp_dest, sizeof(udp_dest) );
93 printdbg( "can -> eth\n" );
96 void signal_exit( int sig )
100 printf( "exiting\n" );
105 int main( int argc, char* argv[] )
107 struct sockaddr_in udp_addr;
108 struct sockaddr_can can_addr;
109 struct pollfd pfd[2];
112 struct cegw_if ceif[2], iflisten;
113 struct cegw_if* ifcan,* ifeth;
118 struct option longopt[] =
120 {"listen", 1, NULL, 'l'},
124 while( (opt = getopt_long( argc, argv, "s:d:l:f:i:", longopt, NULL )) != -1 )
129 if( read_if(optarg, &ceif[0]) != 0 )
134 opt_flag |= GW_FLAG_SRC;
137 if( read_if(optarg, &ceif[1]) != 0 )
142 opt_flag |= GW_FLAG_DST;
145 if( read_if(optarg, &iflisten) != 0 )
150 if( iflisten.type != IF_ETH_UDP )
152 perr( "'-l' udp interface expected" );
155 opt_flag |= GW_FLAG_LISTEN;
158 if( sscanf( optarg, "%x:%x", &flt.can_id,
159 &flt.can_mask ) != 2 )
161 perr( "bad filter format");
164 opt_flag |= GW_FLAG_FILTER;
172 if( !((opt_flag & GW_FLAG_SRC) && (opt_flag & GW_FLAG_DST)
173 && (opt_flag & GW_FLAG_LISTEN)) )
175 perr( "'s', 'd' and 'l' are mandatory" );
180 if( !(ceif[0].type == IF_CAN && ceif[1].type == IF_ETH_UDP) &&
181 !(ceif[0].type == IF_ETH_UDP && ceif[1].type == IF_CAN ) )
183 perr( "'-s' and '-d' should be different interface type" );
187 if( ceif[0].type == IF_CAN )
197 signal( SIGINT, signal_exit );
199 /* prepare udp destination */
200 udp_dest.sin_family = AF_INET;
201 udp_dest.sin_port = htons(ifeth->eth.port);
202 udp_dest.sin_addr = ifeth->eth.ip;
205 sock_udp = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
208 perr( "udp socket creation failed" );
212 udp_addr.sin_family = AF_INET;
213 udp_addr.sin_port = htons(iflisten.eth.port);
214 udp_addr.sin_addr = iflisten.eth.ip;
216 if( bind( sock_udp, (struct sockaddr*) &udp_addr, sizeof(udp_addr) ) < 0 )
218 perr( "udp socket binding failed" );
224 sock_can = socket( PF_CAN, SOCK_RAW, CAN_RAW );
227 perr( "can socket creation failed");
232 can_addr.can_family = AF_CAN;
233 can_addr.can_ifindex = ifcan->can.ifindex;
235 if( bind( sock_can, (struct sockaddr*) &can_addr, sizeof(can_addr) ) < 0 )
237 perr( "can socket binding failed" );
242 pfd[GW_POLL_ETH].fd = sock_udp;
243 pfd[GW_POLL_ETH].events = POLLIN | POLLPRI;
244 pfd[GW_POLL_ETH].revents = 0;
246 pfd[GW_POLL_CAN].fd = sock_can;
247 pfd[GW_POLL_CAN].events = POLLIN | POLLPRI;
248 pfd[GW_POLL_CAN].revents = 0;
250 printf( "canethgw is running\n" );
254 printdbg( "polling\n" );
255 polret = poll( pfd, 2, -1 );
258 perr( "poll(..) failed" );
264 if( pfd[GW_POLL_ETH].revents != 0 )
268 if( pfd[GW_POLL_CAN].revents != 0 )
273 pfd[GW_POLL_ETH].revents = 0;
274 pfd[GW_POLL_CAN].revents = 0;