示例#1
0
        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")
            };

            Random random = new Random();

            for (int i = 0; i != 100; ++i)
            {
                IpV4Layer ipV4Layer = random.NextIpV4Layer(IpV4Protocol.Gre);
                ipV4Layer.HeaderChecksum = null;

                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, ipV4Layer, greLayer);
                Packet        packet        = packetBuilder.Build(DateTime.Now);
                Assert.IsTrue(packet.IsValid ||
                              new[] { EthernetType.IpV4, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(greLayer.ProtocolType),
                              "IsValid. ProtoclType=" + greLayer.ProtocolType);

                GreDatagram gre = packet.Ethernet.IpV4.Gre;

                // Remove a byte from routing
                Datagram newIpPayload = new Datagram(gre.Take(gre.Length - 1).ToArray());
                packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, new PayloadLayer {
                    Data = newIpPayload
                });
                packet = packetBuilder.Build(DateTime.Now);
                Assert.IsNull(packet.Ethernet.IpV4.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, ipV4Layer, 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, ipV4Layer, 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, ipV4Layer, 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, ipV4Layer, new PayloadLayer {
                    Data = newIpPayload
                });
                packet = packetBuilder.Build(DateTime.Now);
                Assert.IsFalse(packet.IsValid);
            }
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            GreDatagram greDatagram = (GreDatagram)datagram;

            switch (field.Name())
            {
            case "gre.flags_and_version":
                XElement[] innerFields = field.Fields().ToArray();
                MoreAssert.IsInRange(8, 9, innerFields.Length);

                int currentInnerFieldIndex = 0;
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.ChecksumPresent);
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.RoutingPresent);
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.KeyPresent);
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.SequenceNumberPresent);
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.StrictSourceRoute);
                innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.RecursionControl);
                if (innerFields.Length == 9)
                {
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.AcknowledgmentSequenceNumberPresent);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.FutureUseBits);
                }
                else
                {
                    byte futureUseBitsValue = (byte)((greDatagram.AcknowledgmentSequenceNumberPresent.ToInt() << 4) | greDatagram.FutureUseBits);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(futureUseBitsValue);
                }
                innerFields[currentInnerFieldIndex].AssertShowDecimal((byte)greDatagram.Version);
                break;

            case "data.len":
                field.AssertShowDecimal(
                    greDatagram.Payload.Length + (greDatagram.AcknowledgmentSequenceNumberPresent &&
                                                  (greDatagram.Version != GreVersion.EnhancedGre || !greDatagram.SequenceNumberPresent)
                                                          ? 4
                                                          : 0), "GRE data.len");
                field.AssertNoFields();
                break;

            case "gre.checksum":
                field.AssertShowDecimal(greDatagram.Checksum);
                field.AssertNoFields();
                break;

            case "gre.key.payload_length":
                field.AssertShowDecimal(greDatagram.KeyPayloadLength);
                field.AssertNoFields();
                break;

            case "gre.key.call_id":
                field.AssertShowDecimal(greDatagram.KeyCallId);
                field.AssertNoFields();
                break;

            case "gre.ack_number":
                field.AssertShowDecimal(greDatagram.AcknowledgmentSequenceNumber);
                field.AssertNoFields();
                break;

            case "gre.sequence_number":
                field.AssertShowDecimal(greDatagram.SequenceNumber);
                field.AssertNoFields();
                break;

            case "gre.offset":
                field.AssertShowDecimal(greDatagram.RoutingOffset);
                field.AssertNoFields();
                break;

            case "gre.routing":
                field.AssertShow("");
                field.AssertNoFields();
                break;

            case "gre.routing.address_family":
                if (_routingEntryIndex == greDatagram.Routing.Count)
                {
                    field.AssertShowDecimal(0);
                }
                else
                {
                    field.AssertShowDecimal((ushort)greDatagram.Routing[_routingEntryIndex].AddressFamily);
                }
                field.AssertNoFields();
                break;

            case "gre.routing.sre_offset":
                if (_routingEntryIndex == greDatagram.Routing.Count)
                {
                    field.AssertShowDecimal(0);
                }
                else
                {
                    field.AssertShowDecimal(greDatagram.Routing[_routingEntryIndex].PayloadOffset);
                }
                field.AssertNoFields();
                break;

            case "gre.routing.src_length":
                if (_routingEntryIndex == greDatagram.Routing.Count)
                {
                    field.AssertShowDecimal(0);
                }
                else
                {
                    field.AssertShowDecimal(greDatagram.Routing[_routingEntryIndex].PayloadLength);
                }
                field.AssertNoFields();
                break;

            case "gre.routing.information":
                if (_routingEntryIndex != greDatagram.Routing.Count)
                {
                    switch (greDatagram.Routing[_routingEntryIndex].AddressFamily)
                    {
                    case GreSourceRouteEntryAddressFamily.IpSourceRoute:
                        field.AssertValue(((GreSourceRouteEntryIp)greDatagram.Routing[_routingEntryIndex]).Addresses);
                        break;

                    case GreSourceRouteEntryAddressFamily.AsSourceRoute:
                        field.AssertValue(((GreSourceRouteEntryAs)greDatagram.Routing[_routingEntryIndex]).AsNumbers);
                        break;

                    default:
                        field.AssertValue(((GreSourceRouteEntryUnknown)greDatagram.Routing[_routingEntryIndex]).Data);
                        break;
                    }

                    ++_routingEntryIndex;
                }
                field.AssertNoFields();
                break;

            case "gre.proto":
                field.AssertShowDecimal((ushort)greDatagram.ProtocolType);
                field.AssertNoFields();
                break;

            case "gre.key":
                field.AssertShowDecimal(greDatagram.Key);
                field.AssertNoFields();
                break;

            case "data":
            case "data.data":
                field.AssertDataField(greDatagram.Payload);
                break;

            default:
                Assert.Fail("Invalid field name: " + field.Name());
                break;
            }

            return(true);
        }