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; } } }
public static GreLayer NextGreLayer(this Random random) { GreVersion version = random.NextEnum <GreVersion>(); bool isChecksum = random.NextBool(); GreSourceRouteEntry[] routing = null; ushort? routingOffset = null; bool strictSourceRoute = false; EthernetType protocolType = random.NextEnum(EthernetType.None); uint? key = random.NextBool() ? (uint?)random.NextUInt() : null; if (version == GreVersion.Gre) { if (random.NextBool()) { strictSourceRoute = random.NextBool(); routing = new GreSourceRouteEntry[random.Next(5)]; GreSourceRouteEntryAddressFamily family; if (random.NextBool()) { family = random.NextEnum(GreSourceRouteEntryAddressFamily.None); } else { family = (GreSourceRouteEntryAddressFamily)random.NextUShort(); } for (int i = 0; i != routing.Length; ++i) { switch (family) { case GreSourceRouteEntryAddressFamily.AsSourceRoute: { ushort[] asNumbers = ((Func <ushort>)(() => random.NextUShort())).GenerateArray(random.NextInt(1, 5)); routing[i] = new GreSourceRouteEntryAs(asNumbers.AsReadOnly(), random.Next(asNumbers.Length + 1)); break; } case GreSourceRouteEntryAddressFamily.IpSourceRoute: { IpV4Address[] ips = ((Func <IpV4Address>)(() => random.NextIpV4Address())).GenerateArray(random.NextInt(1, 5)); routing[i] = new GreSourceRouteEntryIp(ips.AsReadOnly(), random.Next(ips.Length + 1)); break; } default: { int dataLength = random.NextInt(1, 100); routing[i] = new GreSourceRouteEntryUnknown(family, random.NextDatagram(dataLength), random.Next(dataLength + 1)); break; } } } routingOffset = 0; if (routing.Any()) { int routingIndex = random.Next(routing.Length); for (int i = 0; i != routingIndex; ++i) { routingOffset += (ushort)routing[i].Length; } } } } else { protocolType = EthernetType.PointToPointProtocol; isChecksum = false; key = random.NextUInt(); } return(new GreLayer { Version = version, ProtocolType = protocolType, ChecksumPresent = isChecksum, Checksum = isChecksum && random.NextBool() ? (ushort?)random.NextUShort() : null, Key = key, SequenceNumber = random.NextBool() ? (uint?)random.NextUInt() : null, AcknowledgmentSequenceNumber = version == GreVersion.EnhancedGre && random.NextBool() ? (uint?)random.NextUInt() : null, RecursionControl = random.NextByte(8), // Flags = random.NextByte(32), Routing = routing == null ? null : routing.AsReadOnly(), RoutingOffset = routingOffset, StrictSourceRoute = strictSourceRoute, }); }