Exemple #1
0
        private static PacketCommunicator OpenOfflineDevice(int numPackets, Packet packet, TimeSpan intervalBetweenPackets, string dumpFilename, string readFilename = null)
        {
            IPacketDevice      device       = GetOfflineDevice(numPackets, packet, intervalBetweenPackets, dumpFilename, readFilename);
            PacketCommunicator communicator = device.Open();

            try
            {
                MoreAssert.AreSequenceEqual(new[] { DataLinkKind.Ethernet }.Select(kind => new PcapDataLink(kind)), communicator.SupportedDataLinks);
                Assert.AreEqual(DataLinkKind.Ethernet, communicator.DataLink.Kind);
                Assert.AreEqual("EN10MB (Ethernet)", communicator.DataLink.ToString());
                Assert.AreEqual(communicator.DataLink, new PcapDataLink(communicator.DataLink.Name));
                Assert.IsTrue(communicator.IsFileSystemByteOrder);
                Assert.AreEqual(PacketCommunicatorMode.Capture, communicator.Mode);
                Assert.IsFalse(communicator.NonBlocking);
                Assert.AreEqual(PacketDevice.DefaultSnapshotLength, communicator.SnapshotLength);
                Assert.AreEqual(2, communicator.FileMajorVersion);
                Assert.AreEqual(4, communicator.FileMinorVersion);
                return(communicator);
            }
            catch (Exception)
            {
                communicator.Dispose();
                throw;
            }
        }
Exemple #2
0
        private static void CompareIpV4Options(XElement element, IpV4Options options)
        {
            int currentOptionIndex = 0;

            foreach (var field in element.Fields())
            {
                if (currentOptionIndex >= options.Count)
                {
                    Assert.IsFalse(options.IsValid);
                    Assert.IsTrue(field.Show() == "Commercial IP security option" ||
                                  field.Show() == "Loose source route (length byte past end of options)" ||
                                  field.Show() == "Time stamp:" ||
                                  field.Show().StartsWith("Unknown") ||
                                  field.Show().StartsWith("Security") ||
                                  field.Show().StartsWith("Router Alert (with option length = ") ||
                                  field.Show().StartsWith("Stream identifier (with option length = ") ||
                                  field.Show().Contains("with too") ||
                                  field.Show().Contains(" bytes says option goes past end of options") ||
                                  field.Show().Contains("(length byte past end of options)") ||
                                  XElementExtensions.Show(field.Fields().First()).StartsWith("Pointer: ") && XElementExtensions.Show(field.Fields().First()).EndsWith(" (points to middle of address)") ||
                                  field.Fields().Where(value => value.Show() == "(suboption would go past end of option)").Count() != 0, field.Show());
                    break;
                }
                IpV4Option option = options[currentOptionIndex++];
                if (option.OptionType == IpV4OptionType.BasicSecurity ||
                    option.OptionType == IpV4OptionType.TraceRoute)
                {
                    Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString()));
                    continue; // Wireshark doesn't support
                }
                field.AssertShow(option.GetWiresharkString());

                if ((option is IpV4OptionUnknown))
                {
                    continue;
                }

                var optionShows = from f in field.Fields() select f.Show();

                MoreAssert.AreSequenceEqual(optionShows, option.GetWiresharkSubfieldStrings());
            }
        }
Exemple #3
0
        public static PacketCommunicator OpenLiveDevice()
        {
            NetworkInterface networkInterface =
                NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(
                    ni => !ni.IsReceiveOnly && ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet && ni.OperationalStatus == OperationalStatus.Up);
            LivePacketDevice device = networkInterface.GetLivePacketDevice();

            MoreAssert.IsMatch(@"Network adapter '.*' on local host", device.Description);
            Assert.AreEqual(DeviceAttributes.None, device.Attributes);
            Assert.AreNotEqual(MacAddress.Zero, device.GetMacAddress());
            Assert.AreNotEqual(string.Empty, device.GetPnpDeviceId());
            MoreAssert.IsBiggerOrEqual(1, device.Addresses.Count);
            foreach (DeviceAddress address in device.Addresses)
            {
                if (address.Address.Family == SocketAddressFamily.Internet)
                {
                    MoreAssert.IsMatch("Address: " + SocketAddressFamily.Internet + @" [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ " +
                                       "Netmask: " + SocketAddressFamily.Internet + @" 255\.[0-9]+\.[0-9]+\.[0-9]+ " +
                                       "Broadcast: " + SocketAddressFamily.Internet + @" 255.255.255.255",
                                       address.ToString());
                }
                else
                {
                    Assert.AreEqual(SocketAddressFamily.Internet6, address.Address.Family);
                    MoreAssert.IsMatch("Address: " + SocketAddressFamily.Internet6 + @" (?:[0-9A-F]{4}:){7}[0-9A-F]{4} " +
                                       "Netmask: " + SocketAddressFamily.Unspecified + @" " + IpV6Address.Zero + " " +
                                       "Broadcast: " + SocketAddressFamily.Unspecified + @" " + IpV6Address.Zero,
                                       address.ToString());
                }
            }

            PacketCommunicator communicator = device.Open();

            try
            {
                MoreAssert.AreSequenceEqual(new[] { DataLinkKind.Ethernet, DataLinkKind.Docsis }.Select(kind => new PcapDataLink(kind)), communicator.SupportedDataLinks);
                PacketTotalStatistics totalStatistics = communicator.TotalStatistics;
                Assert.AreEqual <object>(totalStatistics, totalStatistics);
                Assert.AreNotEqual(null, totalStatistics);
                Assert.AreEqual(totalStatistics.GetHashCode(), totalStatistics.GetHashCode());
                Assert.IsTrue(totalStatistics.Equals(totalStatistics));
                Assert.IsFalse(totalStatistics.Equals(null));
                Assert.AreNotEqual(null, totalStatistics);
                Assert.AreNotEqual(totalStatistics, 2);
                MoreAssert.IsSmallerOrEqual <uint>(1, totalStatistics.PacketsCaptured, "PacketsCaptured");
                Assert.AreEqual <uint>(0, totalStatistics.PacketsDroppedByDriver, "PacketsDroppedByDriver");
                Assert.AreEqual <uint>(0, totalStatistics.PacketsDroppedByInterface, "PacketsDroppedByInterface");
                MoreAssert.IsSmallerOrEqual <uint>(1, totalStatistics.PacketsReceived, "PacketsReceived");
                Assert.IsNotNull(totalStatistics.ToString());
                communicator.SetKernelBufferSize(2 * 1024 * 1024); // 2 MB instead of 1
                communicator.SetKernelMinimumBytesToCopy(10);      // 10 bytes minimum to copy
                communicator.SetSamplingMethod(new SamplingMethodNone());
                Assert.AreEqual(DataLinkKind.Ethernet, communicator.DataLink.Kind);
                communicator.DataLink = communicator.DataLink;
                Assert.AreEqual("EN10MB (Ethernet)", communicator.DataLink.ToString());
                Assert.AreEqual(communicator.DataLink, new PcapDataLink(communicator.DataLink.Name));
                Assert.IsTrue(communicator.IsFileSystemByteOrder);
                Assert.AreEqual(PacketCommunicatorMode.Capture, communicator.Mode);
                Assert.IsFalse(communicator.NonBlocking);
                Assert.AreEqual(PacketDevice.DefaultSnapshotLength, communicator.SnapshotLength);
                return(communicator);
            }
            catch (Exception)
            {
                communicator.Dispose();
                throw;
            }
        }
Exemple #4
0
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            HttpDatagram httpDatagram = (HttpDatagram)datagram;

            if (field.Name() == "data" || field.Name() == "data.data")
            {
                if (field.Name() == "data")
                {
                    field.AssertNoShow();
                }

                MoreAssert.AreSequenceEqual(httpDatagram.Subsegment(0, _data.Length / 2), HexEncoding.Instance.GetBytes(_data.ToString()));
                // TODO: Uncomment once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10707 is fixed.
//                field.AssertValue(httpDatagram.Subsegment(_data.Length / 2 + 2, httpDatagram.Length - _data.Length / 2 - 2));
                return(false);
            }

            string fieldShow = field.Show();
            string httpFieldName;

            switch (field.Name())
            {
            case "http.request":
                field.AssertShowDecimal(httpDatagram.IsRequest);
                break;

            case "http.response":
                field.AssertShowDecimal(httpDatagram.IsResponse);
                break;

            case "":
                if (fieldShow == "HTTP chunked response")
                {
                    throw new InvalidOperationException("HTTP chunked response");
                }
                if (fieldShow == @"\r\n" || fieldShow == "HTTP response 1/1" || fieldShow == "HTTP request 1/1")
                {
                    break;
                }

                _data.Append(field.Value());

                if (_isFirstEmptyName)
                {
                    CompareHttpFirstLine(field, httpDatagram);
                    _isFirstEmptyName = false;
                }
                else if (fieldShow.StartsWith("Content-encoded entity body"))
                {
                    break;
                }
                else
                {
                    fieldShow = EncodingExtensions.Iso88591.GetString(HexEncoding.Instance.GetBytes(field.Value()));
                    fieldShow = fieldShow.Substring(0, fieldShow.Length - 2);
                    int colonIndex = fieldShow.IndexOf(':');
                    MoreAssert.IsBiggerOrEqual(0, colonIndex, "Can't find colon in field with empty name");

                    if (httpDatagram.Header == null)
                    {
                        if (httpDatagram.IsRequest)
                        {
                            Assert.IsNull(httpDatagram.Version);
                        }
                        else
                        {
                            Assert.IsTrue(IsBadHttp(httpDatagram));
                        }
                        break;
                    }
                    httpFieldName = fieldShow.Substring(0, colonIndex);
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header[httpFieldName]);
                    }
                    else
                    {
                        string fieldValue         = fieldShow.Substring(colonIndex + 1).SkipWhile(c => c == ' ').TakeWhile(c => c != '\\').SequenceToString();
                        string expectedFieldValue = httpDatagram.Header[httpFieldName].ValueString;
                        Assert.IsTrue(expectedFieldValue.Contains(fieldValue),
                                      string.Format("{0} <{1}> doesn't contain <{2}>", field.Name(), expectedFieldValue, fieldValue));
                    }
                }
                break;

            case "data.len":
                field.AssertShowDecimal(httpDatagram.Length - _data.Length / 2);
                break;

            case "http.host":
            case "http.user_agent":
            case "http.accept":
            case "http.accept_language":
            case "http.accept_encoding":
            case "http.connection":
            case "http.cookie":
            case "http.cache_control":
            case "http.content_encoding":
            case "http.date":
            case "http.referer":
            case "http.last_modified":
            case "http.server":
            case "http.set_cookie":
            case "http.location":
                _data.Append(field.Value());
                httpFieldName = field.Name().Substring(5).Replace('_', '-');
                HttpField httpField = httpDatagram.Header[httpFieldName];
                if (!field.Value().EndsWith("0d0a"))
                {
                    Assert.IsNull(httpField);
                }
                else
                {
                    string fieldValue         = field.Show().Replace("\\\"", "\"");
                    string expectedFieldValue = httpField.ValueString;
                    Assert.IsTrue(expectedFieldValue.Contains(fieldValue),
                                  string.Format("{0} <{1}> doesn't contain <{2}>", field.Name(), expectedFieldValue, fieldValue));
                }
                break;

            case "http.content_length_header":
                _data.Append(field.Value());
                if (!IsBadHttp(httpDatagram))
                {
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header.ContentLength);
                    }
                    else
                    {
                        field.AssertShowDecimal(httpDatagram.Header.ContentLength.ContentLength.Value);
                    }
                }
                break;

            case "http.content_type":
                _data.Append(field.Value());
                string[] mediaType = fieldShow.Split(new[] { ';', ' ', '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (!IsBadHttp(httpDatagram))
                {
                    if (!field.Value().EndsWith("0d0a"))
                    {
                        Assert.IsNull(httpDatagram.Header.ContentType);
                    }
                    else
                    {
                        Assert.AreEqual(httpDatagram.Header.ContentType.MediaType, mediaType[0]);
                        Assert.AreEqual(httpDatagram.Header.ContentType.MediaSubtype, mediaType[1]);
                        int fieldShowParametersStart = fieldShow.IndexOf(';');
                        if (fieldShowParametersStart == -1)
                        {
                            Assert.IsFalse(httpDatagram.Header.ContentType.Parameters.Any());
                        }
                        else
                        {
                            string expected =
                                httpDatagram.Header.ContentType.Parameters.Select(pair => pair.Key + '=' + pair.Value.ToWiresharkLiteral()).
                                SequenceToString(';');
                            Assert.AreEqual(expected, fieldShow.Substring(fieldShowParametersStart + 1));
                        }
                    }
                }
                break;

            case "http.request.line":
            case "http.response.line":
                if (_data.ToString().EndsWith(field.Value()))
                {
                    break;
                }
                {
                    _data.Append(field.Value());
                }
                break;

            case "http.transfer_encoding":
                if (!IsBadHttp(httpDatagram))
                {
                    Assert.AreEqual(fieldShow.ToWiresharkLowerLiteral(),
                                    httpDatagram.Header.TransferEncoding.TransferCodings.SequenceToString(',').ToLowerInvariant().ToWiresharkLiteral());
                }
                break;

            case "http.request.full_uri":
                // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10681 is fixed.
                // Assert.AreEqual(fieldShow, ("http://" + httpDatagram.Header["Host"].ValueString + ((HttpRequestDatagram)httpDatagram).Uri).ToWiresharkLiteral());
                break;

            default:
                throw new InvalidOperationException("Invalid HTTP field " + field.Name());
            }

            return(true);
        }
