免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1837 | 回复: 2
打印 上一主题 下一主题

[内核模块] 求助,netfilter实现两块网卡之间的流量转发 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-03-24 16:43 |只看该作者 |倒序浏览
情况是这样的,主机上有两块网卡(eth0和eth1),我想实现的功能就是:把从eth0出去的数据包复制一份发给eth1。
遇到的问题是我把hook挂在LOCAL_OUT,然后将eth0的包复制并修改目标MAC,但是总是死机,我试过了,导致死机的就是红色那部分,但是不知道为什么,求告知啊

int copy_forward(struct sk_buff * skb, struct iphdr * iph)
{
    int tot_len, iph_len;

    struct ethhdr * mach = NULL;
    struct net_device * dev = NULL;

    int ret = 0;

    iph_len = ip_hdrlen ( skb );
    tot_len = ntohs ( iph->tot_len );

            struct sk_buff * new_skb;
            if( !(new_skb = skb_copy(skb, GFP_ATOMIC)) )
            {
                printk ("skb_copy failed");
                return -1;
            }

            dev = dev_get_by_name ( &init_net, _IF_ETH1_ );
            new_skb->dev = dev;
            skb_push ( new_skb, ETHALEN );
            mach = eth_hdr ( new_skb );

            memcpy (mach->h_source, mac_src, ETH_ALEN);
            mach->h_proto = __constant_htons (ETH_P_IP);
            memcpy ( mach->h_dest, mac_dst, ETH_ALEN );

            
            ret = dev_queue_xmit ( new_skb );   
  
            if ( ret < 0 )
            {
                dev_put ( dev );
                return -1;
            }
            

    dev_put ( dev );
    return 0;
}

unsigned int pkt_filter ( unsigned int hooknum, struct sk_buff * __skb,
        const struct net_device * in, const struct net_device * out,
        int ( *okfn ) ( struct sk_buff * ) )
{

    struct sk_buff * skb;
    struct iphdr * iph;
    struct tcphdr *tcph;

    int tot_len, iph_len, tcph_len;
    int payload_len;
    unsigned char * payload = NULL;

    int mark = NO_ACTION;

    skb = __skb;
    if ( skb == NULL ) { return NF_ACCEPT; }

    iph = ip_hdr ( skb );
    if ( iph == NULL ) { return NF_ACCEPT; }
    iph_len = ip_hdrlen ( skb );

    tot_len = ntohs ( iph->tot_len );
    if ( tot_len <= 20 ) { return NF_ACCEPT; }


    if( !(memcmp(out->name, _IF_ETH0_, sizeof(_IF_ETH0_)) == 0) )
    {
        return NF_ACCEPT;
    }

    switch ( iph->protocol )
    {
        case IPPROTO_TCP:
            {
            skb_pull(skb, iph_len);
            skb_reset_transport_header(skb);
            tcph = tcp_hdr ( skb );

            
            if(tcph->dest == htons(22) || tcph->source == htons(22))
            {

                skb_push(skb, iph_len);
                return NF_ACCEPT;
            }

            else
            {
                skb_push(skb, iph_len);
                mark = COPY;
            }
            break;
            }
        default:
            {
            break;
            }
    }

    switch ( mark )
    {
        case COPY:                        
            {
            if( -1 == copy_forward(skb, iph) )
            {
                printk_0 ("Packet copy and forward failed");
            }
            break;
            }
        default:
            break;
    }

    return NF_ACCEPT;
}

static int __init init ( void )
{

    nfho_filter.hook     = pkt_filter;
    //nfho_filter.hooknum  = NF_INET_PRE_ROUTING;
    //nfho_filter.hooknum  = NF_INET_POST_ROUTING;
    //nfho_filter.hooknum  = NF_INET_FORWARD;
    nfho_filter.hooknum  = NF_INET_LOCAL_OUT;
    nfho_filter.pf       = PF_INET;

    //nfho_filter.priority = NF_IP_PRI_CONNTRACK+1;
    nfho_filter.priority = NF_IP_PRI_FIRST+1;
    nf_register_hook ( &nfho_filter );


    return 0;
}

static void __exit fini ( void )
{
    nf_unregister_hook ( &nfho_filter );

}

module_init ( init );
module_exit ( fini );

论坛徽章:
4
丑牛
日期:2014-01-11 15:11:12亥猪
日期:2014-12-15 22:19:092015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-03-13 19:45:11
2 [报告]
发表于 2015-03-24 20:25 |只看该作者
我说的不一定对,只修改mac地址应该还不行吧,我觉得你还得修改Ip地址,两个网卡,两个IP,另外,如果传输层是udp的话,可能过程会简单些

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
3 [报告]
发表于 2015-03-26 09:24 |只看该作者
本帖最后由 nswcfd 于 2015-03-26 09:39 编辑

local out的位置skb.mac还没有初始化呢。
也就是说,在这个上下文里,eth_hdr返回值是没有意义的。

试试在pull(ETH_ALEN)和eth_hdr()之间加上一句skb_reset_mac_hdr()。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP