`
shaojiashuai123456
  • 浏览: 262223 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
社区版块
存档分类
最新评论

ipv6 分片

阅读更多
519 static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
520 {
521         struct net_device *dev;
522         struct sk_buff *frag;
523         struct rt6_info *rt = (struct rt6_info*)skb->dst;
524         struct ipv6hdr *tmp_hdr;
525         struct frag_hdr *fh;
526         unsigned int mtu, hlen, left, len;
527         u32 frag_id = 0;
528         int ptr, offset = 0, err=0;
529         u8 *prevhdr, nexthdr = 0;
530 
531         dev = rt->u.dst.dev;                           //取得路由项中的设备
532         hlen = ip6_find_1stfragopt(skb, &prevhdr);//
533         nexthdr = *prevhdr;
534         //去掉分片头和ip头
535         mtu = dst_pmtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr);
1 快分片
          //如果已经在tcp分片,先查验第一个分片是否满足不用分片的条件,如果满足快速查验其他分片,有问题就跳到慢分片处处理
537         if (skb_shinfo(skb)->frag_list) {
     1.1 查看第一个分片
538                 int first_len = skb_pagelen(skb); //取得第一个分片长度
539                //查看第一个分片是否已经满足不用分片条件
540                 if (first_len - hlen > mtu ||       //是否大于MTU
541                     ((first_len - hlen) & 7) ||      //是否8字节对齐
542                     skb_cloned(skb))                   //是否克隆包
543                         goto slow_path;
     1.2 查看其他分片
545           for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) 
546            {             /* Correct geometry. */
547                         if (frag->len > mtu ||
548                             ((frag->len & 7) && frag->next) ||
549                             skb_headroom(frag) < hlen)
550                             goto slow_path;
551 
552                         /* Correct socket ownership. */
553                         if (frag->sk == NULL)
554                                 goto slow_path;
555 
556                         /* Partially cloned skb? */
557                         if (skb_shared(frag))  //如果是共享数据包,不能被修改
558                                 goto slow_path;
559               }
560 
561                 err = 0;
562                 offset = 0;
563                 frag = skb_shinfo(skb)->frag_list; 
564                 skb_shinfo(skb)->frag_list = NULL;
     1.3 设置主数据包头部
565                 /* BUILD HEADER */
        1.3.1 将头部放在临时区域
567                 tmp_hdr = kmalloc(hlen, GFP_ATOMIC);
568                 if (!tmp_hdr) {
569                         IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
570                         return -ENOMEM;
571                 }
572 
573                 *prevhdr = NEXTHDR_FRAGMENT;
574                 memcpy(tmp_hdr, skb->nh.raw, hlen);
        1.3.2 加入分片头部
575                 __skb_pull(skb, hlen);
576         fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
        1.3.3 原头部放回
577                 skb->nh.raw = __skb_push(skb, hlen);
578                 memcpy(skb->nh.raw, tmp_hdr, hlen); 
        1.3.4 设置分片头部
580                 ipv6_select_ident(skb, fh);
581                 fh->nexthdr = nexthdr;
582                 fh->reserved = 0;
583                 fh->frag_off = htons(IP6_MF);
584                 frag_id = fh->identification;
585 
586                 first_len = skb_pagelen(skb);
587                 skb->data_len = first_len - skb_headlen(skb);
588                 skb->len = first_len;
589                 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr));
590  
     1.4 发送所有分片
592                 for (;;) {
593                         /* Prepare header of the next frame,
594                          * before previous one went down. */
595                         if (frag) {
        1.4.1 设置个分段数据包头部
596                                 frag->ip_summed = CHECKSUM_NONE;
597                                 frag->h.raw = frag->data;
598                                 fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
599                                 frag->nh.raw = __skb_push(frag, hlen);
600                                 memcpy(frag->nh.raw, tmp_hdr, hlen);
601                                 offset += skb->len - hlen - sizeof(struct frag_hdr);
602                                 fh->nexthdr = nexthdr;
603                                 fh->reserved = 0;
604                                 fh->frag_off = htons(offset);
605                                 if (frag->next != NULL)
606                                         fh->frag_off |= htons(IP6_MF);
607                                 fh->identification = frag_id;
608                                 frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
609                                 ip6_copy_metadata(frag, skb);
610                         }
        1.4.2 发送数据报
612                         err = output(skb);
613                         if (err || !frag)
614                                 break;
615 
616                         skb = frag;
617                         frag = skb->next;
618                         skb->next = NULL;
619                 }
620 
621                 if (tmp_hdr)
622                         kfree(tmp_hdr);
623 
624                 if (err == 0) {
625                         IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
626                         return 0;
627                 }
        1.4.3 释放节点
629                 while (frag) {
630                         skb = frag->next;
631                         kfree_skb(frag);
632                         frag = skb;
633                 }
634 
635                 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
636                 return err;
637         }
2 慢分片
639 slow_path:
640         left = skb->len - hlen;         /* Space per frame */
641         ptr = hlen;                     /* Where to start from */
642 
643         /*
644          *      Fragment the datagram.
645          */
646 
647         *prevhdr = NEXTHDR_FRAGMENT;
648 
649         /*
650          *      Keep copying data until we run out.
651          */
652         while(left > 0) {
     2.1 分片
          2.1.1 设置分片长度
653                 len = left;
654                 /* IF: it doesn't fit, use 'mtu' - the data space left */
655                 if (len > mtu)
656                         len = mtu;
657                 /* IF: we are not sending upto and including the packet end
658                    then align the next start on an eight byte boundary */
659                 if (len < left) {
660                         len &= ~7;
661                 }
662                 /*
663                  *      Allocate buffer.
664                  */
          2.1.2 分配分片数据报空间
665 
666                 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
667                         NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n"));
668                         IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
669                         err = -ENOMEM;
670                         goto fail;
671                 }
672 
673                 /*
674                  *      Set up data on packet
675                  */
676 
          2.1.3 初始化数据包结构
677                 ip6_copy_metadata(frag, skb);
678                 skb_reserve(frag, LL_RESERVED_SPACE(rt->u.dst.dev));
679                 skb_put(frag, len + hlen + sizeof(struct frag_hdr));
680                 frag->nh.raw = frag->data;
681                 fh = (struct frag_hdr*)(frag->data + hlen);
682                 frag->h.raw = frag->data + hlen + sizeof(struct frag_hdr);
683 
684                 /*
685                  *      Charge the memory for the fragment to any owner
686                  *      it might possess
687                  */
688                 if (skb->sk)
689                         skb_set_owner_w(frag, skb->sk);
690 
691                 /*
692                  *      Copy the packet header into the new buffer.
693                  */
          2.1.4 设置数据包内容
694                 memcpy(frag->nh.raw, skb->data, hlen);  //拷贝数据报头
695 
696                 /*
697                  *      Build fragment header.
698                  */
699                 fh->nexthdr = nexthdr;
700                 fh->reserved = 0;
701                 if (frag_id) {
702                         ipv6_select_ident(skb, fh);
703                         frag_id = fh->identification;
704                 } else
705                         fh->identification = frag_id;
706 
707                 /*
708                  *      Copy a block of the IP datagram.
709                  */
710                 if (skb_copy_bits(skb, ptr, frag->h.raw, len)) //拷贝数据
711                         BUG();
712                 left -= len;
713 
714                 fh->frag_off = htons(offset);
715                 if (left > 0)
716                         fh->frag_off |= htons(IP6_MF);
717                 frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
718 
719                 ptr += len;
720                 offset += len;
721 
722                 /*
723                  *      Put this fragment into the sending queue.
724                  */
725 
726                 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
727 

     2.2 发送
728                 err = output(frag);
729                 if (err)
730                         goto fail;
731         }
732         kfree_skb(skb);
733         IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
734         return err;
735 
736 fail:
737         kfree_skb(skb); 
738         IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
739         return err;
740 }

 

0
0
分享到:
评论

相关推荐

    IPv6分片报文

    IPv6分片报文,研究 IPv6协议扩展头部的时候可以使用。

    Linux内核处理IPv6报文的重复分片存在的问题及解决对策.pdf

    然而,Linux内核在处理IPv6分片报文时,尤其是在处理重复分片方面,存在一些问题。 Linux内核的IPv6分片重组模块主要涉及以下几个关键功能: 1. `ip6qhashfn`函数:此函数用于根据分片ID、源和目的IP地址创建一个...

    IPv6分片重组在Snort中的解决方案

    IPv6分片攻击指的是攻击者利用IPv6协议中分片机制的特点,对网络中的数据包进行恶意的分片处理,然后再传输到目标主机。在目标主机重组这些分片数据包的过程中,可能会遭受攻击,例如资源耗尽、逻辑错误导致的系统...

    5G网优案例:传输IPV6分片报文Reserved字段校验不通过导致VONR呼叫失败.docx

    ### 5G网络优化案例分析:传输IPV6分片报文Reserved字段校验问题 #### 背景概述 随着5G网络在全球范围内的普及和VoNR(Voice over New Radio)技术的大规模商用,运营商面临着诸多挑战。其中一项关键挑战就是确保...

    ipv6_pcap.rar

    学习ipv6协议用到的一些有用的数据包,其中有tcp udp 数据包,分片数据包,http数据包等,对学习ipv6有很大帮助

    IPv6相关的RFC

    3. **RFC 5722**:更新了IPv6分片的处理方式,解决了重叠碎片可能导致的安全和实现复杂性问题。 4. **RFC 6437**:对IPv6流标签进行了详细定义,流标签用于标识具有特定服务质量需求的数据流。 5. **RFC 6564**:...

    路由的配置ipv6静态路由

    - **MTU问题**:如果接口的Maximum Transmission Unit (MTU)设置不正确,可能导致IPv6分片出现问题,从而阻止通信。可以检查并调整所有相关接口的MTU值。 - **路由配置错误**:虽然静态路由显示在路由表中,但可能...

    第三章作业1

    【知识点详解】 1. IPv6 地址结构与表示: ...综上所述,这个作业涉及的知识点涵盖了IPv6的地址表示、数据报结构、分片机制、源路由选择以及网络诊断工具的应用,这些都是网络协议和网络架构中的基础概念。

    ipv6 UDP pcap数据包 ipv6 pcap数据包

    ipv6 UDP pcap数据包 ipv6 pcap数据包 共大家参考是什么样子的,另外可以看下 ipv6的地址如何配置的。

    IPv4与IPv6业务-IP虚拟分片重组技术介绍.pdf

    2. Overlapping Fragment攻击:当设备接收到完全相同的分片报文,或者分片报文与前一分片或后一分片有重叠时,这可能表明正在进行Overlapping Fragment攻击。虚拟分片重组机制可以检测到这种情况,并采取相应的防护...

    Carrier IP - HCNA(H31-211)认证考试.docx

    2. **IPv6分片**: 问题2指出ICMPv6不用于分片操作。在IPv6中,与IPv4不同,数据包的分片通常由源节点完成,而不是由中间路由器进行,以减少网络拥塞并提高效率。 3. **IPv6中的广播**: 问题3说明IPv6不使用广播。在...

    ipv6协议详解和ipv6教程

    3. **更好的路由与分段**:IPv6不再支持IP分片,而是由更上层的协议(如TCP或UDP)负责数据包的分段与重组,这降低了路由器的负担,也提高了网络性能。 4. **内置安全性**:IPv6支持IPsec(Internet Protocol ...

    IPv4与IPv6业务-IP虚拟分片重组技术介绍-D.docx

    - **应用场景**:IP虚拟分片重组技术广泛应用于数据中心、企业网络、电信运营商网络等多种场景下,特别是在IPv4向IPv6迁移过程中,对于提升网络性能和加强网络安全具有重要意义。 - **优势**: - 提高网络传输效率...

    H3C IPV6基本配置

    这有助于优化网络性能,避免数据包分片。在H3C设备上,PMTU的配置可能涉及“ipv6 pmtu discover”命令,以启用PMTU发现功能。 此外,IPv6还引入了新的协议ICMPv6(Internet Control Message Protocol for IPv6),...

    IPv6技术基础PPT

    IPv6的基础协议主要涉及地址结构、报文头部格式和分片重组。IPv6地址长度为128位,采用冒号十六进制表示法,通常分为8个16位的段。报文头部相比IPv4更为简洁,减少了选项字段,以提高处理效率。此外,IPv6不再支持...

    IPv6相关中文RFC

    这是最权威的IPv6规范,详细定义了IPv6协议的各个方面,包括地址结构、报文格式、报文头选项、邻居发现、路径MTU发现、分片与重组、ICMPv6(互联网控制消息协议第六版)等。 5. **RFC2893**:《IPv6过渡技术:隧道...

    IPv6之二:IPv6简介与协议入门(下) IPv6之二:IPv6简介与协议入门(下)

    IPv6的头部比IPv4简洁,但它支持可选的扩展报头,如分片报头、认证报头、封装安全负载报头等,增强了网络功能和安全性。 六、IPv6的连接与安全 IPv6原生支持IPsec,可以提供数据包的加密和验证,提升了网络通信的...

    CCIE 400 101 考试大纲

    - 解释IP操作原理,包括ICMP不可达、重定向、IPv4选项、IPv6扩展头、IPv4与IPv6分片、TTL和IP MTU。 #### TCP协议操作 - 解释TCP操作原理,包括最大段大小(MSS)、IPv4和IPv6 PMTU、带宽延迟乘积、延迟、窗口大小...

    ccie路由交换大纲

    - **IPv4与IPv6分片**:阐述IPv4和IPv6分片机制的工作原理。 - **TTL (Time To Live)**:解释TTL字段的作用及其实现机制。 - **IP MTU (Maximum Transmission Unit)**:探讨最大传输单元的概念及其在网络通信中的...

    ipv6基础知识介绍

    默认情况下,IPv6的最大传输单元为1280字节,这意味着所有IPv6报文的负载长度不应超过这个值,以避免在网络中进行分片操作。 #### 六、流标签 流标签字段用于标识一组具有相同源和目的地址的报文,通常用于需要...

Global site tag (gtag.js) - Google Analytics