예제 #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">A <see cref="ByteArraySegment" /></param>
        /// <param name="parentPacket">The parent packet.</param>
        public GrePacket(ByteArraySegment byteArraySegment, Packet parentPacket)
        {
            // slice off the header portion
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = GreFields.FlagsLength + GreFields.ProtocolLength
            };

            if (HasCheckSum)
            {
                Header.Length += GreFields.ChecksumLength;
            }

            if (HasReserved)
            {
                Header.Length += GreFields.ReservedLength;
            }

            if (HasKey)
            {
                Header.Length += GreFields.KeyLength;
            }

            if (HasSequence)
            {
                Header.Length += GreFields.SequenceLength;
            }

            // parse the encapsulated bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() => EthernetPacket.ParseNextSegment(Header, Protocol));
            ParentPacket        = parentPacket;
        }
예제 #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public IPv6Packet(ByteArraySegment byteArraySegment)
        {
            Log.Debug(byteArraySegment.ToString());

            // IPv6 headers have a fixed length.
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = IPv6Fields.HeaderLength
            };
            ParseExtensionHeaders();

            Log.DebugFormat("PayloadLength: {0}", PayloadLength);

            if (PayloadLength > 0)
            {
                // parse the payload
                PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
                {
                    var startingOffset = Header.Offset + Header.Length;
                    var segmentLength  = Math.Min(PayloadLength, Header.BytesLength - startingOffset);
                    var bytesLength    = startingOffset + segmentLength;

                    var payload = new ByteArraySegment(Header.Bytes, startingOffset, segmentLength, bytesLength);

                    return(ParseNextSegment(payload,
                                            Protocol,
                                            this));
                });
            }
        }
예제 #3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public UdpPacket(ByteArraySegment byteArraySegment)
        {
            Log.DebugFormat("ByteArraySegment {0}", byteArraySegment);

            // set the header field, header field values are retrieved from this byte array
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = UdpFields.HeaderLength
            };

            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                const int wakeOnLanPort0 = 0;
                const int wakeOnLanPort7 = 7;
                const int wakeOnLanPort9 = 9;
                const int l2TpPort       = 1701;
                const int teredoPort     = 3544;

                var result          = new PacketOrByteArraySegment();
                var destinationPort = DestinationPort;
                var sourcePort      = SourcePort;
                var payload         = Header.NextSegment();

                // If this packet is going to port 0, 7 or 9, then it might be a WakeOnLan packet.
                if ((destinationPort == wakeOnLanPort0) || (destinationPort == wakeOnLanPort7) || (destinationPort == wakeOnLanPort9))
                {
                    if (WakeOnLanPacket.IsValid(payload))
                    {
                        result.Packet = new WakeOnLanPacket(payload);
                        return(result);
                    }
                }

                if ((destinationPort == l2TpPort) || (sourcePort == l2TpPort))
                {
                    result.Packet = new L2tpPacket(payload, this);
                    return(result);
                }

                // Teredo encapsulates IPv6 traffic into UDP packets, parse out the bytes in the payload into packets.
                // If it contains a IPV6 packet, it to this current packet as a payload.
                // https://tools.ietf.org/html/rfc4380#section-5.1.1
                if ((destinationPort == teredoPort) || (sourcePort == teredoPort))
                {
                    if (ContainsIPv6Packet(payload))
                    {
                        result.Packet = new IPv6Packet(payload);
                        return(result);
                    }
                }

                // store the payload bytes
                result.ByteArraySegment = payload;
                return(result);
            });
        }
예제 #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public LinuxSllPacket(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = LinuxSllFields.SLLHeaderLength
            };

            // parse the payload via an EthernetPacket method
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() => EthernetPacket.ParseNextSegment(Header,
                                                                                                                EthernetProtocolType));
        }
