免费注册 查看新帖 |

Chinaunix

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

[内核模块] dev_queue_xmit 死机,小白求帮助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-11-04 13:26 |只看该作者 |倒序浏览
在内核模块中将利用netfilter在local_out挂载一个钩子函数,将发送出去的icmp报文都添加vxlan隧道报文。在利用dev_queue_xmit发包,发包的时候centos系统死机了,求帮助,下面是我的代码:
static int add_tunnel_vxlan(struct sk_buff *s_skb,
                                UINT1 smac[],UINT1 dmac[],UINT4 sip,UINT4 dip,UINT2 sport,UINT2 dport,UINT4 vni)
{
        struct sk_buff *skb =NULL;
        tUdp *pUdp =NULL;
        tIp* pIp =NULL;
        tEther* peth=NULL;
        struct vxlan_header *pvxlan =NULL;
        char *p =NULL;
        int ret =0;

        int data_len = s_skb->len+sizeof(struct ethhdr); //±¨¤
        int udp_data_len = data_len + sizeof(struct vxlan_header)+sizeof(struct udphdr);
        int ip_data_len   = udp_data_len + sizeof(struct iphdr);
        int tot_len = ip_data_len + sizeof(struct ethhdr); //í±¨¤

        skb = alloc_skb(1514,GFP_ATOMIC);
       
        // 猀欀戀
        skb->pkt_type = s_skb->pkt_type;
        skb->dev = s_skb->dev;
        skb->ip_summed = s_skb->ip_summed;
        skb->len = ip_data_len;

    /* ±猀欀戀ò */
    skb_reserve (skb, 2 +tot_len);

    /* ì */
    p = skb_push(skb, data_len-sizeof(struct ethhdr));
    memcpy(p, skb->data, data_len-sizeof(struct ethhdr));

    p= skb_push(skb,sizeof(struct ethhdr));
    peth =(tEther*)p;
    peth->proto = ntohs(ETH_P_IP);
    memcpy(peth->src,smac,MAC_ALEN);
    memcpy(peth->dest,dmac,MAC_ALEN);

        /*¨ vxlan·*/
    p = skb_push(skb, sizeof(struct vxlan_header));
    pvxlan = (struct vxlan_header*)p;
    pvxlan->flags = 0x08;
    pvxlan->vni   = vni;

        /*ìUDP·*/
    p = skb_push(skb, sizeof(struct udphdr));
    pUdp = (tUdp *)p;  
    // 甀搀瀀栀搀爀×
    pUdp->dport = dport;
    pUdp->sport = sport;
    pUdp->cksum =0x00;
    pUdp->len   = ntohs(udp_data_len);
    skb_reset_transport_header(skb);

    /* ìIP· */
    p = skb_push(skb, sizeof(struct iphdr));
    pIp = (tIp*)p;
    // 椀瀀栀搀爀×
    pIp->hlen = 0x45;
    pIp->tos = 0;
    pIp->len = ntohs(ip_data_len);
    pIp->ipid =interface_ipid++;
    pIp->fragoff =0x00;
    pIp->ttl =64;
    pIp->proto = IPPROTO_UDP;
    pIp->src = sip;
    pIp->dest = dip;
    pIp->cksum =0;
    skb_reset_network_header(skb);

    /* ì· */
    p = skb_push(skb, sizeof(struct ethhdr));
    peth = (tEther*)p;
    // 攀琀栀栀搀爀×
    peth->proto = ntohs(ETH_P_IP);
    memcpy(peth->src,smac,MAC_ALEN);
    memcpy(peth->dest,dmac,MAC_ALEN);
    skb_reset_mac_header(skb);

    /* · */
    //ret = dev_queue_xmit(skb);
    if(ret <0)
    {
             printk("dev_queue_xmit() error\n");
             return 1;
    }
        return 0;
}

将dev_queue_xmit注释掉的时centos正常,打开注释,发包的时centos直接死机了。求大神们帮忙

论坛徽章:
0
2 [报告]
发表于 2015-11-04 13:56 |只看该作者
有大神知道是哪里有问题么?

求职 : 通讯/电信开
论坛徽章:
2
2015亚冠之鹿岛鹿角
日期:2015-07-08 11:58:2615-16赛季CBA联赛之佛山
日期:2015-12-21 17:28:04
3 [报告]
发表于 2015-11-04 16:58 |只看该作者
  data_len怎么加上以太网头部了?
  int data_len = s_skb->len+sizeof(struct ethhdr); //±¨¤

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2015-11-05 10:17 |只看该作者
回复 1# qq452739204

你这是将一个 LOCAL out 出去的正常 ip 报文,加了个 VLAN 头吧。 dev_queue_xmit 发送的报文,下面就交给网卡驱动的。

所以你应该是在调用 xmit 前,将报文构造正确。这个有检验吗?


   

论坛徽章:
0
5 [报告]
发表于 2015-11-05 10:28 |只看该作者
贴的代码里面没有做校验,贴图之后把校验和加上了回复 4# Godbach


   

论坛徽章:
0
6 [报告]
发表于 2015-11-05 10:34 |只看该作者
回复 3# 九阳神功爱喝茶
data_len是原报文呀,skb->len的长度值不包括以太网头部的,我打印skb->len之后才发现的。skb->data指向的是IP头部。所以后来我人为的给原报文添加了一个以太网头部。

   

求职 : 通讯/电信开
论坛徽章:
2
2015亚冠之鹿岛鹿角
日期:2015-07-08 11:58:2615-16赛季CBA联赛之佛山
日期:2015-12-21 17:28:04
7 [报告]
发表于 2015-11-05 10:38 |只看该作者
那后面为什么又要加上一个以太网头部呢  int tot_len = ip_data_len + sizeof(struct ethhdr); //í±¨¤回复 6# qq452739204


   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2015-11-05 11:05 |只看该作者
回复 6# qq452739204

你封装的报文,要加上 VLAN 头,还有 MAC 头的。这个你处理好了吗



   

论坛徽章:
0
9 [报告]
发表于 2015-11-05 11:16 |只看该作者
回复 8# Godbach


   已经解决了,是skb->dev这个赋值有问题,改成skb->dev = dev_get_by_name(sock_net(s_skb->sk),"eth0";就可以了。谢谢你啦

论坛徽章:
0
10 [报告]
发表于 2015-11-05 11:40 |只看该作者
回复 8# Godbach


   现在再看csum_tcpudp_magic这个函数怎么用的了,总感觉我的参数没填对;        uh = udp_hdr(skb);
        skb->csum = csum_partial(skb_transport_header(skb),skb->len, 0);
        uh->check = csum_tcpudp_magic(iph->saddr,iph->daddr, ntohs(uh->len), iph->protocol, skb->csum);


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP