关于扩展报头的问题

我需要在ipv4报头前面加一个扩展报头,所以在ip_rcv中加了一个自己写的函数,但是使用skb_push后,加了一个扩展报头,没有进行其他操作,机子重启,老是在我改的地方循环走,不能正常关机,是否还需要写其他相应的东西。多谢了

作者: duancanran   发布时间: 2011-02-22

你怎么扩展的包头,skb 相关指针怎么调整的

作者: Godbach   发布时间: 2011-02-22

扩展以后大于 MTU 了你打算怎么处理?

作者: platinum   发布时间: 2011-02-22

int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
        struct iphdr *iph;
        u32 len;

        /* added by DongPing for address mapping,20060614 */
        if((*addrmap_func)(skb, ((struct iphdr *)(skb->network_header))->daddr,((struct iphdr *)(skb->network_header))->saddr)==0)
                goto drop;       
        /* added end */

        /* When the interface is in promisc. mode, drop all the crap
         * that it receives, do not try to analyse it.
         */

        add_pid_to_header(skb);
        printk("skb->pkt_type is %d\n",skb->pkt_type);
        if (skb->pkt_type == PACKET_OTHERHOST)
                goto drop;
这是原先的代码,我添加了一个函数add_pid_to_header(skb),其他没改变

作者: duancanran   发布时间: 2011-02-22



QUOTE:
    add_pid_to_header(skb);


能否把这个函数的实现贴出来

作者: Godbach   发布时间: 2011-02-22

另外,ip_rcv 是处理进入系统的包,你给这个数据包 IP 头前添加一些内容,是基于什么需求。

作者: Godbach   发布时间: 2011-02-22

static void add_pid_to_header(struct sk_buff *skb)
{
        struct net *net = sock_net(skb->sk);
        struct iphdr *iph;
        struct ippidhdr *added_iph;//定义的扩展报头
        struct pid_node *sa_node;
        struct pid_node *da_node;
        __be32 saaddr,daaddr;
        unsigned int len;
        iph=ip_hdr(skb);
        printk("iph is %x\n",iph);
        char addr[1024];
        len=sizeof(struct ippidhdr);   

        printk("len is %d\n",len);
        printk("skb->head is %x\n",skb->head);
        printk("skb->data is %x\n",skb->data);
        saaddr=iph->saddr;

        skb_push(skb,len);
        printk("skb->data is %x\n",skb->data);

        saaddr=iph->saddr;

        inet_ntop(AF_INET,&saaddr,addr,1024);
        printk("ip_rcv saaddr is %s\n",saaddr);


        daaddr=iph->daddr;
        printk("ip_rcv daaddr is %x\n",daaddr);
        inet_ntop(AF_INET,&daaddr,addr,1024);
        printk("ip_rcv daaddr is %s\n",daaddr);


        sa_node=pid_node_lookup(net->ipv4.pid_route,saaddr);
        if(sa_node)
                {
                printk("sa_node pid is %x\n",sa_node->p.Pathid);
                added_iph->saas_nu=sa_node->p.as_nu;
                }
        else
                goto drop;
        da_node=pid_node_lookup(net->ipv4.pid_route,daaddr);
        if(da_node)
                {
                printk("da_node pid is %x\n",da_node->p.Pathid);
                added_iph->daas_nu=da_node->p.as_nu;
                added_iph->Pathid=da_node->p.Pathid;
                }
        else
                goto drop;

        printk("iph is %x\n",iph);
        printk("added_iph->saas_nu is %x\n",added_iph->saas_nu);
        printk("added_iph->daas_nu is %x\n",added_iph->daas_nu);
        printk("added_iph->Pathid is %x\n",added_iph->Pathid);


drop:
        printk("don't find as number and pid");*/
        skb_pull(skb,len);
        printk("skb->data is %x\n",skb->data);
        saaddr=iph->saddr;
        printk("ip_rcv saaddr3 is %x\n",saaddr);
        skb_reset_network_header(skb);
       
}

作者: duancanran   发布时间: 2011-02-22

写的很烂,大家将就着看看

作者: duancanran   发布时间: 2011-02-22



