本文档的Copyleft归necofang所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。 msn :
近来做一个产品需要在网关上获取特定UDP端口(假设是1000端口)的报文,并将其转发给其它设备的1000端口。虽然此类文章网上已经有很多了,但我还是贴上来,这样自己也做下记录,大家也多一份参考。
下面只给出了代码片段,自己慢慢调试。
我们假设网络拓扑如下所示:
LINUX +---------+ +---------+ +---------+ | PC-1 |-------| Server | -------| DataSrv | +---------+ +---------+ +---------+
pc-1发送udp报文到server的1000端口时,我们将报文拷贝一份并发送给DataSrv的1000端口。 报文的获取,我们采用netfilter hook. 我们将hook钩到 NF_IP_LOCAL_IN,优先级别设置成NF_IP_PRI_FIRST。
为什么hook到NF_IP_LOCAL_IN 而不是PERROUTING呢? 这是因为hook到 LOCAL_IN的话,我们就不用去考虑报文的重组了。如下图:
ip_rcv ------> ip_local_deliver ----------> netfilter
|-----------ip_defrag-------^
为什么优先级别设置成最高了,这样可以防止udp的穿透。
这里我们不详细描述netfilter hook如何编写。下面我们来看获取到skb(重组好了的)的报文后,我们如何处理。
首先,我们假设DataSrv的ip地址为 192.168.1.254/24;Server的ip地址为 192.168.1.253/24。
# define TEST_XMIT( skb, rt) \ NF_HOOK( PF_INET , NF_IP_LOCAL_OUT, ( skb) , NULL , \ ( rt) - > u. dst. dev, dst_output) ; # define IP_PARTS_NATIVE( n) \ ( unsigned int ) ( ( n) & 0xFF) , \ ( unsigned int ) ( ( n) > > 8) & 0xFF, \ ( unsigned int ) ( ( n) > > 16) & 0xFF, \ ( unsigned int ) ( ( n) > > 24) & 0xFF# define TEST_BUG( ) BUG( ) # define TEST_ERR( msg. . . ) printk( KERN_ERR "TEST: " msg) # define TEST_INFO( msg. . . ) printk( KERN_INFO "TEST: " msg) # define TEST_WARNING( msg. . . ) printk( KERN_WARNING "TEST: " msg) # define TEST_ERR_RL( msg. . . ) \ do { \ if ( net_ratelimit( ) ) \ printk( KERN_ERR "TEST: " msg) ; \ } while ( 0)
//调用test_pop前 需要 拷贝或克隆 skb,然后再传入 static inline int TEST_pop ( struct sk_buff * skb) { struct iphdr * iph = NULL ; struct rtable * rt = NULL ; struct ethhdr * ethh = NULL ; struct flowi fl; unsigned long ulpeerip = 0; unsigned int udphoff = 0; fl. oif = 0; fl. nl_u. ip4_u. daddr = in_aton ( "192.168.1.254" ) ; fl. nl_u. ip4_u. saddr = in_aton ( "192.168.1.253" ) ; fl. nl_u. ip4_u. tos = RT_TOS( 0) ; //查找出口路由 if ( unlikely ( ip_route_output_key( & rt, & fl) ) ) { TEST_ERR( "%s no route from 192.168.1.253 to 192.168.1.254 (%s:%d)\n" , __FUNCTION__ , __FILE__ , __LINE__ ) ; return ( 1) ; } //修改IP头 iph = skb- > nh. iph; iph-
阅读(2558) | 评论(0) | 转发(0) |