/// <summary> /// This function build an IPv4 over GRE over IPv4 over Ethernet packet. /// </summary> public static Packet BuildGrePacket() { EthernetLayer ethernetLayer = new EthernetLayer { Source = new MacAddress(macAddressSource), Destination = new MacAddress(macAddressDest), EtherType = EthernetType.None, // Will be filled automatically. }; IpV4Layer ipV4Layer = new IpV4Layer { Source = new IpV4Address(ipSource), CurrentDestination = new IpV4Address(ipDest), Fragmentation = IpV4Fragmentation.None, HeaderChecksum = null, // Will be filled automatically. Identification = 123, Options = IpV4Options.None, Protocol = null, // Will be filled automatically. Ttl = 100, TypeOfService = 0, }; GreLayer greLayer = new GreLayer { Version = GreVersion.Gre, ProtocolType = EthernetType.None, // Will be filled automatically. RecursionControl = 0, FutureUseBits = 0, ChecksumPresent = true, Checksum = null, // Will be filled automatically. Key = null, SequenceNumber = 123, AcknowledgmentSequenceNumber = null, RoutingOffset = null, Routing = null, StrictSourceRoute = false, }; IpV4Layer innerIpV4Layer = new IpV4Layer { Source = new IpV4Address("100.200.201.202"), CurrentDestination = new IpV4Address("123.254.132.40"), Fragmentation = IpV4Fragmentation.None, HeaderChecksum = null, // Will be filled automatically. Identification = 123, Options = IpV4Options.None, Protocol = IpV4Protocol.Udp, Ttl = 120, TypeOfService = 0, }; PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer, innerIpV4Layer); return(builder.Build(DateTime.Now)); }
private static void CreateRandomIpV4Payload(Random random, IpV4Layer ipV4Layer, List <ILayer> layers) { if (random.NextBool(20)) { // Finish with payload. PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100)); layers.Add(payloadLayer); return; } ipV4Layer.Protocol = null; if (random.NextBool()) { ipV4Layer.Fragmentation = IpV4Fragmentation.None; } switch (random.Next(0, 9)) { case 0: // IpV4. case 1: IpV4Layer innerIpV4Layer = random.NextIpV4Layer(); layers.Add(innerIpV4Layer); CreateRandomIpV4Payload(random, innerIpV4Layer, layers); return; case 2: // Igmp. layers.Add(random.NextIgmpLayer()); return; case 3: // Icmp. IcmpLayer icmpLayer = random.NextIcmpLayer(); layers.Add(icmpLayer); layers.AddRange(random.NextIcmpPayloadLayers(icmpLayer)); return; case 4: // Gre. GreLayer greLayer = random.NextGreLayer(); layers.Add(greLayer); CreateRandomEthernetPayload(random, greLayer, layers); return; case 5: // Udp. case 6: UdpLayer udpLayer = random.NextUdpLayer(); layers.Add(udpLayer); CreateRandomUdpPayload(random, udpLayer, layers); return; case 7: // Tcp. case 8: TcpLayer tcpLayer = random.NextTcpLayer(); layers.Add(tcpLayer); CreateRandomTcpPayload(random, tcpLayer, layers); return; default: throw new InvalidOperationException("Invalid value."); } }
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 void InvalidGreTest() { 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 != 100; ++i) { IpV4Layer ipV4Layer = random.NextIpV4Layer(IpV4Protocol.Gre); ipV4Layer.HeaderChecksum = null; Layer ipLayer = random.NextBool() ? (Layer)ipV4Layer : random.NextIpV6Layer(IpV4Protocol.Gre, false); GreLayer greLayer = random.NextGreLayer(); greLayer.Checksum = null; greLayer.Routing = new List <GreSourceRouteEntry> { new GreSourceRouteEntryAs(new List <ushort> { 123 }.AsReadOnly(), 0), new GreSourceRouteEntryIp(new List <IpV4Address> { random.NextIpV4Address() }.AsReadOnly(), 0) }.AsReadOnly(); PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, greLayer); Packet packet = packetBuilder.Build(DateTime.Now); Assert.IsTrue(packet.IsValid || new[] { EthernetType.IpV4, EthernetType.IpV6, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(greLayer.ProtocolType), "IsValid. ProtoclType=" + greLayer.ProtocolType); GreDatagram gre = packet.Ethernet.Ip.Gre; // Remove a byte from routing Datagram newIpPayload = new Datagram(gre.Take(gre.Length - 1).ToArray()); packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, new PayloadLayer { Data = newIpPayload }); packet = packetBuilder.Build(DateTime.Now); Assert.IsNull(packet.Ethernet.Ip.Gre.Payload); Assert.IsFalse(packet.IsValid); // SreLength is too big byte[] buffer = gre.ToArray(); buffer[buffer.Length - 1] = 200; newIpPayload = new Datagram(buffer); packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, new PayloadLayer { Data = newIpPayload }); packet = packetBuilder.Build(DateTime.Now); Assert.IsFalse(packet.IsValid); // PayloadOffset is too big buffer = gre.ToArray(); buffer[gre.Length - 10] = 100; newIpPayload = new Datagram(buffer); packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, new PayloadLayer { Data = newIpPayload }); packet = packetBuilder.Build(DateTime.Now); Assert.IsFalse(packet.IsValid); // PayloadOffset isn't aligned to ip buffer = gre.ToArray(); buffer[gre.Length - 10] = 3; newIpPayload = new Datagram(buffer); packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, new PayloadLayer { Data = newIpPayload }); packet = packetBuilder.Build(DateTime.Now); Assert.IsFalse(packet.IsValid); // PayloadOffset isn't aligned to as buffer = gre.ToArray(); buffer[gre.Length - 16] = 1; newIpPayload = new Datagram(buffer); packetBuilder = new PacketBuilder(ethernetLayer, ipLayer, new PayloadLayer { Data = newIpPayload }); packet = packetBuilder.Build(DateTime.Now); Assert.IsFalse(packet.IsValid); } }
private static void CreateRandomIpPayload(Random random, Layer ipLayer, List <ILayer> layers) { IpV6Layer ipV6Layer = ipLayer as IpV6Layer; if (ipV6Layer != null) { var headers = ipV6Layer.ExtensionHeaders.Headers; if (headers.Any() && headers.Last().Protocol == IpV4Protocol.EncapsulatingSecurityPayload) { return; } } if (ipV6Layer != null ? ipV6Layer.LastNextHeader != null : random.NextBool(20)) { // Finish with payload. PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100)); layers.Add(payloadLayer); return; } IpV4Layer ipV4Layer = ipLayer as IpV4Layer; if (ipV4Layer != null) { ipV4Layer.Protocol = null; if (random.NextBool()) { ipV4Layer.Fragmentation = IpV4Fragmentation.None; } } switch (random.Next(0, 11)) { case 0: // IpV4. case 1: IpV4Layer innerIpV4Layer = random.NextIpV4Layer(); layers.Add(innerIpV4Layer); CreateRandomIpPayload(random, innerIpV4Layer, layers); return; case 2: // IpV6. case 3: IpV6Layer innerIpV6Layer = random.NextIpV6Layer(random.NextBool(20)); layers.Add(innerIpV6Layer); CreateRandomIpPayload(random, innerIpV6Layer, layers); return; case 4: // Igmp. layers.Add(random.NextIgmpLayer()); return; case 5: // Icmp. IcmpLayer icmpLayer = random.NextIcmpLayer(); layers.Add(icmpLayer); layers.AddRange(random.NextIcmpPayloadLayers(icmpLayer)); return; case 6: // Gre. GreLayer greLayer = random.NextGreLayer(); layers.Add(greLayer); CreateRandomEthernetPayload(random, greLayer, layers); return; case 7: // Udp. case 8: UdpLayer udpLayer = random.NextUdpLayer(); layers.Add(udpLayer); CreateRandomUdpPayload(random, udpLayer, layers); return; case 9: // Tcp. case 10: TcpLayer tcpLayer = random.NextTcpLayer(); layers.Add(tcpLayer); CreateRandomTcpPayload(random, tcpLayer, layers); return; default: throw new InvalidOperationException("Invalid value."); } }
/// <summary> /// This function build an IPv4 over GRE over IPv4 over Ethernet packet. /// </summary> private static Packet BuildGrePacket() { EthernetLayer ethernetLayer = new EthernetLayer { Source = new MacAddress("01:01:01:01:01:01"), Destination = new MacAddress("02:02:02:02:02:02"), EtherType = EthernetType.None, // Will be filled automatically. }; IpV4Layer ipV4Layer = new IpV4Layer { Source = new IpV4Address("1.2.3.4"), CurrentDestination = new IpV4Address("11.22.33.44"), Fragmentation = IpV4Fragmentation.None, HeaderChecksum = null, // Will be filled automatically. Identification = 123, Options = IpV4Options.None, Protocol = null, // Will be filled automatically. Ttl = 100, TypeOfService = 0, }; GreLayer greLayer = new GreLayer { Version = GreVersion.Gre, ProtocolType = EthernetType.None, // Will be filled automatically. RecursionControl = 0, FutureUseBits = 0, ChecksumPresent = true, Checksum = null, // Will be filled automatically. Key = null, SequenceNumber = 123, AcknowledgmentSequenceNumber = null, RoutingOffset = null, Routing = null, StrictSourceRoute = false, }; IpV4Layer innerIpV4Layer = new IpV4Layer { Source = new IpV4Address("100.200.201.202"), CurrentDestination = new IpV4Address("123.254.132.40"), Fragmentation = IpV4Fragmentation.None, HeaderChecksum = null, // Will be filled automatically. Identification = 123, Options = IpV4Options.None, Protocol = IpV4Protocol.Udp, Ttl = 120, TypeOfService = 0, }; PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer, innerIpV4Layer); return builder.Build(DateTime.Now); }