public static IpPacket Parse()

in Source/Tx.Network/Ip/PacketParser.cs [80:172]


        public static IpPacket Parse(
            DateTimeOffset receivedTime, 
            bool reuseOriginalBuffer,
            byte[] packetBytes, 
            int offset, 
            int packetBytesLength)
        {
            if (packetBytes == null)
            {
                throw new ArgumentNullException("packetBytes");
            }

            var ipVers = packetBytes.ReadBits(offset, 0, 4);                    //bits 0 to 3
            if (ipVers != 4) throw new NotSupportedException("IPv4 only currently supported"); //ensure this is v4

            var internetHeaderLength = packetBytes.ReadBits(offset++, 4, 4);        //bits 4 to 7
            var dscpValue = packetBytes.ReadBits(offset, 0, 6);                     //8 to 13
            var explicitCongestionNotice = packetBytes.ReadBits(offset++, 6, 2);    //14 to 15
            var ipPacketLength = packetBytes.ReadNetOrderUShort(offset);            //16 to 31
            offset += 2;
            var fragmentGroupId = packetBytes.ReadNetOrderUShort(offset);           //32 to 47
            offset += 2;
            var ipHeaderFlags = packetBytes.ReadBits(offset, 0, 3);                 //48 to 50
            var fragmentOffset = packetBytes.ReadNetOrderUShort(offset, 3, 13);     //51 to 63
            offset += 2;
            var timeToLive = packetBytes[offset++];                                 //64 to 71
            var protocolNumber = packetBytes[offset++];                             //72 to 79
            var protocol = (ProtocolType)protocolNumber;                            //Enum
            var packetHeaderChecksum = packetBytes.ReadNetOrderUShort(offset);      //80 to 95
            offset += 2;
            var sourceIpAddress = packetBytes.ReadIpAddress(offset);                //96 to 127
            offset += 4;
            var destinationIpAddress = packetBytes.ReadIpAddress(offset);           //128 to 160
            offset += 4;

            var ipOptions = default(ArraySegment<byte>);
            if (internetHeaderLength > 5) //161 and up
            {
                int length = (internetHeaderLength - 5) * 4;

                if (reuseOriginalBuffer)
                {
                    ipOptions = new ArraySegment<byte>(packetBytes, offset, length);
                }
                else
                {
                    var ipOptionsDataArray = new byte[length];
                    Array.Copy(packetBytes, offset, ipOptionsDataArray, 0, length);
                    ipOptions = new ArraySegment<byte>(ipOptionsDataArray);
                }
                offset += length;
            }

            var packetData = default(ArraySegment<byte>);

            //IpHeader in bytes is 4*IHL bytes long
            if (ipPacketLength > 4 * internetHeaderLength)
            {
                int length = ipPacketLength - (internetHeaderLength * 4);

                if (reuseOriginalBuffer)
                {
                    packetData = new ArraySegment<byte>(packetBytes, offset, length);
                }
                else
                {
                    var packetDataArray = new byte[length];
                    Array.Copy(packetBytes, offset, packetDataArray, 0, length);
                    packetData = new ArraySegment<byte>(packetDataArray);
                }
            }

            return new IpPacket
            {
                PacketHeader = new IpPacketHeader(
                    sourceIpAddress,
                    destinationIpAddress,
                    false,
                    internetHeaderLength,
                    dscpValue,
                    explicitCongestionNotice,
                    ipPacketLength,
                    fragmentGroupId,
                    ipHeaderFlags,
                    fragmentOffset,
                    timeToLive,
                    packetHeaderChecksum),
                IpOptions = ipOptions,
                ReceivedTime = receivedTime,
                ProtocolType = protocol,
                PacketData = packetData
            };
        }