Exemple #5
0
        public void RandomHttpTest()
        {
            int seed = new Random().Next();

            Console.WriteLine("Seed: " + seed);
            Random random = new Random(seed);

            for (int i = 0; i != 200; ++i)
            {
                EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
                IpV4Layer     ipV4Layer     = random.NextIpV4Layer(null);
                ipV4Layer.HeaderChecksum = null;
                Layer    ipLayer  = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(true);
                TcpLayer tcpLayer = random.NextTcpLayer();
                tcpLayer.Checksum = null;
                HttpLayer httpLayer = random.NextHttpLayer();

                Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipLayer, tcpLayer, httpLayer);
                Assert.IsTrue(packet.IsValid, "IsValid");

                HttpDatagram httpDatagram = packet.Ethernet.Ip.Tcp.Http;
                Assert.AreEqual(httpLayer.Version, httpDatagram.Version);
                if (httpLayer.Version != null)
                {
                    Assert.AreEqual(httpLayer.Version.GetHashCode(), httpDatagram.Version.GetHashCode());
                }
                if (httpLayer is HttpRequestLayer)
                {
                    Assert.IsTrue(httpDatagram.IsRequest);
                    Assert.IsTrue(httpLayer.IsRequest);
                    Assert.IsFalse(httpDatagram.IsResponse);
                    Assert.IsFalse(httpLayer.IsResponse);

                    HttpRequestLayer    httpRequestLayer    = (HttpRequestLayer)httpLayer;
                    HttpRequestDatagram httpRequestDatagram = (HttpRequestDatagram)httpDatagram;
                    Assert.AreEqual(httpRequestLayer.Method, httpRequestDatagram.Method);
                    if (httpRequestLayer.Method != null)
                    {
                        Assert.AreEqual(httpRequestLayer.Method.GetHashCode(), httpRequestDatagram.Method.GetHashCode());
                        Assert.AreEqual(httpRequestLayer.Method.KnownMethod, httpRequestDatagram.Method.KnownMethod);
                    }
                    Assert.AreEqual(httpRequestLayer.Uri, httpRequestDatagram.Uri);
                }
                else
                {
                    Assert.IsFalse(httpDatagram.IsRequest);
                    Assert.IsFalse(httpLayer.IsRequest);
                    Assert.IsTrue(httpDatagram.IsResponse);
                    Assert.IsTrue(httpLayer.IsResponse);

                    HttpResponseLayer    httpResponseLayer    = (HttpResponseLayer)httpLayer;
                    HttpResponseDatagram httpResponseDatagram = (HttpResponseDatagram)httpDatagram;
                    Assert.AreEqual(httpResponseLayer.StatusCode, httpResponseDatagram.StatusCode);
                    Assert.AreEqual(httpResponseLayer.ReasonPhrase, httpResponseDatagram.ReasonPhrase);
                }
                Assert.AreEqual(httpLayer.Header, httpDatagram.Header);
                if (httpLayer.Header != null)
                {
                    Assert.AreEqual(httpLayer.Header.GetHashCode(), httpDatagram.Header.GetHashCode());
                    if (!httpDatagram.IsRequest || ((HttpRequestDatagram)httpDatagram).Uri != "")
                    {
                        Assert.IsTrue(httpDatagram.IsValidStart, "IsValidStart");
                    }

                    foreach (var field in httpLayer.Header)
                    {
                        Assert.IsFalse(field.Equals("abc"));
                    }
                    foreach (var field in (IEnumerable)httpLayer.Header)
                    {
                        Assert.IsFalse(field.Equals("abc"));
                    }

                    MoreAssert.AreSequenceEqual(httpLayer.Header.Select(field => field.GetHashCode()), httpDatagram.Header.Select(field => field.GetHashCode()));

                    if (httpLayer.Header.ContentType != null)
                    {
                        var parameters = httpLayer.Header.ContentType.Parameters;
                        Assert.IsNotNull(((IEnumerable)parameters).GetEnumerator());
                        Assert.AreEqual <object>(parameters, httpDatagram.Header.ContentType.Parameters);
                        Assert.AreEqual(parameters.GetHashCode(), httpDatagram.Header.ContentType.Parameters.GetHashCode());
                        Assert.AreEqual(parameters.Count, httpDatagram.Header.ContentType.Parameters.Count);
                        int maxParameterNameLength = parameters.Any() ? parameters.Max(pair => pair.Key.Length) : 0;
                        Assert.IsNull(parameters[new string('a', maxParameterNameLength + 1)]);
                    }
                }
                Assert.AreEqual(httpLayer.Body, httpDatagram.Body);
                Assert.AreEqual(httpLayer, httpDatagram.ExtractLayer(), "HTTP Layer");
                Assert.AreEqual(httpLayer.Length, httpDatagram.Length);
            }
        }
