예제 #1
0
        public void SimpleTest()
        {
            Assert.AreEqual <SerialNumber32>(1, 1);
            Assert.AreNotEqual <SerialNumber32>(1, 2);
            MoreAssert.IsBigger(1, 2);
            MoreAssert.IsSmaller(2, 1);

            SerialNumber32 serialNumber = 1;

            serialNumber = serialNumber.Add(10);
            Assert.AreEqual <SerialNumber32>(11, serialNumber);

            serialNumber = serialNumber.Add(((uint)1 << 31) - 1);
            Assert.AreEqual <SerialNumber32>(2147483658, serialNumber);
            MoreAssert.IsSmaller <SerialNumber32>(1, serialNumber);
            MoreAssert.IsBigger <SerialNumber32>(20, serialNumber);

            serialNumber = serialNumber.Add(((uint)1 << 31) - 1);
            Assert.AreEqual <SerialNumber32>(9, serialNumber);

            Assert.IsTrue(new SerialNumber32(1) < new SerialNumber32(2));
            Assert.IsTrue(new SerialNumber32(2) > new SerialNumber32(1));
            // ReSharper disable EqualExpressionComparison
            Assert.IsFalse(new SerialNumber32(1) < new SerialNumber32(1));
            Assert.IsFalse(new SerialNumber32(1) > new SerialNumber32(1));
            // ReSharper restore EqualExpressionComparison
            Assert.IsTrue(new SerialNumber32(2) != new SerialNumber32(1));
            Assert.IsFalse(new SerialNumber32(1) != new SerialNumber32(0).Add(1));
            Assert.IsTrue(new SerialNumber32(2) == new SerialNumber32(1).Add(1));
            Assert.IsFalse(new SerialNumber32(1).Equals(1.0));

            Assert.AreEqual("1", new SerialNumber32(1).ToString());
        }
