private static bool TryReadEntry(byte[] buffer, int payloadOffset, int payloadLength, GreSourceRouteEntryAddressFamily addressFamily, int offsetInPayload, out GreSourceRouteEntry entry) { entry = null; switch (addressFamily) { case GreSourceRouteEntryAddressFamily.IpSourceRoute: if (offsetInPayload % IpV4Address.SizeOf != 0 || payloadLength % IpV4Address.SizeOf != 0) { return(false); } int numAddresses = payloadLength / IpV4Address.SizeOf; IpV4Address[] addresses = new IpV4Address[numAddresses]; for (int i = 0; i != numAddresses; ++i) { addresses[i] = buffer.ReadIpV4Address(payloadOffset + i * IpV4Address.SizeOf, Endianity.Big); } entry = new GreSourceRouteEntryIp(addresses, offsetInPayload / IpV4Address.SizeOf); return(true); case GreSourceRouteEntryAddressFamily.AsSourceRoute: if (offsetInPayload % sizeof(ushort) != 0 || payloadLength % sizeof(ushort) != 0) { return(false); } int numAsNumbers = payloadLength / sizeof(ushort); ushort[] asNumbers = new ushort[numAsNumbers]; for (int i = 0; i != numAsNumbers; ++i) { asNumbers[i] = buffer.ReadUShort(payloadOffset + i * sizeof(ushort), Endianity.Big); } entry = new GreSourceRouteEntryAs(asNumbers, offsetInPayload / sizeof(ushort)); return(true); default: Datagram data = new Datagram(buffer, payloadOffset, payloadLength); entry = new GreSourceRouteEntryUnknown(addressFamily, data, offsetInPayload); return(true); } }
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, }; }