QUOTE:
static void add_pid_to_header(struct sk_buff *skb)
{
       struct net *net = sock_net(skb->sk);


高亮加粗的这行代码是有问题的。
你可以先 printk skb->sk,这个应该是空指针,而你应该是通过 sock_net 进行解引用了。所以应该会 oops 的

作者: Godbach   发布时间: 2011-02-22

一个进入系统的数据包,才刚刚到三层,skb 的 sk 成员应该是没有被赋值的。

作者: Godbach   发布时间: 2011-02-22

回复 Godbach


    我把使用net的地方先注销了,还是不通过

作者: duancanran   发布时间: 2011-02-22

说一下你的需求吧。代码只是需求的实现

作者: Godbach   发布时间: 2011-02-22

回复 Godbach


    就是在ipv4包头前面加一点东西,根据需要决定是否添加,需要查我新建的几个表,就是这个功能

作者: duancanran   发布时间: 2011-02-22



QUOTE:
回复  Godbach


    就是在ipv4包头前面加一点东西,根据需要决定是否添加,需要查我新建的几个表,就 ...
duancanran 发表于 2011-02-22 16:46


也就是进入系统的数据包,你要查找几个自己建的表,以确定是否需要扩展 IP 头,对吧。

作者: Godbach   发布时间: 2011-02-22

回复 Godbach


    对

作者: duancanran   发布时间: 2011-02-22



QUOTE:
回复  Godbach


    对
duancanran 发表于 2011-02-22 17:08


那你觉得在 IP 头部插入新的数据,这个实现中你要那些因素需要考虑吗?

作者: Godbach   发布时间: 2011-02-22

还有,你添加了这个数据之后,后续那个环节会去读取呢?

作者: Godbach   发布时间: 2011-02-22

既然你前面说这行代码注释掉了:


QUOTE:
       struct net *net = sock_net(skb->sk);



那么,下面这些代码注释了吗:


QUOTE:
      sa_node=pid_node_lookup(net->ipv4.pid_route,saaddr);
        if(sa_node)
                {
                printk("sa_node pid is %x\n",sa_node->p.Pathid);
                added_iph->saas_nu=sa_node->p.as_nu;
                }
        else
                goto drop;
        da_node=pid_node_lookup(net->ipv4.pid_route,daaddr);
        if(da_node)
                {
                printk("da_node pid is %x\n",da_node->p.Pathid);
                added_iph->daas_nu=da_node->p.as_nu;
                added_iph->Pathid=da_node->p.Pathid;
                }
        else
                goto drop;


方便的话,把修改后的代码重新贴一下吧。

作者: Godbach   发布时间: 2011-02-22

问一下楼主,修改数据包的机器用于自己处理数据(送往自身的高层协议栈),还是负责数据转发?

作者: platinum   发布时间: 2011-02-22

回复 Godbach


    在路由的时候我会用到,根据我添加的东西,判断一些路由的规则,支持应用层的服务,至于要考虑什么不是很清楚,也是新手,被老师逼着去完成,只能边学边弄,能指教一下么

作者: duancanran   发布时间: 2011-02-22

如果转发的话,路由器能正确识别出来吗

作者: Godbach   发布时间: 2011-02-22



QUOTE:
回复  Godbach


    在路由的时候我会用到,根据我添加的东西,判断一些路由的规则,支持应用层的服务 ...
duancanran 发表于 2011-02-22 17:27


那就说你这台机器是主机,不具有转发功能。

作者: Godbach   发布时间: 2011-02-22

你要记录的信息有多少字节?

作者: Godbach   发布时间: 2011-02-22

如果只是在 IP 层用,需要记录一些私有数据,是可以考虑使用 skb->cb 的。这样避免了修改数据包了。

作者: Godbach   发布时间: 2011-02-22



QUOTE:
如果转发的话,路由器能正确识别出来吗
Godbach 发表于 2011-02-22 17:27



我担心的倒不是这个,大不了对端再有一个去掉 header 的程序去处理
我担心设备收到 IP 报文后,添加了数据,长度大于 MTU 了,之后重新分片,导致 TCP 数据错误,无法穿越 internet
比如,MTU 是 1500,添加了一个 header,长度变成了 1510
IP 头长度 20 字节,TCP 头长度 20 字节,TCP payload 1460 字节(MSS 设定)
由于转发的时候,重新根据 1500 的 MTU 进行处理,导致所有原本不用分片的 IP 包全部分片了
TCP 里面又有很多很复杂的拥塞控制机制,结果……………………

在实际环境中会影响吗?

作者: platinum   发布时间: 2011-02-22

回复 platinum


    数据转发

作者: duancanran   发布时间: 2011-02-22

应用层修改的是路由协议

作者: duancanran   发布时间: 2011-02-22

回复 Godbach


    8,我打印出来,skb->head和skb->data之间可以足够放8字节

作者: duancanran   发布时间: 2011-02-22

回复 duancanran

head 和 data 之间是超过 8 个字节,因为里面有 MAC 头部,那你修改了这部分,确定不要 MAC 头部了吗

作者: Godbach   发布时间: 2011-02-22



QUOTE:
我担心的倒不是这个,大不了对端再有一个去掉 header 的程序去处理


这个地方为什么不用担心啊,公网上的路由器不是受你控制的,你在 MAC 头和 IP 头增加了数据,路由器怎么解析 IP 啊。



QUOTE:
我担心设备收到 IP 报文后,添加了数据,长度大于 MTU 了,之后重新分片,导致 TCP 数据错误,无法穿越 internet


LZ 说是修改 skb 的 head 和 data 之间的数据了。倒是没有修改数据包长度,不过 MAC 头就被修改了。

BTW,我觉得是不是可以考虑使用 skb->cb。

作者: Godbach   发布时间: 2011-02-22