예제 #2
0
        public void RandomGreTest()
        {
            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 != 200; ++i)
            {
                IpV4Layer ipV4Layer = random.NextIpV4Layer(null);
                ipV4Layer.HeaderChecksum = null;
                Layer ipLayer = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(IpV4Protocol.Gre, false);

                GreLayer     greLayer     = random.NextGreLayer();
                PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100));

                PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, greLayer, payloadLayer);

                Packet packet = packetBuilder.Build(DateTime.Now);
                if (greLayer.Checksum == null &&
                    !new[] { EthernetType.IpV4, EthernetType.IpV6, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(packet.Ethernet.Ip.Gre.ProtocolType))
                {
                    Assert.IsTrue(packet.IsValid, "IsValid, ProtocolType=" + packet.Ethernet.Ip.Gre.ProtocolType);
                }

                // 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.Gre;
                    ipV4Layer.HeaderChecksum = ((IpV4Layer)packet.Ethernet.Ip.ExtractLayer()).HeaderChecksum;
                    Assert.AreEqual(ipV4Layer, packet.Ethernet.Ip.ExtractLayer());
                    ipV4Layer.HeaderChecksum = null;
                    Assert.AreEqual(ipV4Layer.Length, packet.Ethernet.IpV4.HeaderLength);
                    Assert.IsTrue(packet.Ethernet.IpV4.IsHeaderChecksumCorrect);
                    Assert.AreEqual(ipV4Layer.Length + greLayer.Length + payloadLayer.Length,
                                    packet.Ethernet.Ip.TotalLength);
                    Assert.AreEqual(IpV4Datagram.DefaultVersion, packet.Ethernet.Ip.Version);
                }
                else
                {
                    // IPv6.
                    Assert.AreEqual(ipLayer, packet.Ethernet.Ip.ExtractLayer());
                }

                // GRE
                GreDatagram actualGre      = packet.Ethernet.Ip.Gre;
                GreLayer    actualGreLayer = (GreLayer)actualGre.ExtractLayer();
                if (greLayer.ChecksumPresent && greLayer.Checksum == null)
                {
                    Assert.IsTrue(actualGre.IsChecksumCorrect);
                    greLayer.Checksum = actualGre.Checksum;
                }
                Assert.AreEqual(greLayer, actualGreLayer, "Layer");
                if (actualGreLayer.Key != null)
                {
                    actualGreLayer.SetKey(actualGreLayer.KeyPayloadLength.Value, actualGreLayer.KeyCallId.Value);
                }
                else
                {
                    Assert.IsNull(actualGreLayer.KeyPayloadLength);
                    Assert.IsNull(actualGreLayer.KeyCallId);
                }
                Assert.AreEqual(greLayer, actualGreLayer, "Layer");
                if (actualGre.KeyPresent)
                {
                    Assert.AreEqual(greLayer.KeyPayloadLength, actualGre.KeyPayloadLength, "KeyPayloadLength");
                    Assert.AreEqual(greLayer.KeyCallId, actualGre.KeyCallId, "KeyCallId");
                }
                Assert.AreNotEqual(random.NextGreLayer(), actualGreLayer, "Not Layer");
                Assert.AreEqual(greLayer.Length, actualGre.HeaderLength);
                Assert.IsTrue(actualGre.KeyPresent ^ (greLayer.Key == null));
                MoreAssert.IsSmaller(8, actualGre.RecursionControl);
                MoreAssert.IsSmaller(32, actualGre.FutureUseBits);
                Assert.IsTrue(actualGre.RoutingPresent ^ (greLayer.Routing == null && greLayer.RoutingOffset == null));
                Assert.IsTrue(actualGre.SequenceNumberPresent ^ (greLayer.SequenceNumber == null));
                Assert.IsTrue(!actualGre.StrictSourceRoute || actualGre.RoutingPresent);
                if (actualGre.RoutingPresent)
                {
                    Assert.IsNotNull(actualGre.ActiveSourceRouteEntryIndex);
                    if (actualGre.ActiveSourceRouteEntryIndex < actualGre.Routing.Count)
                    {
                        Assert.IsNotNull(actualGre.ActiveSourceRouteEntry);
                    }

                    foreach (GreSourceRouteEntry entry in actualGre.Routing)
                    {
                        Assert.AreNotEqual(entry, 2);
                        Assert.AreEqual(entry.GetHashCode(), entry.GetHashCode());
                        switch (entry.AddressFamily)
                        {
                        case GreSourceRouteEntryAddressFamily.AsSourceRoute:
                            GreSourceRouteEntryAs asEntry = (GreSourceRouteEntryAs)entry;
                            MoreAssert.IsInRange(0, asEntry.AsNumbers.Count, asEntry.NextAsNumberIndex);
                            if (asEntry.NextAsNumberIndex != asEntry.AsNumbers.Count)
                            {
                                Assert.AreEqual(asEntry.AsNumbers[asEntry.NextAsNumberIndex], asEntry.NextAsNumber);
                            }
                            break;

                        case GreSourceRouteEntryAddressFamily.IpSourceRoute:
                            GreSourceRouteEntryIp ipEntry = (GreSourceRouteEntryIp)entry;
                            MoreAssert.IsInRange(0, ipEntry.Addresses.Count, ipEntry.NextAddressIndex);
                            if (ipEntry.NextAddressIndex != ipEntry.Addresses.Count)
                            {
                                Assert.AreEqual(ipEntry.Addresses[ipEntry.NextAddressIndex], ipEntry.NextAddress);
                            }
                            break;

                        default:
                            GreSourceRouteEntryUnknown unknownEntry = (GreSourceRouteEntryUnknown)entry;
                            MoreAssert.IsInRange(0, unknownEntry.Data.Length, unknownEntry.PayloadOffset);
                            break;
                        }
                    }
                }
                else
                {
                    Assert.IsNull(actualGre.ActiveSourceRouteEntry);
                }

                Assert.IsNotNull(actualGre.Payload);
                switch (actualGre.ProtocolType)
                {
                case EthernetType.IpV4:
                    Assert.IsNotNull(actualGre.IpV4);
                    break;

                case EthernetType.Arp:
                    Assert.IsNotNull(actualGre.Arp);
                    break;
                }
            }
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IpV6Datagram ipV6Datagram = (IpV6Datagram)datagram;

            SkipAuthenticationHeaders(ipV6Datagram);
            int optionsIndex = 0;

            switch (field.Name())
            {
            case "ipv6.version":
                field.AssertShowDecimal(ipV6Datagram.Version);
                foreach (XElement subfield in field.Fields())
                {
                    switch (subfield.Name())
                    {
                    case "ip.version":
                        subfield.AssertShowDecimal(ipV6Datagram.Version);
                        break;

                    default:
                        throw new InvalidOperationException(string.Format("Invalid ipv6 version subfield {0}", subfield.Name()));
                    }
                }
                break;

            case "ipv6.class":
                field.AssertShowDecimal(ipV6Datagram.TrafficClass);
                break;

            case "ipv6.flow":
                field.AssertShowDecimal(ipV6Datagram.FlowLabel);
                field.AssertNoFields();
                break;

            case "ipv6.plen":
                field.AssertShowDecimal(ipV6Datagram.PayloadLength);
                field.AssertNoFields();
                break;

            case "ipv6.nxt":
                field.AssertShowDecimal((byte)ipV6Datagram.NextHeader);
                field.AssertNoFields();
                break;

            case "ipv6.hlim":
                field.AssertShowDecimal(ipV6Datagram.HopLimit);
                field.AssertNoFields();
                break;

            case "ipv6.src":
            case "ipv6.src_host":
                field.AssertShow(ipV6Datagram.Source.GetWiresharkString());
                field.AssertNoFields();
                break;

            case "ipv6.src_6to4_gw_ipv4":
            case "ipv6.src_6to4_sla_id":
            case "ipv6.6to4_gw_ipv4":
            case "ipv6.6to4_sla_id":
                field.AssertNoFields();
                break;

            case "ipv6.dst":
            case "ipv6.dst_host":
                field.AssertShow(ipV6Datagram.CurrentDestination.GetWiresharkString());
                field.AssertNoFields();
                break;

            case "ipv6.addr":
            case "ipv6.host":
                Assert.IsTrue(field.Show() == ipV6Datagram.Source.GetWiresharkString() ||
                              field.Show() == ipV6Datagram.CurrentDestination.GetWiresharkString());
                field.AssertNoFields();
                break;

            case "ipv6.hop_opt":
                if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count)
                {
                    Assert.IsFalse(ipV6Datagram.ExtensionHeaders.IsValid);
                    int maxLength = ipV6Datagram.Length - IpV6Datagram.HeaderLength - ipV6Datagram.ExtensionHeaders.BytesLength;
                    if (field.Fields().Any(subfield => subfield.Name() == "ipv6.opt.length"))
                    {
                        int length = int.Parse(field.Fields().First(subfield => subfield.Name() == "ipv6.opt.length").Show());
                        MoreAssert.IsBigger(maxLength, length);
                    }
                    else
                    {
                        Assert.AreEqual(6, maxLength);
                    }
                }
                else
                {
                    IpV6ExtensionHeaderHopByHopOptions hopByHopOptions =
                        (IpV6ExtensionHeaderHopByHopOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                    IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                    CompareOptions(field, ref optionsIndex, ipV6Datagram, hopByHopOptions);
                }
                break;

            case "ipv6.routing_hdr":
                if (!ipV6Datagram.IsValid)
                {
                    return(false);
                }
                IpV6ExtensionHeaderRouting routing = (IpV6ExtensionHeaderRouting)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks routingProtocolLowPowerAndLossyNetworks =
                    routing as IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks;
                int routingProtocolLowPowerAndLossyNetworksAddressIndex = 0;
                IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                int sourceRouteAddressIndex = 0;
                foreach (var headerField in field.Fields())
                {
                    switch (headerField.Name())
                    {
                    case "":
                        headerField.AssertNoFields();
                        ValidateExtensionHeaderUnnamedField(routing, headerField);
                        break;

                    case "ipv6.routing_hdr.type":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal((byte)routing.RoutingType);
                        break;

                    case "ipv6.routing_hdr.left":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal(routing.SegmentsLeft);
                        break;

                    case "ipv6.mipv6_home_address":
                        headerField.AssertNoFields();
                        IpV6ExtensionHeaderRoutingHomeAddress routingHomeAddress = (IpV6ExtensionHeaderRoutingHomeAddress)routing;
                        headerField.AssertShow(routingHomeAddress.HomeAddress.ToString("x"));
                        break;

                    case "ipv6.routing_hdr.addr":
                        headerField.AssertNoFields();
                        IpV6ExtensionHeaderRoutingSourceRoute routingSourceRoute = (IpV6ExtensionHeaderRoutingSourceRoute)routing;
                        headerField.AssertShow(routingSourceRoute.Addresses[sourceRouteAddressIndex++].ToString("x"));
                        break;

                    case "ipv6.routing_hdr.rpl.cmprI":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForNonLastAddresses);
                        break;

                    case "ipv6.routing_hdr.rpl.cmprE":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForLastAddress);
                        break;

                    case "ipv6.routing_hdr.rpl.pad":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.PadSize);
                        break;

                    case "ipv6.routing_hdr.rpl.reserved":
                        headerField.AssertNoFields();
                        headerField.AssertShowDecimal(0);
                        break;

                    case "ipv6.routing_hdr.rpl.segments":
                        if (headerField.Fields().Any())
                        {
                            headerField.AssertNumFields(1);
                            headerField.Fields().First().AssertName("_ws.expert");
                        }
                        // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11803 is fixed.
                        if (routingProtocolLowPowerAndLossyNetworks.Addresses.Count > 0)
                        {
                            headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.Addresses.Count);
                        }
                        break;

                    case "ipv6.routing_hdr.rpl.address":
                        headerField.AssertNoFields();
                        // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11803 is fixed.
                        if (routingProtocolLowPowerAndLossyNetworks.Addresses.Count > 0)
                        {
                            IpV6Address actualAddress =
                                new IpV6Address(UInt128.Parse(headerField.Value(), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
                            Assert.AreEqual(routingProtocolLowPowerAndLossyNetworks.Addresses[routingProtocolLowPowerAndLossyNetworksAddressIndex],
                                            actualAddress);
                        }
                        break;

                    case "ipv6.routing_hdr.rpl.full_address":
                        headerField.AssertNoFields();
                        // TODO: Uncomment the following code when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10673 is fixed.
//                                // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11803 is fixed.
//                                if (routingProtocolLowPowerAndLossyNetworks.Addresses.Count > 0)
//                                {
//                                    IpV6Address actualFullAddress = new IpV6Address(headerField.Show());
//
//                                    IpV6Address destinationAddress = ipV6Datagram.CurrentDestination;
//                                    for (int i = 0; i < _currentExtensionHeaderIndex; ++i)
//                                    {
//                                        IpV6ExtensionHeaderRoutingHomeAddress ipV6ExtensionHeaderRoutingHomeAddress =
//                                            ipV6Datagram.ExtensionHeaders[i] as IpV6ExtensionHeaderRoutingHomeAddress;
//                                        if (ipV6ExtensionHeaderRoutingHomeAddress != null)
//                                            destinationAddress = ipV6ExtensionHeaderRoutingHomeAddress.HomeAddress;
//
//                                        IpV6ExtensionHeaderRoutingSourceRoute ipV6ExtensionHeaderRoutingSourceRoute =
//                                            ipV6Datagram.ExtensionHeaders[i] as IpV6ExtensionHeaderRoutingSourceRoute;
//                                        if (ipV6ExtensionHeaderRoutingSourceRoute != null && ipV6ExtensionHeaderRoutingSourceRoute.Addresses.Any())
//                                            destinationAddress = ipV6ExtensionHeaderRoutingSourceRoute.Addresses.Last();
//                                    }
//
//                                    int commonPrefixLength =
//                                        routingProtocolLowPowerAndLossyNetworksAddressIndex == routingProtocolLowPowerAndLossyNetworks.Addresses.Count - 1
//                                            ? routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForLastAddress
//                                            : routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForNonLastAddresses;
//
//                                    byte[] destinationAddressBytes = new byte[IpV6Address.SizeOf];
//                                    destinationAddressBytes.Write(0, destinationAddress, Endianity.Big);
//
//                                    byte[] routingAddressBytes = new byte[IpV6Address.SizeOf];
//                                    routingAddressBytes.Write(0, routingProtocolLowPowerAndLossyNetworks.Addresses[routingProtocolLowPowerAndLossyNetworksAddressIndex], Endianity.Big);
//
//                                    byte[] fullAddressBytes = destinationAddressBytes.Subsegment(0, commonPrefixLength).Concat(routingAddressBytes.Subsegment(commonPrefixLength, IpV6Address.SizeOf - commonPrefixLength)).ToArray();
//                                    IpV6Address expectedFullAddress = fullAddressBytes.ReadIpV6Address(0, Endianity.Big);
//
//                                    Assert.AreEqual(expectedFullAddress, actualFullAddress);
//                                }

                        ++routingProtocolLowPowerAndLossyNetworksAddressIndex;
                        break;

                    default:
                        throw new InvalidOperationException("Invalid IPv6 routing source route field " + headerField.Name());
                    }
                }
                break;

            case "ipv6.dst_opt":
                if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count)
                {
                    int expectedExtensionHeaderLength = (int.Parse(field.Fields().Skip(1).First().Value(), NumberStyles.HexNumber) + 1) * 8;
                    int actualMaxPossibleLength       = ipV6Datagram.RealPayloadLength -
                                                        ipV6Datagram.ExtensionHeaders.Take(_currentExtensionHeaderIndex).Sum(
                        extensionHeader => extensionHeader.Length);
                    MoreAssert.IsSmaller(expectedExtensionHeaderLength, actualMaxPossibleLength);
                    return(false);
                }
                IpV6ExtensionHeaderDestinationOptions destinationOptions = (IpV6ExtensionHeaderDestinationOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                CompareOptions(field, ref optionsIndex, ipV6Datagram, destinationOptions);
                break;

            case "ipv6.shim6":
                // TODO: Implement Shim6.
                IpV4Protocol nextHeader = _currentExtensionHeaderIndex > 0
                                                  ? ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex - 1].NextHeader.Value
                                                  : ipV6Datagram.NextHeader;
                Assert.IsTrue(nextHeader == IpV4Protocol.Shim6);
                break;

            case "ipv6.unknown_hdr":
                Assert.AreEqual(ipV6Datagram.ExtensionHeaders.Count(), _currentExtensionHeaderIndex);
                // TODO: Fix according to https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9996
                return(false);

            case "ipv6.src_sa_mac":
            case "ipv6.dst_sa_mac":
            case "ipv6.sa_mac":
            case "ipv6.dst_6to4_gw_ipv4":
            case "ipv6.dst_6to4_sla_id":
                // TODO: Understand how these are calculated.
                break;

            case "":
                switch (field.Show())
                {
                case "Fragmentation Header":
                    if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count && !ipV6Datagram.IsValid)
                    {
                        return(false);
                    }
                    IpV6ExtensionHeaderFragmentData fragmentData =
                        (IpV6ExtensionHeaderFragmentData)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                    IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                    foreach (var headerField in field.Fields())
                    {
                        switch (headerField.Name())
                        {
                        case "ipv6.fragment.nxt":
                            headerField.AssertValue((byte)fragmentData.NextHeader.Value);
                            break;

                        case "ipv6.fragment.offset":
                            headerField.AssertShowDecimal(fragmentData.FragmentOffset);
                            break;

                        case "ipv6.fragment.more":
                            headerField.AssertShowDecimal(fragmentData.MoreFragments);
                            break;

                        case "ipv6.fragment.id":
                            headerField.AssertShowDecimal(fragmentData.Identification);
                            break;

                        case "ipv6.fragment.reserved_octet":
                        case "ipv6.fragment.reserved_bits":
                            headerField.AssertShowDecimal(0);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid ipv6 fragmentation field " + headerField.Name());
                        }
                    }
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid ipv6 field {0}", field.Show()));
                }
                break;

            default:
                throw new InvalidOperationException(string.Format("Invalid ipv6 field {0}", field.Name()));
            }

            return(true);
        }