Esempio n. 1
0
        private static Boolean ParseNetworkLayer(ReadOnlySpan <Byte> networkData,
                                                 EthernetPacketType ethernetProtocol,
                                                 out ReadOnlySpan <Byte> transportData,
                                                 out IPProtocolType ipProtocol,
                                                 out IPAddress sourceIpAddress,
                                                 out IPAddress destinationIpAddress,
                                                 out IPFragmentSignature ipv4FragmentSignature)
        {
            transportData         = ReadOnlySpan <Byte> .Empty;
            ipProtocol            = IPProtocolType.NONE;
            sourceIpAddress       = IPAddress.None;
            destinationIpAddress  = IPAddress.None;
            ipv4FragmentSignature = null;

            switch (ethernetProtocol)
            {
            case EthernetPacketType.IPv4:
                return(ParseNetworkIpv4Layer(networkData, ref transportData, ref ipProtocol, ref sourceIpAddress, ref destinationIpAddress, ref ipv4FragmentSignature));

            case EthernetPacketType.IPv6:
                return(ParseNetworkIpv6Layer(networkData, ref transportData, ref ipProtocol, ref sourceIpAddress, ref destinationIpAddress));

            default:
                return(false);
            }
        }
Esempio n. 2
0
        private static Boolean ParseNetworkIpv4Layer(ReadOnlySpan <Byte> networkData,
                                                     ref ReadOnlySpan <Byte> transportData,
                                                     ref IPProtocolType ipProtocol,
                                                     ref IPAddress sourceIpAddress,
                                                     ref IPAddress destinationIpAddress,
                                                     ref IPFragmentSignature ipv4FragmentSignature)
        {
            // Min ipv4 header size
            if (networkData.Length < 20)
            {
                return(false);
            }

            ipProtocol = (IPProtocolType)networkData[IPv4Fields.ProtocolPosition];

            sourceIpAddress      = new IPAddress(networkData.Slice(IPv4Fields.SourcePosition, 4));
            destinationIpAddress = new IPAddress(networkData.Slice(IPv4Fields.DestinationPosition, 4));

            var headerLen = (networkData[0] & 0x0F) * 4;
            var totalLen  =
                BinaryPrimitives.ReadUInt16BigEndian(networkData.Slice(IPv4Fields.TotalLengthPosition, IPv4Fields.TotalLengthLength));

            transportData = networkData.Slice(headerLen, totalLen - headerLen);


            var moreFragments  = (networkData[IPv4Fields.FragmentOffsetAndFlagsPosition] & 0b00100000) != 0;
            var fragmentOffset = ((networkData[IPv4Fields.FragmentOffsetAndFlagsPosition] & 0b00011111) << 8) |
                                 networkData[IPv4Fields.FragmentOffsetAndFlagsPosition + 1];
            var identification     = BinaryPrimitives.ReadUInt16BigEndian(networkData.Slice(IPv4Fields.IdPosition, 2));
            var packetIsFragmented = moreFragments || fragmentOffset > 0;

            if (packetIsFragmented)
            {
                ipv4FragmentSignature = new IPFragmentSignature(sourceIpAddress, destinationIpAddress, ipProtocol, identification, moreFragments, fragmentOffset);
            }

            return(true);
        }
Esempio n. 3
0
        public static Boolean ExtractRawPacketSignature(RawPacket rawPacket,
                                                        out IPAddress sourceIpAddress,
                                                        out IPAddress destinationIpAddress,
                                                        out UInt16 sourcePort,
                                                        out UInt16 destinationPort,
                                                        out IPProtocolType ipProtocol,
                                                        out IPFragmentSignature ipv4FragmentSignature)
        {
            sourceIpAddress       = destinationIpAddress = IPAddress.None;
            sourcePort            = destinationPort = 0;
            ipProtocol            = IPProtocolType.NONE;
            ipv4FragmentSignature = null;

            if (!ParseLinkLayer(rawPacket.RawPacketData, rawPacket.LinkType, out var networkData, out var ethernetProtocol))
            {
                return(false);
            }

            if (!ParseNetworkLayer(networkData, ethernetProtocol, out var transportData,
                                   out ipProtocol, out sourceIpAddress, out destinationIpAddress, out ipv4FragmentSignature))
            {
                return(false);
            }

            // Don't continue with parsing of a transport layer, if the current packet is fragmented and this fragment is not the initial one (containing transport header)
            if (ipv4FragmentSignature != null && ipv4FragmentSignature.FragmentOffset > 0)
            {
                return(true);
            }

            if (!ParseTransportLayer(transportData, ipProtocol, out sourcePort, out destinationPort))
            {
                return(false);
            }

            return(true);
        }