예제 #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public NullPacket(ByteArraySegment byteArraySegment)
        {
            Log.Debug("");

            // slice off the header portion as our header
            // ReSharper disable once UseObjectOrCollectionInitializer
            Header        = new ByteArraySegment(byteArraySegment);
            Header.Length = NullFields.HeaderLength;

            // parse the encapsulated bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() => ParseNextSegment(Header, Protocol));
        }
예제 #6
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public Ieee8021QPacket(ByteArraySegment byteArraySegment)
        {
            // set the header field, header field values are retrieved from this byte array
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = Ieee8021QFields.HeaderLength
            };

            // parse the payload via an EthernetPacket method
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() => EthernetPacket.ParseNextSegment(Header,
                                                                                                                Type));
        }
예제 #7
0
#pragma warning restore 0169, 0649
#endif

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public IcmpV4Packet(ByteArraySegment byteArraySegment)
        {
            Log.Debug("");

            // ReSharper disable once UseObjectOrCollectionInitializer
            Header        = new ByteArraySegment(byteArraySegment);
            Header.Length = IcmpV4Fields.HeaderLength;

            // store the payload bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() => new PacketOrByteArraySegment {
                ByteArraySegment = Header.NextSegment()
            });
        }
예제 #8
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment"></param>
        public DrdaPacket(ByteArraySegment byteArraySegment)
        {
            Log.Debug("");

            // set the header field, header field values are retrieved from this byte array
            Header = new ByteArraySegment(byteArraySegment);

            // store the payload bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                var result = new PacketOrByteArraySegment {
                    ByteArraySegment = Header.NextSegment()
                };
                return(result);
            });
        }
예제 #9
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public IgmpV2Packet(ByteArraySegment byteArraySegment)
        {
            // set the header field, header field values are retrieved from this byte array
            // ReSharper disable once UseObjectOrCollectionInitializer
            Header        = new ByteArraySegment(byteArraySegment);
            Header.Length = UdpFields.HeaderLength;

            // store the payload bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                var result = new PacketOrByteArraySegment {
                    ByteArraySegment = Header.NextSegment()
                };
                return(result);
            });
        }
예제 #10
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public RawIPPacket(ByteArraySegment byteArraySegment)
        {
            // Pcap raw link layer format does not have any header
            // you need to identify whether you have ipv4 or ipv6
            // directly by checking the IP version number.
            // If the first nibble is 0x04, then you have IP v4
            // If the first nibble is 0x06, then you have IP v6
            // The RawIPPacketProtocol enum has been defined to match this.
            var firstNibble = byteArraySegment.Bytes[0] >> 4;

            Protocol = (RawIPPacketProtocol)firstNibble;

            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = 0
            };

            // parse the encapsulated bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                var result = new PacketOrByteArraySegment();
                switch (Protocol)
                {
                case RawIPPacketProtocol.IPv4:
                    {
                        result.Packet = new IPv4Packet(Header.NextSegment());
                        break;
                    }

                case RawIPPacketProtocol.IPv6:
                    {
                        result.Packet = new IPv6Packet(Header.NextSegment());
                        break;
                    }

                default:
                    {
                        throw new NotImplementedException("Protocol of " + Protocol + " is not implemented");
                    }
                }

                return(result);
            });
        }
예제 #11
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public TcpPacket(ByteArraySegment byteArraySegment)
        {
            Log.Debug("");

            // set the header field, header field values are retrieved from this byte array
            // ReSharper disable once UseObjectOrCollectionInitializer
            Header        = new ByteArraySegment(byteArraySegment);
            Header.Length = DataOffset * 4;

            // NOTE: we update the Length field AFTER the header field because
            // we need the header to be valid to retrieve the value of DataOffset

            // store the payload bytes
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                var result = new PacketOrByteArraySegment {
                    ByteArraySegment = Header.NextSegment()
                };
                return(result);
            });
        }