Exemple #6
0
        public void RandomIcmpTest()
        {
            EthernetLayer ethernetLayer = new EthernetLayer
            {
                Source      = new MacAddress("00:01:02:03:04:05"),
                Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
            };

            int seed = new Random().Next();

            Console.WriteLine("Seed: " + seed);
            Random random = new Random(seed);

            for (int i = 0; i != 2000; ++i)
            {
                IpV4Layer ipV4Layer = random.NextIpV4Layer(null);
                ipV4Layer.HeaderChecksum = null;
                Layer ipLayer = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(IpV4Protocol.InternetControlMessageProtocol, false);

                IcmpLayer icmpLayer = random.NextIcmpLayer();
                icmpLayer.Checksum = null;
                if (icmpLayer.MessageType == IcmpMessageType.DestinationUnreachable &&
                    icmpLayer.MessageTypeAndCode != IcmpMessageTypeAndCode.DestinationUnreachableFragmentationNeededAndDoNotFragmentSet)
                {
                    ((IcmpDestinationUnreachableLayer)icmpLayer).NextHopMaximumTransmissionUnit = 0;
                }

                IEnumerable <ILayer> icmpPayloadLayers = random.NextIcmpPayloadLayers(icmpLayer);

                int icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum();

                switch (icmpLayer.MessageType)
                {
                case IcmpMessageType.ParameterProblem:
                    if (icmpPayloadLength % 4 != 0)
                    {
                        icmpPayloadLayers = icmpPayloadLayers.Concat(new[] { new PayloadLayer {
                                                                                 Data = random.NextDatagram(4 - icmpPayloadLength % 4)
                                                                             } });
                    }
                    icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum();
                    IcmpParameterProblemLayer icmpParameterProblemLayer = (IcmpParameterProblemLayer)icmpLayer;
                    icmpParameterProblemLayer.Pointer = (byte)(icmpParameterProblemLayer.Pointer % icmpPayloadLength);
                    icmpParameterProblemLayer.OriginalDatagramLength = icmpPayloadLength - icmpPayloadLayers.First().Length;
                    break;

                case IcmpMessageType.SecurityFailures:
                    ((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength;
                    break;
                }

                PacketBuilder packetBuilder = new PacketBuilder(new ILayer[] { ethernetLayer, ipLayer, icmpLayer }.Concat(icmpPayloadLayers));

                Packet packet = packetBuilder.Build(DateTime.Now);
                Assert.IsTrue(packet.IsValid, "IsValid");

                byte[] buffer = (byte[])packet.Buffer.Clone();
                buffer.Write(ethernetLayer.Length + ipLayer.Length, random.NextDatagram(icmpLayer.Length));
                Packet illegalPacket = new Packet(buffer, DateTime.Now, packet.DataLink);
                Assert.IsFalse(illegalPacket.IsValid, "IsInvalid");
                if (illegalPacket.Ethernet.Ip.Icmp is IcmpUnknownDatagram)
                {
                    byte[] icmpBuffer = new byte[illegalPacket.Ethernet.Ip.Icmp.ExtractLayer().Length];
                    ILayer layer      = illegalPacket.Ethernet.Ip.Icmp.ExtractLayer();
                    layer.Write(icmpBuffer, 0, icmpBuffer.Length, null, null);
                    layer.Finalize(icmpBuffer, 0, icmpBuffer.Length, null);
                    MoreAssert.AreSequenceEqual(illegalPacket.Ethernet.Ip.Icmp.ToArray(),
                                                icmpBuffer);

                    Assert.AreEqual(illegalPacket,
                                    PacketBuilder.Build(DateTime.Now, ethernetLayer, ipLayer, illegalPacket.Ethernet.Ip.Icmp.ExtractLayer()));
                }

                // Ethernet
                ethernetLayer.EtherType = ipLayer == ipV4Layer ? EthernetType.IpV4 : EthernetType.IpV6;
                Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer(), "Ethernet Layer");
                ethernetLayer.EtherType = EthernetType.None;

                // IP.
                if (ipLayer == ipV4Layer)
                {
                    // IPv4.
                    ipV4Layer.Protocol       = IpV4Protocol.InternetControlMessageProtocol;
                    ipV4Layer.HeaderChecksum = ((IpV4Layer)packet.Ethernet.IpV4.ExtractLayer()).HeaderChecksum;
                    Assert.AreEqual(ipV4Layer, packet.Ethernet.IpV4.ExtractLayer());
                    ipV4Layer.HeaderChecksum = null;
                    Assert.AreEqual(ipV4Layer.Length, packet.Ethernet.IpV4.HeaderLength);
                    Assert.IsTrue(packet.Ethernet.IpV4.IsHeaderChecksumCorrect);
                    Assert.AreEqual(ipV4Layer.Length + icmpLayer.Length + icmpPayloadLength,
                                    packet.Ethernet.IpV4.TotalLength);
                    Assert.AreEqual(IpV4Datagram.DefaultVersion, packet.Ethernet.IpV4.Version);
                }
                else
                {
                    // IPv6.
                    Assert.AreEqual(ipLayer, packet.Ethernet.IpV6.ExtractLayer());
                }

                // ICMP
                IcmpDatagram actualIcmp      = packet.Ethernet.Ip.Icmp;
                IcmpLayer    actualIcmpLayer = (IcmpLayer)actualIcmp.ExtractLayer();
                icmpLayer.Checksum = actualIcmpLayer.Checksum;
                Assert.AreEqual(icmpLayer, actualIcmpLayer);
                Assert.AreEqual(icmpLayer.GetHashCode(), actualIcmpLayer.GetHashCode());
                if (actualIcmpLayer.MessageType != IcmpMessageType.RouterSolicitation)
                {
                    Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer);
                    IcmpLayer otherIcmpLayer = random.NextIcmpLayer();
                    Assert.AreNotEqual(otherIcmpLayer.GetHashCode(), actualIcmpLayer.GetHashCode());
                }
                Assert.IsTrue(actualIcmp.IsChecksumCorrect);
                Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType);
                Assert.AreEqual(icmpLayer.CodeValue, actualIcmp.Code);
                Assert.AreEqual(icmpLayer.MessageTypeAndCode, actualIcmp.MessageTypeAndCode);
                Assert.AreEqual(packet.Length - ethernetLayer.Length - ipLayer.Length - IcmpDatagram.HeaderLength, actualIcmp.Payload.Length);
                Assert.IsNotNull(icmpLayer.ToString());

                switch (packet.Ethernet.Ip.Icmp.MessageType)
                {
                case IcmpMessageType.RouterSolicitation:
                case IcmpMessageType.SourceQuench:
                case IcmpMessageType.TimeExceeded:
                    Assert.AreEqual <uint>(0, actualIcmp.Variable);
                    break;

                case IcmpMessageType.DestinationUnreachable:
                case IcmpMessageType.ParameterProblem:
                case IcmpMessageType.Redirect:
                case IcmpMessageType.ConversionFailed:
                case IcmpMessageType.Echo:
                case IcmpMessageType.EchoReply:
                case IcmpMessageType.Timestamp:
                case IcmpMessageType.TimestampReply:
                case IcmpMessageType.InformationRequest:
                case IcmpMessageType.InformationReply:
                case IcmpMessageType.RouterAdvertisement:
                case IcmpMessageType.AddressMaskRequest:
                case IcmpMessageType.AddressMaskReply:
                    break;

                case IcmpMessageType.TraceRoute:
                    Assert.AreEqual(((IcmpTraceRouteLayer)icmpLayer).ReturnHopCount == 0xFFFF, ((IcmpTraceRouteDatagram)actualIcmp).IsOutbound);
                    break;

                case IcmpMessageType.DomainNameRequest:
                case IcmpMessageType.SecurityFailures:
                    break;

                case IcmpMessageType.DomainNameReply:
                default:
                    throw new InvalidOperationException("Invalid icmpMessageType " + packet.Ethernet.Ip.Icmp.MessageType);
                }
            }
        }