1
votes

So i found this solution for IpV4:

private IEnumerable<Packet> SplitPacket(Packet packet, int numberOfFragments)
{
    IpV4Datagram ipV4Datagram = packet.Ethernet.IpV4;

    if (ipV4Datagram.Protocol == IpV4Protocol.Tcp || ipV4Datagram.Protocol == IpV4Protocol.Udp)
    {
        EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
        ILayer layer = packet.Ethernet.IpV4.ExtractLayer();
        IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
        ipV4Layer.HeaderChecksum = null;
        DateTime packetTimestamp = packet.Timestamp;
        PayloadLayer payload = (PayloadLayer)packet.Ethernet.IpV4.Payload.ExtractLayer(); //extract the data
        int totalLength = payload.Length;
        int partialLength = totalLength / numberOfFragments; //split data into smaller segments
        partialLength = (partialLength / 8) * 8; //make sure it's divisible with 8
        if (partialLength == 0)
            partialLength = 8;
        //(http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly)
        ushort offset = 0; //send one by one

        while (offset < totalLength)
        {
            int fragmentLength = partialLength; //get length for this fragment
            IpV4FragmentationOptions options = IpV4FragmentationOptions.MoreFragments;

            if (offset + fragmentLength >= totalLength) //is this the last fragment ? trim length if needed
            {
                options = IpV4FragmentationOptions.None;
                fragmentLength = totalLength - offset;
            }

            byte[] newBuffer = ipV4Datagram.Payload.ToArray(); //copy the actual data into a new buffer
            PayloadLayer newPayload = new PayloadLayer { Data = new Datagram(newBuffer, offset, fragmentLength) };
            ipV4Layer.Fragmentation = new IpV4Fragmentation(options, offset); //change IP layer fragmentation options
            Packet newPacket = null;

            if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp)
            {
                TcpLayer tcpLayer = (TcpLayer)packet.Ethernet.IpV4.Tcp.ExtractLayer();
                tcpLayer.Checksum = null;
                newPacket = PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, tcpLayer, newPayload);
            }
            else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
            {
                UdpLayer udpLayer = (UdpLayer)packet.Ethernet.IpV4.Udp.ExtractLayer();
                udpLayer.Checksum = null;
                newPacket = PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, udpLayer, newPayload);
            }

            yield return newPacket;
            //yield return PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, tcpLayer, newPayload); //return
            offset += (ushort)fragmentLength; //next offset
        }
    }
}

And since Ipv6Layer does not contain several fields like in IpV4layer for example IpV4FragmentationOptions i wonder how Fragmentation is implemented over IpV6

1

1 Answers

0
votes

From Wikipedia:

Fragmentation

Unlike in IPv4, IPv6 routers never fragment IPv6 packets. Packets exceeding the size of the maximum transmission unit of the destination link are dropped and this condition is signaled by a Packet too Big ICMPv6 type 2 message to the originating node, similarly to the IPv4 method when the Don't Fragment bit is set.

End nodes in IPv6 are expected to perform path MTU discovery to determine the maximum size of packets to send, and the upper-layer protocol is expected to limit the payload size. However, if the upper-layer protocol is unable to do so, the sending host may use the Fragment extension header in order to perform end-to-end fragmentation of IPv6 packets. Any data link layer conveying IPv6 data must be capable of delivering an IP packet containing 1280 bytes without the need to invoke end-to-end fragmentation at the IP layer.

Fragmenting

A packet containing a fragment of an original (larger) packet consists of two parts: the unfragmentable part of the original packet (which is the same for all fragments), and a piece of the fragmentable part of the original packet, identified by a Fragment Offset. The Fragment Offset of the first ("leftmost") fragment is 0.

The unfragmentable part of a packet consists of the fixed header and some of the extension headers of the original packet (if present): all extension headers up to and including the Routing extension header, or else the Hop-by-Hop extension header. If neither extension headers are present, the unfragmentable part is just the fixed header.

The Next Header value of the last (extension) header of the unfragmentable part is set to 44 to indicate that a Fragment extension header follows. After the Fragment extension header a fragment of the rest of the original packet follows.

The first fragment(s) hold the rest of the extension headers (if present). After that the rest of the payload follows. Each fragment is a multiple of 8 octets in length, except the last fragment.

Each Fragment extension header has its M flag set to 1 (indicating more fragments follow), except the last, whose flag is set to 0.

Reassembly

The original packet is reassembled by the receiving node by collecting all fragments and placing each fragment at the right offset and discarding the Fragment extension headers of the packets that carried them. Packets containing fragments need not arrive in sequence; they will be rearranged by the receiving node.

If not all fragments are received within 60 seconds after receiving the first packet with a fragment, reassembly of the original packet is abandoned and all fragments are discarded. If the first fragment was received (which contains the fixed header), a Time Exceeded message (ICMPv6 type 3, code 1) is returned to the node originating the fragmented packet, if the packet was discarded for this reason.

Receiving hosts must make a best-effort attempt to reassemble fragmented IP datagrams that, after reassembly, contain up to 1500 bytes. Hosts are permitted to make an attempt to reassemble fragmented datagrams larger than 1500 bytes, but they are also permitted to silently discard any datagram after it becomes apparent that the reassembled packet would be larger than 1500 bytes. Therefore, senders should avoid sending fragmented IP datagrams with a total reassembled size larger than 1500 bytes, unless they have previous assurance that the receiver is capable of reassembling such large datagrams.

Security

Research has shown that the use of fragmentation can be leveraged to evade network security controls. As a result, RFC 7112 requires that the first fragment of an IPv6 packet contains the entire IPv6 header chain, such that some very pathological fragmentation cases are forbidden. Additionally, as a result of research on the evasion of RA-Guard in RFC 7113, RFC 6980 has deprecated the use of fragmentation with Neighbor Discovery, and discouraged the use of fragmentation with Secure Neighbor Discovery (SEND).