예제 #12
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public IPv4Packet(ByteArraySegment byteArraySegment)
        {
            Log.Debug("");

            Header = new ByteArraySegment(byteArraySegment);

            // TCP offload engine (TOE), see http://en.wikipedia.org/wiki/TCP_offload_engine
            var totalLength = TotalLength;

            if (totalLength == 0)
            {
                totalLength = Header.Length;
                TotalLength = totalLength;
            }

            // Check that the TotalLength is valid, at least HeaderMinimumLength long
            if (totalLength < HeaderMinimumLength)
            {
                ThrowHelper.ThrowInvalidOperationException(ExceptionDescription.TotalLengthBelowMinimumHeaderLength);
            }

            // update the header length with the correct value
            // NOTE: we take care to convert from 32-bit words into bytes
            // NOTE: we do this *after* setting header because we need header to be valid
            //       before we can retrieve the HeaderLength property
            Header.Length = HeaderLength * 4;

            Log.DebugFormat("IPv4Packet HeaderLength {0}", HeaderLength);
            Log.DebugFormat("header {0}", Header);

            // parse the payload
            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                var payload = Header.NextSegment(PayloadLength);
                return(ParseNextSegment(payload,
                                        Protocol,
                                        this));
            });
        }
예제 #13
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public UdpPacket(ByteArraySegment byteArraySegment)
        {
            Log.DebugFormat("ByteArraySegment {0}", byteArraySegment);

            // set the header field, header field values are retrieved from this byte array
            Header = new ByteArraySegment(byteArraySegment)
            {
                Length = UdpFields.HeaderLength
            };

            PayloadPacketOrData = new LazySlim <PacketOrByteArraySegment>(() =>
            {
                const int wakeOnLanPort0 = 0;
                const int wakeOnLanPort7 = 7;
                const int wakeOnLanPort9 = 9;

                var result          = new PacketOrByteArraySegment();
                var destinationPort = DestinationPort;
                var sourcePort      = SourcePort;
                var payload         = Header.NextSegment();

                // If this packet is going to port 0, 7 or 9, then it might be a WakeOnLan packet.
                if (destinationPort == wakeOnLanPort0 || destinationPort == wakeOnLanPort7 || destinationPort == wakeOnLanPort9)
                {
                    if (WakeOnLanPacket.IsValid(payload))
                    {
                        result.Packet = new WakeOnLanPacket(payload);
                        return(result);
                    }
                }

                if (destinationPort == L2tpFields.Port || sourcePort == L2tpFields.Port)
                {
                    result.Packet = new L2tpPacket(payload, this);
                    return(result);
                }

                if ((sourcePort == DhcpV4Fields.ClientPort || sourcePort == DhcpV4Fields.ServerPort) &&
                    (destinationPort == DhcpV4Fields.ClientPort || destinationPort == DhcpV4Fields.ServerPort))
                {
                    var nextSegmentLength = byteArraySegment.Length - Header.Length;
                    if (nextSegmentLength >= DhcpV4Fields.MinimumSize)
                    {
                        var nextSegment = new ByteArraySegment(byteArraySegment.Bytes, byteArraySegment.Offset + Header.Length, nextSegmentLength);

                        var magicNumber = EndianBitConverter.Big.ToUInt32(nextSegment.Bytes, nextSegment.Offset + DhcpV4Fields.MagicNumberPosition);
                        if (magicNumber == DhcpV4Fields.MagicNumber)
                        {
                            result.Packet = new DhcpV4Packet(nextSegment, this);
                            return(result);
                        }
                    }
                }

                // Teredo encapsulates IPv6 traffic into UDP packets, parse out the bytes in the payload into packets.
                // If it contains a IPV6 packet, it to this current packet as a payload.
                // https://tools.ietf.org/html/rfc4380#section-5.1.1
                if (destinationPort == IPv6Fields.TeredoPort || sourcePort == IPv6Fields.TeredoPort)
                {
                    if (ContainsIPv6Packet(payload))
                    {
                        result.Packet = new IPv6Packet(payload);
                        return(result);
                    }
                }

                // store the payload bytes
                result.ByteArraySegment = payload;
                return(result);
            });
        }