protected override bool CompareField(XElement field, Datagram parentDatagram, Datagram datagram) { IpDatagram ipDatagram = (IpDatagram)parentDatagram; UdpDatagram udpDatagram = (UdpDatagram)datagram; switch (field.Name()) { case "udp.srcport": field.AssertShowDecimal(udpDatagram.SourcePort); break; case "udp.dstport": field.AssertShowDecimal(udpDatagram.DestinationPort); break; case "udp.port": Assert.IsTrue(ushort.Parse(field.Show()) == udpDatagram.SourcePort || ushort.Parse(field.Show()) == udpDatagram.DestinationPort); break; case "udp.length": field.AssertShowDecimal(udpDatagram.TotalLength); break; case "udp.checksum": field.AssertShowDecimal(udpDatagram.Checksum); if (udpDatagram.Checksum != 0) { foreach (var checksumField in field.Fields()) { switch (checksumField.Name()) { case "udp.checksum_good": checksumField.AssertShowDecimal(ipDatagram.IsTransportChecksumCorrect); break; case "udp.checksum_bad": if (checksumField.Show() == "1") Assert.IsFalse(ipDatagram.IsTransportChecksumCorrect); else checksumField.AssertShowDecimal(0); break; } } } break; case "udp.checksum_coverage": field.AssertShowDecimal(udpDatagram.TotalLength); break; case "udp.stream": break; default: throw new InvalidOperationException("Invalid udp field " + field.Name()); } return true; }
private static void CompareEthernetAddress(XElement element, MacAddress address) { foreach (var field in element.Fields()) { switch (field.Name()) { case "eth.addr": case "eth.dst_resolved": case "eth.addr_resolved": case "eth.src_resolved": field.AssertShow(address.ToString().ToLower()); field.AssertNoFields(); break; case "eth.ig": case "eth.lg": field.AssertNoFields(); break; case "_ws.expert": field.AssertNumFields(4); break; default: throw new InvalidOperationException("Invalid ethernet address field " + field.Name()); } } }
protected void CompareDatagram(XElement layer, Datagram parentDatagram, Datagram datagram) { foreach (var field in layer.Fields()) { if (!CompareField(field, parentDatagram, datagram)) break; } WiresharkCompareTests.CompareProtocols(datagram, layer); }
protected bool CompareDatagram(XElement layer, Datagram parentDatagram, Datagram datagram) { bool success = true; foreach (var element in layer.Fields()) { if (!CompareField(element, parentDatagram, datagram)) { success = false; break; } } WiresharkCompareTests.CompareProtocols(datagram, layer, success); return success; }
protected bool CompareDatagram(XElement layer, Datagram parentDatagram, Datagram datagram) { bool success = true; foreach (var element in layer.Fields()) { // TODO: Remove this hack when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11802 is fixed. IpV6Datagram ipV6ParentDatagram = parentDatagram as IpV6Datagram; if (ipV6ParentDatagram != null && (ipV6ParentDatagram.NextHeader == IpV4Protocol.IsoIp || ipV6ParentDatagram.ExtensionHeaders.NextHeader == IpV4Protocol.IsoIp)) return false; if (!CompareField(element, parentDatagram, datagram)) { success = false; break; } } WiresharkCompareTests.CompareProtocols(datagram, layer, success); return success; }
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; }
protected override bool CompareField(XElement field, Datagram datagram) { VLanTaggedFrameDatagram vLanTaggedFrameDatagram = (VLanTaggedFrameDatagram)datagram; switch (field.Name()) { case "vlan.priority": field.AssertNoFields(); field.AssertShowDecimal((byte)vLanTaggedFrameDatagram.PriorityCodePoint); break; case "vlan.cfi": field.AssertNoFields(); field.AssertShowDecimal(vLanTaggedFrameDatagram.CanonicalFormatIndicator); break; case "vlan.id": field.AssertNoFields(); field.AssertShowDecimal(vLanTaggedFrameDatagram.VLanIdentifier); break; case "vlan.etype": field.AssertNoFields(); field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType); break; case "vlan.len": field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType); if (field.Fields().Any()) { field.AssertNumFields(1); field.Fields().First().AssertName("_ws.expert"); } break; case "vlan.trailer": field.AssertNoFields(); if (!new[] { (EthernetType)1, (EthernetType)5, (EthernetType)12, (EthernetType)17, (EthernetType)29, (EthernetType)30, (EthernetType)43, (EthernetType)50, EthernetType.ReverseArp, // TODO: Support RARP EthernetType.ExtensibleAuthenticationProtocolOverLan, // TODO: Support this protocol. }.Contains( vLanTaggedFrameDatagram.EtherType)) { field.AssertValue(vLanTaggedFrameDatagram.ExtraData); } break; case "eth.padding": field.AssertNoFields(); if (!new[] { EthernetType.ExtensibleAuthenticationProtocolOverLan, // TODO: Support this protocol. }.Contains( vLanTaggedFrameDatagram.EtherType)) { field.AssertValue(vLanTaggedFrameDatagram.Trailer); } break; default: throw new InvalidOperationException("Invalid VLanTaggedFrame field " + field.Name()); } return true; }
protected override bool CompareField(XElement field, Datagram datagram) { IpV4Datagram ipV4Datagram = (IpV4Datagram)datagram; switch (field.Name()) { case "ip.version": field.AssertShowDecimal(ipV4Datagram.Version); field.AssertNoFields(); break; case "ip.hdr_len": field.AssertShowDecimal(ipV4Datagram.HeaderLength); field.AssertNoFields(); break; case "ip.dsfield": field.AssertShowDecimal((int)ipV4Datagram.TypeOfService); // TODO: Parse TypeOfService to Differentiated Services and ECN. break; case "ip.len": field.AssertShowDecimal(ipV4Datagram.TotalLength); field.AssertNoFields(); break; case "ip.id": field.AssertShowDecimal(ipV4Datagram.Identification); field.AssertNoFields(); break; case "ip.flags": field.AssertShowDecimal(((ushort)ipV4Datagram.Fragmentation.Options >> 13)); foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "ip.flags.rb": break; case "ip.flags.df": subfield.AssertShowDecimal((ipV4Datagram.Fragmentation.Options & IpV4FragmentationOptions.DoNotFragment) == IpV4FragmentationOptions.DoNotFragment); break; case "ip.flags.mf": subfield.AssertShowDecimal((ipV4Datagram.Fragmentation.Options & IpV4FragmentationOptions.MoreFragments) == IpV4FragmentationOptions.MoreFragments); break; default: throw new InvalidOperationException(string.Format("Invalid ip flags subfield {0}", subfield.Name())); } } break; case "ip.frag_offset": field.AssertShowDecimal(ipV4Datagram.Fragmentation.Offset); field.AssertNoFields(); break; case "ip.ttl": field.AssertShowDecimal(ipV4Datagram.Ttl); foreach (XElement subfield in field.Fields()) { switch (subfield.Name()) { case "_ws.expert": break; default: subfield.AssertNoFields(); throw new InvalidOperationException(string.Format("Invalid ip subfield {0}", subfield.Name())); } } break; case "ip.proto": field.AssertShowDecimal((byte)ipV4Datagram.Protocol); field.AssertNoFields(); break; case "ip.checksum": field.AssertShowDecimal(ipV4Datagram.HeaderChecksum); if (field.Showname().EndsWith(" [not all data available]")) { Assert.IsFalse(ipV4Datagram.IsValid); break; } foreach (var checksumField in field.Fields()) { switch (checksumField.Name()) { case "ip.checksum_good": checksumField.AssertNoFields(); // TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed. if (field.Showname().EndsWith(" [in ICMP error packet]")) break; checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect); break; case "ip.checksum_bad": if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength || ipV4Datagram.Length < ipV4Datagram.HeaderLength || // TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed. field.Showname().EndsWith(" [in ICMP error packet]")) break; checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect); break; } } break; case "ip.src": case "ip.src_host": field.AssertShow(ipV4Datagram.Source.ToString()); field.AssertNoFields(); break; case "ip.dst": case "ip.dst_host": // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10959 is fixed or (worst case) when MTU Reply and CommercialSecurity options are supported. if (ipV4Datagram.Options == null || !ipV4Datagram.Options.Any(option => option.OptionType == IpV4OptionType.MaximumTransmissionUnitReply || option.OptionType == IpV4OptionType.CommercialSecurity)) { field.AssertShow(ipV4Datagram.Destination.ToString()); } field.AssertNoFields(); break; case "ip.addr": case "ip.host": // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10959 is fixed or (worst case) when MTU Reply and CommercialSecurity options are supported. if (ipV4Datagram.Options == null || !ipV4Datagram.Options.Any(option => option.OptionType == IpV4OptionType.MaximumTransmissionUnitReply || option.OptionType == IpV4OptionType.CommercialSecurity)) { Assert.IsTrue(field.Show() == ipV4Datagram.Source.ToString() || field.Show() == ipV4Datagram.Destination.ToString()); } field.AssertNoFields(); break; case "ip.cur_rt": case "ip.cur_rt_host": field.AssertShow(ipV4Datagram.CurrentDestination.ToString()); break; case "": CompareIpV4Options(field, ipV4Datagram, ipV4Datagram.Options); break; default: throw new InvalidOperationException(string.Format("Invalid ip field {0}", field.Name())); } return true; }
private static void CompareFrame(XElement frame, Packet packet) { foreach (var field in frame.Fields()) { switch (field.Name()) { // case "frame.time": // string fieldShow = field.Show(); // if (fieldShow == "Not representable") // break; // fieldShow = fieldShow.Substring(0, fieldShow.Length - 2); // DateTime fieldTimestamp = fieldShow[4] == ' ' // ? DateTime.ParseExact(fieldShow, "MMM d, yyyy HH:mm:ss.fffffff", CultureInfo.InvariantCulture) // : DateTime.ParseExact(fieldShow, "MMM dd, yyyy HH:mm:ss.fffffff", CultureInfo.InvariantCulture); // MoreAssert.IsInRange(fieldTimestamp.AddSeconds(-2), fieldTimestamp.AddSeconds(2), packet.Timestamp, "Timestamp"); // break; case "frame.time_epoch": double timeEpoch = double.Parse(field.Show(), CultureInfo.InvariantCulture); DateTime fieldTimestamp = new DateTime(1970, 1, 1).AddSeconds(timeEpoch); MoreAssert.IsInRange(fieldTimestamp.AddMilliseconds(-1), fieldTimestamp.AddMilliseconds(1), packet.Timestamp.ToUniversalTime(), "Timestamp"); break; case "frame.cap_len": field.AssertShowDecimal(packet.Length); break; } } }
protected override bool CompareField(XElement field, Datagram datagram) { IpV4Datagram ipV4Datagram = (IpV4Datagram)datagram; switch (field.Name()) { case "ip.version": field.AssertShowDecimal(ipV4Datagram.Version); break; case "ip.hdr_len": field.AssertShowDecimal(ipV4Datagram.HeaderLength); break; case "ip.dsfield": field.AssertShowDecimal((int)ipV4Datagram.TypeOfService); break; case "ip.len": field.AssertShowDecimal(ipV4Datagram.TotalLength); break; case "ip.id": field.AssertShowHex(ipV4Datagram.Identification); break; case "ip.flags": field.AssertShowHex((byte)((ushort)ipV4Datagram.Fragmentation.Options >> 13)); break; case "ip.frag_offset": field.AssertShowDecimal(ipV4Datagram.Fragmentation.Offset); break; case "ip.ttl": field.AssertShowDecimal(ipV4Datagram.Ttl); break; case "ip.proto": field.AssertShowDecimal((byte)ipV4Datagram.Protocol); break; case "ip.checksum": field.AssertShowHex(ipV4Datagram.HeaderChecksum); foreach (var checksumField in field.Fields()) { switch (checksumField.Name()) { case "ip.checksum_good": checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect); break; case "ip.checksum_bad": if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength || ipV4Datagram.Length < ipV4Datagram.HeaderLength) break; checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect); break; } } break; case "ip.src": case "ip.src_host": field.AssertShow(ipV4Datagram.Source.ToString()); break; case "ip.dst": case "ip.dst_host": if (field.Show() != ipV4Datagram.Destination.ToString()) { // TODO: Remove this fallback once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7043 is fixed. field.AssertShow(ipV4Datagram.CurrentDestination.ToString()); Assert.IsTrue(ipV4Datagram.Options.IsBadForWireshark(), string.Format("Expected destination: {0}. Destination: {1}. Current destination: {2}.", field.Show(), ipV4Datagram.Destination, ipV4Datagram.CurrentDestination)); } break; case "ip.addr": case "ip.host": Assert.IsTrue(field.Show() == ipV4Datagram.Source.ToString() || field.Show() == ipV4Datagram.Destination.ToString() || // TODO: Remove this fallback once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7043 is fixed. field.Show() == ipV4Datagram.CurrentDestination.ToString() && ipV4Datagram.Options.IsBadForWireshark(), string.Format("Expected ip: {0}. ", field.Show()) + (ipV4Datagram.IsValid ? string.Format("Source: {0}. Destination: {1}. Current destination: {2}.", ipV4Datagram.Source, ipV4Datagram.Destination, ipV4Datagram.CurrentDestination) : "")); break; case "": CompareIpV4Options(field, ipV4Datagram.Options); break; default: throw new InvalidOperationException("Invalid ip field " + field.Name()); } return true; }
private static void CompareIpV4Options(XElement element, IpV4Datagram ipV4Datagram, IpV4Options options) { int currentOptionIndex = 0; foreach (var field in element.Fields()) { if (currentOptionIndex >= options.Count) { Assert.IsFalse(options.IsValid); Assert.IsTrue(field.Show() == "Commercial IP security option" || field.Show() == "Loose source route (length byte past end of options)" || field.Show() == "Time stamp:" || field.Show().StartsWith("Unknown") || field.Show().StartsWith("Security") || field.Show().StartsWith("Router Alert (with option length = ") || field.Show().StartsWith("Stream ID (with option length = ") || field.Show().Contains("with too") || field.Show().Contains(" bytes says option goes past end of options") || field.Show().Contains("(length byte past end of options)") || XElementExtensions.Show(field.Fields().First()).StartsWith("Pointer: ") && XElementExtensions.Show(field.Fields().First()).EndsWith(" (points to middle of address)") || field.Fields().Where(value => value.Show() == "(suboption would go past end of option)").Count() != 0, field.Show()); break; } IpV4Option option = options[currentOptionIndex++]; switch (option.OptionType) { case IpV4OptionType.NoOperation: case IpV4OptionType.EndOfOptionList: field.AssertShow(option.OptionType == IpV4OptionType.EndOfOptionList ? "End of Options List (EOL)" : "No Operation (NOP)"); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.BasicSecurity: field.AssertShow("Security (" + option.Length + " bytes)"); var basicSecurity = (IpV4OptionBasicSecurity)option; int basicSecurityFlagsIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.sec_cl": subfield.AssertNoFields(); subfield.AssertShowDecimal((byte)basicSecurity.ClassificationLevel); break; case "ip.opt.sec_prot_auth_flags": foreach (XElement flagField in subfield.Fields()) { flagField.AssertNoFields(); switch (flagField.Name()) { case "ip.opt.sec_prot_auth_genser": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.Genser) == IpV4OptionSecurityProtectionAuthorities.Genser); break; case "ip.opt.sec_prot_auth_siop_esi": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities. SingleIntegrationOptionalPlanExtremelySensitiveInformation) == IpV4OptionSecurityProtectionAuthorities. SingleIntegrationOptionalPlanExtremelySensitiveInformation); break; case "ip.opt.sec_prot_auth_sci": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation) == IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation); break; case "ip.opt.sec_prot_auth_nsa": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.Nsa) == IpV4OptionSecurityProtectionAuthorities.Nsa); break; case "ip.opt.sec_prot_auth_doe": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy) == IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy); break; case "ip.opt.sec_prot_auth_unassigned": flagField.AssertShowDecimal(0); break; case "ip.opt.sec_prot_auth_fti": flagField.AssertShowDecimal(basicSecurity.Length - basicSecurityFlagsIndex > 4); break; default: throw new InvalidOperationException("Invalid flag field " + flagField.Name()); } } ++basicSecurityFlagsIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.StreamIdentifier: field.AssertShow("Stream ID (" + option.Length + " bytes): " + ((IpV4OptionStreamIdentifier)option).Identifier); var streamIdentifier = (IpV4OptionStreamIdentifier)option; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.sid": subfield.AssertNoFields(); subfield.AssertShowDecimal(streamIdentifier.Identifier); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.LooseSourceRouting: field.AssertShow("Loose Source Route (" + option.Length + " bytes)"); var looseSourceRouting = (IpV4OptionLooseSourceRouting)option; int looseRouteIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (looseSourceRouting.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.rec_rt": case "ip.dst": case "ip.addr": case "ip.dst_host": case "ip.src_rt": subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString()); subfield.AssertNoFields(); break; case "ip.rec_rt_host": case "ip.host": case "ip.src_rt_host": subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString()); subfield.AssertNoFields(); ++looseRouteIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.RecordRoute: field.AssertShow("Record Route (" + option.Length + " bytes)"); var recordRoute = (IpV4OptionRecordRoute)option; int recordRouteIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (recordRoute.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.rec_rt": case "ip.empty_rt": subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString()); subfield.AssertNoFields(); break; case "ip.rec_rt_host": case "ip.empty_rt_host": subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString()); subfield.AssertNoFields(); ++recordRouteIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.StrictSourceRouting: field.AssertShow("Strict Source Route (" + option.Length + " bytes)"); var strictSourceRouting = (IpV4OptionStrictSourceRouting)option; int strictSourceRoutingIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (strictSourceRouting.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.dst": case "ip.addr": case "ip.dst_host": case "ip.rec_rt": case "ip.src_rt": subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString()); subfield.AssertNoFields(); break; case "ip.host": case "ip.rec_rt_host": case "ip.src_rt_host": subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString()); subfield.AssertNoFields(); ++strictSourceRoutingIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.RouterAlert: var routerAlert = (IpV4OptionRouterAlert)option; field.AssertShow("Router Alert (" + option.Length + " bytes): " + ((routerAlert.Value != 0) ? "Reserved (" + routerAlert.Value + ")" : "Router shall examine packet (0)")); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ra": subfield.AssertNoFields(); subfield.AssertShowDecimal(routerAlert.Value); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.TraceRoute: field.AssertShow("Traceroute (" + option.Length + " bytes)"); var traceRoute = (IpV4OptionTraceRoute)option; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "ip.opt.id_number": subfield.AssertShowDecimal(traceRoute.Identification); break; case "ip.opt.ohc": subfield.AssertShowDecimal(traceRoute.OutboundHopCount); break; case "ip.opt.rhc": subfield.AssertShowDecimal(traceRoute.ReturnHopCount); break; case "ip.opt.originator": subfield.AssertShow(traceRoute.OriginatorIpAddress.ToString()); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.InternetTimestamp: field.AssertShow("Time Stamp (" + option.Length + " bytes)"); var timestamp = (IpV4OptionTimestamp)option; int timestampIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "": var subfieldParts = subfield.Show().Split(new[] { ':', '=', ',' }, StringSplitOptions.RemoveEmptyEntries); string subfieldValue = subfieldParts[1].Trim(); switch (subfieldParts[0].Trim()) { case "Pointer": Assert.AreEqual(timestamp.PointedIndex, int.Parse(subfieldValue) / 4 - 1); break; case "Overflow": Assert.AreEqual(timestamp.Overflow.ToString(), subfieldValue); break; case "Flag": switch (timestamp.TimestampType) { case IpV4OptionTimestampType.AddressAndTimestamp: Assert.AreEqual("Time stamp and address", subfieldValue); break; case IpV4OptionTimestampType.TimestampOnly: Assert.AreEqual("Time stamps only", subfieldValue); break; case IpV4OptionTimestampType.AddressPrespecified: Assert.AreEqual("Time stamps for prespecified addresses", subfieldValue); break; default: throw new InvalidOperationException("Invalid timestamp type: " + timestamp.TimestampType); } break; case "Time stamp": var timestampOnly = (IpV4OptionTimestampOnly)timestamp; Assert.AreEqual(timestampOnly.Timestamps[timestampIndex].MillisecondsSinceMidnightUniversalTime, uint.Parse(subfieldValue)); ++timestampIndex; break; case "Address": Assert.AreEqual(4, subfieldParts.Length); var timestampAndAddress = (IpV4OptionTimestampAndAddress)timestamp; Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].Address.ToString(), subfieldParts[1].Trim()); Assert.AreEqual("time stamp", subfieldParts[2].Trim()); Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].TimeOfDay.MillisecondsSinceMidnightUniversalTime, uint.Parse(subfieldParts[3])); ++timestampIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Show()); } break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.QuickStart: IpV4OptionQuickStart quickStart = (IpV4OptionQuickStart)option; StringBuilder quickStartWireshark = new StringBuilder("Quick-Start (" + option.Length + " bytes): "); quickStartWireshark.Append(quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest ? "Rate request" : "Rate report"); quickStartWireshark.Append(" (" + (byte)quickStart.QuickStartFunction + ")"); quickStartWireshark.Append(", "); if (quickStart.RateKbps == 0) quickStartWireshark.Append("0 bit/s"); else if (quickStart.RateKbps < 1024) quickStartWireshark.Append(quickStart.RateKbps + " Kbit/s"); else if (quickStart.RateKbps < 1024 * 1024) quickStartWireshark.Append(((double)quickStart.RateKbps / 1000).ToString(CultureInfo.InvariantCulture) + " Mbit/s"); else quickStartWireshark.Append(((double)quickStart.RateKbps / 1000000).ToString(CultureInfo.InvariantCulture) + " Gbit/s"); if (quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest) quickStartWireshark.Append(", QS TTL " + quickStart.Ttl + ", QS TTL diff " + (256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256); field.AssertShow(quickStartWireshark.ToString()); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "ip.opt.qs_func": subfield.AssertShowDecimal((byte)quickStart.QuickStartFunction); break; case "ip.opt.qs_rate": subfield.AssertShowDecimal(quickStart.Rate); break; case "ip.opt.qs_ttl": case "ip.opt.qs_unused": subfield.AssertShowDecimal(quickStart.Ttl); break; case "ip.opt.qs_ttl_diff": subfield.AssertShowDecimal((256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256); break; case "ip.opt.qs_nonce": subfield.AssertShowDecimal(quickStart.Nonce); break; case "ip.opt.qs_reserved": subfield.AssertShowDecimal(0); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.MaximumTransmissionUnitProbe: // TODO: Support MTU Proble. Assert.IsTrue(field.Show().StartsWith("MTU Probe (" + option.Length + " bytes): ")); break; case (IpV4OptionType)12: // TODO: Support 12. if (option.Length != 4) field.AssertShow("MTU Reply (with option length = " + option.Length + " bytes; should be 4)"); else Assert.IsTrue(field.Show().StartsWith("MTU Reply (4 bytes): ")); break; case (IpV4OptionType)133: // TODO: Support 133. if (option.Length >= 3) field.AssertShow("Extended Security (" + option.Length + " bytes)"); else field.AssertShow("Extended Security (with option length = " + option.Length + " bytes; should be >= 3)"); break; case (IpV4OptionType)134: // TODO: Support 134. field.AssertShow("Commercial Security " + (option.Length >= 10 ? "(" + option.Length + " bytes)" : "(with option length = " + option.Length + " bytes; should be >= 10)")); break; case (IpV4OptionType)149: // TODO: Support 149. if (option.Length >= 6) field.AssertShow("Selective Directed Broadcast (" + option.Length + " bytes)"); else field.AssertShow("Selective Directed Broadcast (with option length = " + option.Length + " bytes; should be >= 6)"); break; default: field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x2") + ") (" + option.Length + " bytes)"); field.AssertNoFields(); break; } } }
private void CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord) { var data = resourceRecord.Data; string dataFieldName = dataField.Name(); string dataFieldShow = dataField.Show(); string dataFieldShowUntilColon = dataFieldShow.Split(':')[0]; switch (resourceRecord.DnsType) { case DnsType.A: switch (dataFieldName) { case "dns.resp.addr": dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString()); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Ns: dataField.AssertName("dns.resp.ns"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.Md: // 3. case DnsType.MailForwarder: // 4. case DnsType.Mailbox: // 7. case DnsType.MailGroup: // 8. case DnsType.MailRename: // 9. dataField.AssertName(""); dataField.AssertShow("Host: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.CName: dataField.AssertName("dns.resp.primaryname"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.StartOfAuthority: dataField.AssertName(""); var soaData = (DnsResourceDataStartOfAuthority)data; switch (dataFieldShowUntilColon) { case "Primary name server": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.MainNameServer)); break; case "Responsible authority's mailbox": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.ResponsibleMailbox)); break; case "Serial number": dataField.AssertShow(dataFieldShowUntilColon + ": " + soaData.Serial); break; case "Refresh interval": dataField.AssertValue(soaData.Refresh); break; case "Retry interval": dataField.AssertValue(soaData.Retry); break; case "Expiration limit": dataField.AssertValue(soaData.Expire); break; case "Minimum TTL": dataField.AssertValue(soaData.MinimumTtl); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.Wks: dataField.AssertName(""); var wksData = (DnsResourceDataWellKnownService)data; switch (dataFieldShowUntilColon) { case "Addr": dataField.AssertShow(dataFieldShowUntilColon + ": " + wksData.Address); break; case "Protocol": dataField.AssertValue((byte)wksData.Protocol); break; case "Bits": while (wksData.Bitmap[_wksBitmapIndex] == 0x00) ++_wksBitmapIndex; dataField.AssertValue(wksData.Bitmap[_wksBitmapIndex++]); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.Ptr: dataField.AssertName(""); dataField.AssertShow("Domain name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.HInfo: dataField.AssertName(""); var hInfoData = (DnsResourceDataHostInformation)data; switch (dataFieldShowUntilColon) { case "CPU": dataField.AssertValue(new[] {(byte)hInfoData.Cpu.Length}.Concat(hInfoData.Cpu)); break; case "OS": dataField.AssertValue(new[] {(byte)hInfoData.Os.Length}.Concat(hInfoData.Os)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.MInfo: dataField.AssertName(""); var mInfoData = (DnsResourceDataMailingListInfo)data; switch (dataFieldShowUntilColon) { case "Responsible Mailbox": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.MailingList)); break; case "Error Mailbox": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.ErrorMailbox)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.MailExchange: var mxData = (DnsResourceDataMailExchange)data; switch (dataFieldShowUntilColon) { case "Preference": dataField.AssertShow(dataFieldShowUntilColon + ": " + mxData.Preference); break; case "Mail exchange": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mxData.MailExchangeHost)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.Txt: // 16. case DnsType.Spf: // 99. var txtData = (DnsResourceDataText)data; dataField.AssertShow("Text: " + txtData.Text[_txtIndex++].Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false)); dataField.AssertNoFields(); break; case DnsType.ResponsiblePerson: dataField.AssertName(""); var rpData = (DnsResourceDataResponsiblePerson)data; switch (dataFieldShowUntilColon) { case "Mailbox": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.Mailbox)); break; case "TXT RR": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.TextDomain)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.AfsDatabase: dataField.AssertName(""); var afsDbData = (DnsResourceDataAfsDatabase)data; switch (dataFieldShowUntilColon) { case "Subtype": dataField.AssertShow(dataFieldShowUntilColon + ": " + (ushort)afsDbData.Subtype); break; case "Hostname": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(afsDbData.HostName)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.X25: dataField.AssertName(""); dataField.AssertShow("PSDN-Address: " + ((DnsResourceDataString)data).String.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false)); dataField.AssertNoFields(); break; case DnsType.Isdn: dataField.AssertName(""); var isdnData = (DnsResourceDataIsdn)data; switch (dataFieldShowUntilColon) { case "ISDN Address": dataField.AssertShow(dataFieldShowUntilColon + ": " + isdnData.IsdnAddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false)); break; case "Subaddress": dataField.AssertShow(dataFieldShowUntilColon + ": " + isdnData.Subaddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.RouteThrough: dataField.AssertName(""); var rtData = (DnsResourceDataRouteThrough)data; switch (dataFieldShowUntilColon) { case "Preference": dataField.AssertShow(dataFieldShowUntilColon + ": " + rtData.Preference); break; case "Intermediate-Host": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rtData.IntermediateHost)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.NetworkServiceAccessPoint: var nsapData = (DnsResourceDataNetworkServiceAccessPoint)data; switch (dataFieldName) { case "dns.nsap.rdata": byte[] nsapId = new byte[6]; nsapId.Write(0, nsapData.SystemIdentifier, Endianity.Big); dataField.AssertValue(nsapData.AreaAddress.Concat(nsapId).Concat(nsapData.Selector)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.NetworkServiceAccessPointPointer: dataField.AssertName(""); dataField.AssertShow("Owner: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.Key: dataField.AssertName(""); var keyData = (DnsResourceDataKey)data; switch (dataFieldShowUntilColon) { case "Flags": foreach (var flagField in dataField.Fields()) { int flagCount = GetFlagCount(flagField); switch (flagCount) { case 0: flagField.AssertShow(keyData.AuthenticationProhibited ? "1... .... .... .... = Key prohibited for authentication" : "0... .... .... .... = Key allowed for authentication"); break; case 1: flagField.AssertShow(keyData.ConfidentialityProhibited ? ".1.. .... .... .... = Key prohibited for confidentiality" : ".0.. .... .... .... = Key allowed for confidentiality"); break; case 2: flagField.AssertShow(keyData.Experimental ? "..1. .... .... .... = Key is experimental or optional" : "..0. .... .... .... = Key is required"); break; case 5: flagField.AssertShow(keyData.UserAssociated ? ".... .1.. .... .... = Key is associated with a user" : ".... .0.. .... .... = Key is not associated with a user"); break; case 6: flagField.AssertShow(keyData.NameType == DnsKeyNameType.NonZoneEntity ? ".... ..1. .... .... = Key is associated with the named entity" : ".... ..0. .... .... = Key is not associated with the named entity"); break; case 8: flagField.AssertShow(keyData.IpSec ? ".... .... 1... .... = Key is valid for use with IPSEC" : ".... .... 0... .... = Key is not valid for use with IPSEC"); break; case 9: flagField.AssertShow(keyData.Email ? ".... .... .1.. .... = Key is valid for use with MIME security multiparts" : ".... .... .0.. .... = Key is not valid for use with MIME security multiparts"); break; case 12: Assert.AreEqual(flagField.Show().Substring(19), " = Signatory = " + (byte)keyData.Signatory); break; default: throw new InvalidOperationException("Invalid flag count " + flagCount); } } break; case "Protocol": dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)keyData.Protocol); dataField.AssertNoFields(); break; case "Algorithm": dataField.AssertValue((byte)keyData.Algorithm); dataField.AssertNoFields(); break; case "Key id": // TODO: Calculate key tag. dataField.AssertNoFields(); break; case "Public key": byte[] flagsExtension; if (keyData.FlagsExtension == null) { flagsExtension = new byte[0]; } else { flagsExtension = new byte[2]; flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big); } dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey)); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } break; case DnsType.Signature: // 24. case DnsType.ResourceRecordSignature: // 46. dataField.AssertName(""); var sigData = (DnsResourceDataSignature)data; switch (dataFieldShowUntilColon) { case "Type covered": dataField.AssertValue((ushort)sigData.TypeCovered); break; case "Algorithm": dataField.AssertValue((byte)sigData.Algorithm); break; case "Labels": dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.Labels); break; case "Original TTL": dataField.AssertValue(sigData.OriginalTtl); break; case "Signature expiration": dataField.AssertValue(sigData.SignatureExpiration); break; case "Time signed": dataField.AssertValue(sigData.SignatureInception); break; case "Id of signing key(footprint)": dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.KeyTag); break; case "Signer's name": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(sigData.SignersName)); break; case "Signature": dataField.AssertValue(sigData.Signature); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.PointerX400: dataField.AssertName(""); var pxData = (DnsResourceDataX400Pointer)data; switch (dataFieldShowUntilColon) { case "Preference": dataField.AssertShow(dataFieldShowUntilColon + ": " + pxData.Preference); break; case "MAP822": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.Map822)); break; case "MAPX400": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.MapX400)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.GPos: dataField.AssertName(""); var gposData = (DnsResourceDataGeographicalPosition)data; switch (dataFieldShowUntilColon) { case "Longitude": dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Longitude); break; case "Latitude": dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Latitude); break; case "Altitude": dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Altitude); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.Aaaa: dataField.AssertName(""); dataField.AssertShow("Addr: " + GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data)); break; case DnsType.Loc: dataField.AssertName(""); var locData = (DnsResourceDataLocationInformation)data; switch (dataFieldShowUntilColon) { case "Version": dataField.AssertShow(dataFieldShowUntilColon + ": " + locData.Version); break; case "Data": dataField.AssertShow("Data"); break; case "Size": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.Size)); break; case "Horizontal precision": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.HorizontalPrecision)); break; case "Vertical precision": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.VerticalPrecision)); break; case "Latitude": dataField.AssertValue(locData.Latitude); break; case "Longitude": dataField.AssertValue(locData.Longitude); break; case "Altitude": dataField.AssertValue(locData.Altitude); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon); } dataField.AssertNoFields(); break; case DnsType.NextDomain: dataField.AssertName(""); var nxtData = (DnsResourceDataNextDomain)data; switch (dataFieldShowUntilColon) { case "Next domain name": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nxtData.NextDomainName)); break; case "RR type in bit map": DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First(); DnsType expectedType; if (!TryGetDnsType(dataFieldShow, out expectedType)) throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType)); Assert.AreEqual(expectedType, actualType); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.ServerSelection: dataField.AssertName(""); var srvData = (DnsResourceDataServerSelection)data; switch (dataFieldShowUntilColon) { case "Priority": dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Priority); break; case "Weight": dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Weight); break; case "Port": dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Port); break; case "Target": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(srvData.Target)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon); } dataField.AssertNoFields(); break; case DnsType.NaPtr: dataField.AssertName(""); var naPtrData = (DnsResourceDataNamingAuthorityPointer)data; switch (dataFieldShowUntilColon) { case "Order": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Order); break; case "Preference": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Preference); break; case "Flags length": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Flags.Length); break; case "Flags": dataField.AssertValue(naPtrData.Flags); break; case "Service length": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Services.Length); break; case "Service": dataField.AssertValue(naPtrData.Services); break; case "Regex length": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.RegularExpression.Length); break; case "Regex": dataField.AssertValue(naPtrData.RegularExpression); break; case "Replacement length": dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Replacement.NonCompressedLength); break; case "Replacement": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(naPtrData.Replacement)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.KeyExchanger: dataField.AssertName(""); var kxData = (DnsResourceDataKeyExchanger)data; switch (dataFieldShowUntilColon) { case "Preference": dataField.AssertShow(dataFieldShowUntilColon + ": 0"); dataField.AssertValue(kxData.Preference); break; case "Key exchange": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(kxData.KeyExchangeHost)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.Cert: dataField.AssertName(""); var certData = (DnsResourceDataCertificate)data; switch (dataFieldShowUntilColon) { case "Type": dataField.AssertValue((ushort)certData.CertificateType); break; case "Key footprint": dataField.AssertValue(certData.KeyTag); break; case "Algorithm": dataField.AssertValue((byte)certData.Algorithm); break; case "Public key": dataField.AssertValue(certData.Certificate); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.A6: var a6Data = (DnsResourceDataA6)data; switch (dataFieldShowUntilColon) { case "Prefix len": dataField.AssertShow(dataFieldShowUntilColon + ": " + a6Data.PrefixLength); break; case "Address suffix": Assert.AreEqual(new IpV6Address(dataFieldShow.Substring(dataFieldShowUntilColon.Length + 2)), a6Data.AddressSuffix); break; case "Prefix name": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(a6Data.PrefixName)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.DName: dataField.AssertName(""); dataField.AssertShow("Target name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.Opt: var optResourceRecord = (DnsOptResourceRecord)resourceRecord; var optData = (DnsResourceDataOptions)data; switch (dataFieldName) { case "": switch (dataFieldShowUntilColon) { case "UDP payload size": dataField.AssertShow(dataFieldShowUntilColon + ": " + optResourceRecord.SendersUdpPayloadSize); dataField.AssertNoFields(); break; case "Higher bits in extended RCODE": dataField.AssertValue(optResourceRecord.ExtendedReturnCode); dataField.AssertNoFields(); break; case "EDNS0 version": dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)optResourceRecord.Version); dataField.AssertNoFields(); break; case "Z": ushort flags = (ushort)optResourceRecord.Flags; dataField.AssertValue(flags); if (dataField.Fields().Any()) { dataField.AssertNumFields(2); dataField.Fields().First().AssertShow("Bit 0 (DO bit): 1 (Accepts DNSSEC security RRs)"); // TODO - uncomment once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7045 is fixed. // dataField.Fields().Last().AssertShow("Bits 1-15: 0x" + (flags & 0x7FFF).ToString("x") + " (reserved)"); } else { Assert.AreEqual<ushort>(0, (ushort)optResourceRecord.Flags); } break; case "Data": Assert.AreEqual(dataField.Value().Length, 2 * optData.Options.Options.Sum(option => option.Length)); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } break; case "dns.resp.len": dataField.AssertShow("Data length: " + optData.Options.Options.Sum(option => option.DataLength)); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Apl: var aplData = (DnsResourceDataAddressPrefixList)data; switch (dataFieldName) { case "": switch (dataFieldShowUntilColon) { case "Address Family": dataField.AssertValue((ushort)aplData.Items[_aplItemIndex++].AddressFamily); break; case "IPv4 address": case "IPv6 address": dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldShowUntilColon); } dataField.AssertNoFields(); break; case "dns.apl.coded.prefix": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength); break; case "dns.apl.negation": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].Negation); break; case "dns.apl.afdlength": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.DelegationSigner: // 43. case DnsType.DnsSecLookAsideValidation: // 32769. dataField.AssertName(""); var dsData = (DnsResourceDataDelegationSigner)data; switch (dataFieldShowUntilColon) { case "Key id": dataField.AssertShow(dataFieldShowUntilColon + ": " + dsData.KeyTag.ToString("0000")); break; case "Algorithm": dataField.AssertValue((byte)dsData.Algorithm); break; case "Digest type": dataField.AssertValue((byte)dsData.DigestType); break; case "Public key": dataField.AssertValue(dsData.Digest); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.SshFingerprint: var sshFpData = (DnsResourceDataSshFingerprint)data; switch (dataFieldName) { case "": switch (dataFieldShowUntilColon) { case "Algorithm": dataField.AssertValue((byte)sshFpData.Algorithm); break; case "Fingerprint type": dataField.AssertValue((byte)sshFpData.FingerprintType); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } break; case "dns.sshfp.fingerprint": dataField.AssertValue(sshFpData.Fingerprint); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.IpSecKey: dataField.AssertName(""); var ipSecKeyData = (DnsResourceDataIpSecKey)data; switch (dataFieldShowUntilColon) { case "Gateway precedence": dataField.AssertValue(ipSecKeyData.Precedence); break; case "Algorithm": dataField.AssertValue((byte)ipSecKeyData.Algorithm); break; case "Gateway": switch (ipSecKeyData.GatewayType) { case DnsGatewayType.None: dataField.AssertShow(dataFieldShowUntilColon + ": no gateway"); break; case DnsGatewayType.IpV4: dataField.AssertShow(dataFieldShowUntilColon + ": " + ((DnsGatewayIpV4)ipSecKeyData.Gateway).Value); break; case DnsGatewayType.IpV6: dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkIpV6(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value)); break; case DnsGatewayType.DomainName: dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value)); break; default: throw new InvalidOperationException("Invalid Gateway Type " + ipSecKeyData.GatewayType); } break; case "Public key": dataField.AssertValue(ipSecKeyData.PublicKey); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.NSec: dataField.AssertName(""); var nSecData = (DnsResourceDataNextDomainSecure)data; switch (dataFieldShowUntilColon) { case "Next domain name": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nSecData.NextDomainName)); break; case "RR type in bit map": DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++]; DnsType expectedType; if (!TryGetDnsType(dataFieldShow, out expectedType)) throw new InvalidOperationException(string.Format("Failed parsing type from {0} : {1}", dataFieldShow, actualType)); Assert.AreEqual(expectedType, actualType); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.DnsKey: dataField.AssertName(""); var dnsKeyData = (DnsResourceDataDnsKey)data; switch (dataFieldShowUntilColon) { case "Flags": foreach (var flagField in dataField.Fields()) { int flagCount = GetFlagCount(flagField); switch (flagCount) { case 7: flagField.AssertShow(dnsKeyData.ZoneKey ? ".... ...1 .... .... = This is the zone key for the specified zone" : ".... ...0 .... .... = This is not a zone key"); break; case 8: flagField.AssertShow(dnsKeyData.Revoke ? ".... .... 1... .... = Key is revoked" : ".... .... 0... .... = Key is not revoked"); break; case 15: flagField.AssertShow(dnsKeyData.SecureEntryPoint ? ".... .... .... ...1 = Key is a Key Signing Key" : ".... .... .... ...0 = Key is a Zone Signing Key"); break; default: throw new InvalidOperationException("Invalid DNS data flag field " + flagField.Show()); } } break; case "Protocol": dataField.AssertShow(dataFieldShowUntilColon + ": " + dnsKeyData.Protocol); dataField.AssertNoFields(); break; case "Algorithm": dataField.AssertValue((byte)dnsKeyData.Algorithm); dataField.AssertNoFields(); break; case "Key id": // TODO: Calculate key tag. dataField.AssertNoFields(); break; case "Public key": dataField.AssertValue(dnsKeyData.PublicKey); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } break; case DnsType.DynamicHostConfigurationId: switch (dataFieldName) { case "dns.dhcid.rdata": dataField.AssertValue(((DnsResourceDataAnything)data).Data); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.NSec3: var nSec3Data = (DnsResourceDataNextDomainSecure3)data; switch (dataFieldName) { case "dns.nsec3.algo": dataField.AssertShowDecimal((byte)nSec3Data.HashAlgorithm); dataField.AssertNoFields(); break; case "dns.nsec3.flags": dataField.AssertShowDecimal((byte)nSec3Data.Flags); foreach (var flagField in dataField.Fields()) { string flagFieldName = flagField.Name(); switch (flagFieldName) { case "dns.nsec3.flags.opt_out": dataField.AssertShowDecimal((nSec3Data.Flags & DnsSecNSec3Flags.OptOut) == DnsSecNSec3Flags.OptOut); break; default: throw new InvalidOperationException("Invalid DNS resource data flag field name " + flagFieldName); } } break; case "dns.nsec3.iterations": dataField.AssertShowDecimal(nSec3Data.Iterations); dataField.AssertNoFields(); break; case "dns.nsec3.salt_length": dataField.AssertShowDecimal(nSec3Data.Salt.Length); dataField.AssertNoFields(); break; case "dns.nsec3.salt_value": dataField.AssertValue(nSec3Data.Salt); dataField.AssertNoFields(); break; case "dns.nsec3.hash_length": dataField.AssertShowDecimal(nSec3Data.NextHashedOwnerName.Length); dataField.AssertNoFields(); break; case "dns.nsec3.hash_value": dataField.AssertValue(nSec3Data.NextHashedOwnerName); dataField.AssertNoFields(); break; case "": DnsType expectedType = nSec3Data.TypesExist[_nSec3TypeIndex++]; Assert.IsTrue(dataField.Show().StartsWith("RR type in bit map: ")); if (dataField.Show().EndsWith(string.Format("({0})", (ushort)expectedType))) dataField.AssertShow(string.Format("RR type in bit map: Unknown ({0})", (ushort)expectedType)); else Assert.IsTrue( dataFieldShow.Replace("-", "").StartsWith("RR type in bit map: " + GetWiresharkDnsType(expectedType).Replace("-", "")), string.Format("{0} : {1}", dataFieldShow, GetWiresharkDnsType(expectedType))); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } break; case DnsType.NSec3Parameters: var nSec3ParamData = (DnsResourceDataNextDomainSecure3Parameters)data; switch (dataFieldName) { case "dns.nsec3.algo": dataField.AssertShowDecimal((byte)nSec3ParamData.HashAlgorithm); break; case "dns.nsec3.flags": dataField.AssertShowDecimal((byte)nSec3ParamData.Flags); break; case "dns.nsec3.iterations": dataField.AssertShowDecimal(nSec3ParamData.Iterations); break; case "dns.nsec3.salt_length": dataField.AssertShowDecimal(nSec3ParamData.Salt.Length); break; case "dns.nsec3.salt_value": dataField.AssertShow(nSec3ParamData.Salt); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.Hip: var hipData = (DnsResourceDataHostIdentityProtocol)data; switch (dataFieldName) { case "": switch (dataFieldShowUntilColon) { case "HIT length": dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.HostIdentityTag.Length); break; case "PK algorithm": dataField.AssertValue((byte)hipData.PublicKeyAlgorithm); break; case "PK length": dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.PublicKey.Length); break; case "Rendezvous Server": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++])); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } break; case "dns.hip.hit": dataField.AssertShow(hipData.HostIdentityTag); break; case "dns.hip.pk": dataField.AssertShow(hipData.PublicKey); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.TKey: dataField.AssertName(""); var tKeyData = (DnsResourceDataTransactionKey)data; switch (dataFieldShowUntilColon) { case "Algorithm name": dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(tKeyData.Algorithm)); break; case "Signature inception": dataField.AssertValue(tKeyData.Inception); break; case "Signature expiration": dataField.AssertValue(tKeyData.Expiration); break; case "Mode": dataField.AssertValue((ushort)tKeyData.Mode); break; case "Error": dataField.AssertValue((ushort)tKeyData.Error); break; case "Key Size": dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Key.Length); break; case "Key Data": dataField.AssertValue(tKeyData.Key); break; case "Other Size": dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Other.Length); break; case "Other Data": dataField.AssertValue(tKeyData.Other); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case DnsType.TransactionSignature: var tSigData = (DnsResourceDataTransactionSignature)data; switch (dataFieldName) { case "dns.tsig.algorithm_name": dataField.AssertShow(GetWiresharkDomainName(tSigData.Algorithm)); dataField.AssertNoFields(); break; case "": switch (dataFieldShowUntilColon) { case "Time signed": dataField.AssertValue(tSigData.TimeSigned); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case "dns.tsig.fudge": dataField.AssertShowDecimal(tSigData.Fudge); dataField.AssertNoFields(); break; case "dns.tsig.mac_size": dataField.AssertShowDecimal(tSigData.MessageAuthenticationCode.Length); dataField.AssertNoFields(); break; case "dns.tsig.mac": dataField.AssertShow(""); Assert.AreEqual(1, dataField.Fields().Count()); var tsigSubfield = dataField.Fields().First(); tsigSubfield.AssertShow("No dissector for algorithm:" + GetWiresharkDomainName(tSigData.Algorithm)); tsigSubfield.AssertValue(tSigData.MessageAuthenticationCode); break; case "dns.tsig.original_id": dataField.AssertShowDecimal(tSigData.OriginalId); dataField.AssertNoFields(); break; case "dns.tsig.error": dataField.AssertShowDecimal((ushort)tSigData.Error); dataField.AssertNoFields(); break; case "dns.tsig.other_len": dataField.AssertShowDecimal(tSigData.Other.Length); dataField.AssertNoFields(); break; case "dns.tsig.other_data": dataField.AssertValue(tSigData.Other); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Null: // 10. case DnsType.EId: // 31. case DnsType.NimrodLocator: // 32. case DnsType.AtmA: // 34. case DnsType.Sink: // 40. case DnsType.NInfo: // 56. case DnsType.RKey: // 57. case DnsType.TrustAnchorLink: // 58. case DnsType.Cds: // 59. case DnsType.UInfo: // 100. case DnsType.Uid: // 101. case DnsType.Gid: // 102. case DnsType.Unspecified: // 103. case DnsType.Ixfr: // 251. case DnsType.Axfr: // 252. case DnsType.MailB: // 253. case DnsType.MailA: // 254. case DnsType.Any: // 255. case DnsType.Uri: // 256. case DnsType.CertificationAuthorityAuthorization: // 257. case DnsType.TrustAnchor: // 32768. default: dataField.AssertName(""); dataField.AssertShow("Data"); dataField.AssertNoFields(); break; } }
protected override bool CompareField(XElement field, Datagram datagram) { IpV6Datagram ipV6Datagram = datagram as IpV6Datagram; if (ipV6Datagram == null) return true; if (ipV6Datagram.NextHeader == IpV4Protocol.Cftp || ipV6Datagram.ExtensionHeaders.Any(extensionHeader => extensionHeader.NextHeader == IpV4Protocol.Cftp)) return false; // TODO: Remove after https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9996 is fixed. if (ipV6Datagram.ExtensionHeaders.Select(extensionHeader => extensionHeader.NextHeader).Concat(ipV6Datagram.NextHeader).Any( protocol => protocol == IpV4Protocol.WidebandMonitoring || protocol == IpV4Protocol.SunNetworkDisk || protocol == IpV4Protocol.Swipe || protocol == IpV4Protocol.AnyHostInternal || protocol == IpV4Protocol.SourceDemandRoutingProtocol || protocol == IpV4Protocol.MobileInternetworkingControlProtocol || protocol == IpV4Protocol.IsoIp || protocol == IpV4Protocol.Kryptolan || protocol == IpV4Protocol.LArp || protocol == IpV4Protocol.SecureVersatileMessageTransactionProtocol || protocol == IpV4Protocol.WangSpanNetwork || protocol == IpV4Protocol.Cbt || protocol == IpV4Protocol.Visa || protocol == IpV4Protocol.SimpleMessageProtocol || protocol == IpV4Protocol.InternetPacketCoreUtility || protocol == IpV4Protocol.BbnRccMonitoring || protocol == IpV4Protocol.IpIp || protocol == IpV4Protocol.FibreChannel || protocol == IpV4Protocol.ServiceSpecificConnectionOrientedProtocolInAMultilinkAndConnectionlessEnvironment || protocol == IpV4Protocol.SitaraNetworksProtocol || protocol == IpV4Protocol.Fire || protocol == IpV4Protocol.Leaf1 || protocol == IpV4Protocol.IpsilonFlowManagementProtocol || protocol == IpV4Protocol.CompaqPeer || protocol == IpV4Protocol.InterDomainPolicyRoutingProtocolControlMessageTransportProtocol || protocol == IpV4Protocol.BulkDataTransferProtocol || protocol == IpV4Protocol.SemaphoreCommunicationsSecondProtocol || protocol == IpV4Protocol.Mobile || protocol == IpV4Protocol.HostMonitoringProtocol || protocol == IpV4Protocol.Chaos || protocol == IpV4Protocol.DiiDataExchange || protocol == IpV4Protocol.Emcon || protocol == IpV4Protocol.ThirdPartyConnect || protocol == IpV4Protocol.Aris || protocol == IpV4Protocol.NetworkVoice || protocol == IpV4Protocol.AnyPrivateEncryptionScheme || protocol == IpV4Protocol.PacketVideoProtocol || protocol == IpV4Protocol.PacketRadioMeasurement || protocol == IpV4Protocol.AnyLocalNetwork || protocol == IpV4Protocol.Qnx || protocol == IpV4Protocol.Tcf || protocol == IpV4Protocol.Ttp || protocol == IpV4Protocol.ScheduleTransferProtocol || protocol == IpV4Protocol.TransportLayerSecurityProtocol || protocol == IpV4Protocol.Ax25 || protocol == IpV4Protocol.CombatRadioTransportProtocol || protocol == IpV4Protocol.PerformanceTransparencyProtocol || protocol == IpV4Protocol.IntegratedNetLayerSecurityProtocol || protocol == IpV4Protocol.DatagramDeliveryProtocol || protocol == IpV4Protocol.PrivateNetworkToNetworkInterface || protocol == IpV4Protocol.Pipe || protocol == IpV4Protocol.BackroomSatMon || protocol == IpV4Protocol.Iplt || protocol == IpV4Protocol.Any0HopProtocol || protocol == IpV4Protocol.Leaf2 || protocol == IpV4Protocol.InterDomainPolicyRoutingProtocol || protocol == IpV4Protocol.NationalScienceFoundationNetworkInteriorGatewayProtocol || protocol == IpV4Protocol.WidebandExpak || protocol == IpV4Protocol.Uti || protocol == IpV4Protocol.Multiplexing || protocol == IpV4Protocol.Il || protocol == IpV4Protocol.MulticastTransportProtocol || protocol == IpV4Protocol.AnyDistributedFileSystem || protocol == IpV4Protocol.InteractiveAgentTransferProtocol || protocol == IpV4Protocol.InternetPluribusPacketCore || protocol == IpV4Protocol.InternetworkPacketExchangeInIp || protocol == IpV4Protocol.IntermediateSystemToIntermediateSystemOverIpV4 || protocol == IpV4Protocol.ComputerProtocolNetworkExecutive || protocol == IpV4Protocol.EncapsulationHeader || protocol == IpV4Protocol.GatewayToGateway || protocol == IpV4Protocol.SatMon || protocol == IpV4Protocol.VersatileMessageTransactionProtocol || protocol == IpV4Protocol.ReliableDatagramProtocol || protocol == IpV4Protocol.InternetReliableTransactionProtocol || protocol == IpV4Protocol.MeritInternodalProtocol || protocol == IpV4Protocol.Skip || protocol == IpV4Protocol.BurroughsNetworkArchitecture || protocol == IpV4Protocol.InterDomainRoutingProtocol || protocol == IpV4Protocol.ActiveNetworks || protocol == IpV4Protocol.SpectraLinkRadioProtocol || protocol == IpV4Protocol.MobileAdHocNetwork || protocol == IpV4Protocol.DissimilarGatewayProtocol || protocol == IpV4Protocol.SpriteRpc || protocol == IpV4Protocol.CombatRadioUserDatagram || protocol == IpV4Protocol.Gmtp || protocol == IpV4Protocol.MobileHostRoutingProtocol || protocol == IpV4Protocol.Shim6 || // TODO: Implement Shim6. protocol == IpV4Protocol.RemoteVirtualDiskProtocol)) return false; int currentExtensionHeaderIndex = ipV6Datagram.ExtensionHeaders.TakeWhile(extensionHeader => extensionHeader.Protocol != IpV4Protocol.MobilityHeader).Count(); if (currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count && !ipV6Datagram.IsValid) return false; IpV6ExtensionHeaderMobility mobilityHeader = (IpV6ExtensionHeaderMobility)ipV6Datagram.ExtensionHeaders[currentExtensionHeaderIndex]; switch (field.Name()) { case "mip6.proto": field.AssertShowDecimal((byte)mobilityHeader.NextHeader); field.AssertNoFields(); break; case "mip6.hlen": if (mobilityHeader.IsValid) field.AssertShowDecimal(mobilityHeader.Length / 8 - 1); field.AssertNoFields(); break; case "mip6.mhtype": field.AssertShowDecimal((byte)mobilityHeader.MobilityHeaderType); break; case "mip6.reserved": field.AssertShowDecimal(0); field.AssertNoFields(); break; case "mip6.csum": field.AssertShowDecimal(mobilityHeader.Checksum); break; case "mip6.em.data": IpV6ExtensionHeaderMobilityExperimental experimentalHeader = (IpV6ExtensionHeaderMobilityExperimental)mobilityHeader; field.AssertValue(experimentalHeader.MessageData); break; case "": switch (field.Show()) { case "Binding Refresh Request": Assert.AreEqual(IpV6MobilityHeaderType.BindingRefreshRequest, mobilityHeader.MobilityHeaderType); field.AssertNoFields(); break; case "Heartbeat": IpV6ExtensionHeaderMobilityHeartbeatMessage heartbeatMessage = (IpV6ExtensionHeaderMobilityHeartbeatMessage)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.hb.u_flag": subfield.AssertShowDecimal(heartbeatMessage.IsUnsolicitedHeartbeatResponse); break; case "mip6.hb.r_flag": subfield.AssertShowDecimal(heartbeatMessage.IsResponse); break; case "mip6.hb.seqnr": subfield.AssertShowDecimal(heartbeatMessage.SequenceNumber); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Heartbeat mobility header field {0}", subfield.Name())); } } break; case "Binding Revocation Indication": IpV6ExtensionHeaderMobilityBindingRevocationIndicationMessage bindingRevocationIndicationMessage = (IpV6ExtensionHeaderMobilityBindingRevocationIndicationMessage)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.bri_br.type": subfield.AssertShowDecimal((byte)bindingRevocationIndicationMessage.BindingRevocationType); break; case "mip6.bri_r.trigger": subfield.AssertShowDecimal((byte)bindingRevocationIndicationMessage.RevocationTrigger); break; case "mip6.bri_seqnr": subfield.AssertShowDecimal(bindingRevocationIndicationMessage.SequenceNumber); break; case "mip6.bri_ip": subfield.AssertShowDecimal(bindingRevocationIndicationMessage.ProxyBinding); break; case "mip6.bri_iv": subfield.AssertShowDecimal(bindingRevocationIndicationMessage.IpV4HomeAddressBindingOnly); break; case "mip6.bri_ig": subfield.AssertShowDecimal(bindingRevocationIndicationMessage.Global); break; case "mip6.bri_res": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Revocation Acknowledgement Message mobility header field {0}", subfield.Name())); } } break; case "Binding Revocation Acknowledge": IpV6ExtensionHeaderMobilityBindingRevocationAcknowledgementMessage bindingRevocationAcknowledgementMessage = (IpV6ExtensionHeaderMobilityBindingRevocationAcknowledgementMessage)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.bri_br.type": subfield.AssertShowDecimal((byte)bindingRevocationAcknowledgementMessage.BindingRevocationType); break; case "mip6.bri_status": subfield.AssertShowDecimal((byte)bindingRevocationAcknowledgementMessage.Status); break; case "mip6.bri_seqnr": subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.SequenceNumber); break; case "mip6.bri_ap": subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.ProxyBinding); break; case "mip6.bri_av": subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.IpV4HomeAddressBindingOnly); break; case "mip6.bri_ag": subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.Global); break; case "mip6.bri_res": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Revocation Acknowledgement Message mobility header field {0}", subfield.Name())); } } break; case "Care-of Test Init": IpV6ExtensionHeaderMobilityCareOfTestInit careOfTestInit = (IpV6ExtensionHeaderMobilityCareOfTestInit)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.coti.cookie": subfield.AssertShowDecimal(careOfTestInit.CareOfInitCookie); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Care Of Test Init mobility header field {0}", subfield.Name())); } } break; case "Care-of Test": IpV6ExtensionHeaderMobilityCareOfTest careOfTest = (IpV6ExtensionHeaderMobilityCareOfTest)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.cot.nindex": subfield.AssertShowDecimal(careOfTest.CareOfNonceIndex); break; case "mip6.cot.cookie": subfield.AssertShowDecimal(careOfTest.CareOfInitCookie); break; case "mip6.hot.token": subfield.AssertShowDecimal(careOfTest.CareOfKeygenToken); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Care Of Test mobility header field {0}", subfield.Name())); } } break; case "Fast Binding Acknowledgement": IpV6ExtensionHeaderMobilityFastBindingAcknowledgement fastBindingAcknowledgement = (IpV6ExtensionHeaderMobilityFastBindingAcknowledgement)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "fmip6.fback.status": subfield.AssertShowDecimal((byte)fastBindingAcknowledgement.Status); break; case "fmip6.fback.k_flag": subfield.AssertShowDecimal(fastBindingAcknowledgement.KeyManagementMobilityCapability); break; case "fmip6.fback.seqnr": subfield.AssertShowDecimal(fastBindingAcknowledgement.SequenceNumber); break; case "fmip6.fback.lifetime": subfield.AssertShowDecimal(fastBindingAcknowledgement.Lifetime); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Fast Binding Acknowledgement mobility header field {0}", subfield.Name())); } } break; case "Binding Error": IpV6ExtensionHeaderMobilityBindingError bindingError = (IpV6ExtensionHeaderMobilityBindingError)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.be.status": subfield.AssertShowDecimal((byte)bindingError.Status); break; case "mip6.be.haddr": subfield.AssertShow(bindingError.HomeAddress.ToString("x")); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Error mobility header field {0}", subfield.Name())); } } break; case "Fast Neighbor Advertisement": Assert.AreEqual(IpV6MobilityHeaderType.FastNeighborAdvertisement, mobilityHeader.MobilityHeaderType); field.AssertNoFields(); break; case "Home Test": IpV6ExtensionHeaderMobilityHomeTest homeTest = (IpV6ExtensionHeaderMobilityHomeTest)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.hot.nindex": subfield.AssertShowDecimal(homeTest.HomeNonceIndex); break; case "mip6.hot.cookie": subfield.AssertShowDecimal(homeTest.HomeInitCookie); break; case "mip6.hot.token": subfield.AssertShowDecimal(homeTest.HomeKeygenToken); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Home Test mobility header field {0}", subfield.Name())); } } break; case "Home Test Init": IpV6ExtensionHeaderMobilityHomeTestInit homeTestInit = (IpV6ExtensionHeaderMobilityHomeTestInit)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.hoti.cookie": subfield.AssertShowDecimal(homeTestInit.HomeInitCookie); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Home Test Init mobility header field {0}", subfield.Name())); } } break; case "Binding Update": IpV6ExtensionHeaderMobilityBindingUpdate bindingUpdate = (IpV6ExtensionHeaderMobilityBindingUpdate)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.bu.seqnr": subfield.AssertShowDecimal(bindingUpdate.SequenceNumber); break; case "mip6.bu.a_flag": subfield.AssertShowDecimal(bindingUpdate.Acknowledge); break; case "mip6.bu.h_flag": subfield.AssertShowDecimal(bindingUpdate.HomeRegistration); break; case "mip6.bu.l_flag": subfield.AssertShowDecimal(bindingUpdate.LinkLocalAddressCompatibility); break; case "mip6.bu.k_flag": subfield.AssertShowDecimal(bindingUpdate.KeyManagementMobilityCapability); break; case "mip6.bu.m_flag": subfield.AssertShowDecimal(bindingUpdate.MapRegistration); break; case "mip6.nemo.bu.r_flag": subfield.AssertShowDecimal(bindingUpdate.MobileRouter); break; case "mip6.bu.p_flag": subfield.AssertShowDecimal(bindingUpdate.ProxyRegistration); break; case "mip6.bu.f_flag": subfield.AssertShowDecimal(bindingUpdate.ForcingUdpEncapsulation); break; case "mip6.bu.t_flag": subfield.AssertShowDecimal(bindingUpdate.TypeLengthValueHeaderFormat); break; case "mip6.bu.b_flag": subfield.AssertShowDecimal(bindingUpdate.BulkBindingUpdate); break; case "mip6.bu.lifetime": subfield.AssertShowDecimal(bindingUpdate.Lifetime); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Update mobility header field {0}", subfield.Name())); } } break; case "Binding Acknowledgement": IpV6ExtensionHeaderMobilityBindingAcknowledgement bindingAcknowledgement = (IpV6ExtensionHeaderMobilityBindingAcknowledgement)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.ba.status": subfield.AssertShowDecimal((byte)bindingAcknowledgement.Status); break; case "mip6.ba.k_flag": subfield.AssertShowDecimal(bindingAcknowledgement.KeyManagementMobilityCapability); break; case "mip6.nemo.ba.r_flag": subfield.AssertShowDecimal(bindingAcknowledgement.MobileRouter); break; case "mip6.ba.p_flag": subfield.AssertShowDecimal(bindingAcknowledgement.ProxyRegistration); break; case "mip6.ba.t_flag": subfield.AssertShowDecimal(bindingAcknowledgement.TypeLengthValueHeaderFormat); break; case "mip6.ba.b_flag": // TODO: Support Bulk Binding Update Support for Proxy Mobile IPv6 (RFC 6602). break; case "mip6.ba.seqnr": subfield.AssertShowDecimal(bindingAcknowledgement.SequenceNumber); break; case "mip6.ba.lifetime": subfield.AssertShowDecimal(bindingAcknowledgement.Lifetime); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Acknowledgement mobility header field {0}", subfield.Name())); } } break; case "Fast Binding Update": IpV6ExtensionHeaderMobilityFastBindingUpdate fastBindingUpdate = (IpV6ExtensionHeaderMobilityFastBindingUpdate)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "fmip6.fbu.seqnr": subfield.AssertShowDecimal(fastBindingUpdate.SequenceNumber); break; case "fmip6.fbu.a_flag": subfield.AssertShowDecimal(fastBindingUpdate.Acknowledge); break; case "fmip6.fbu.h_flag": subfield.AssertShowDecimal(fastBindingUpdate.HomeRegistration); break; case "fmip6.fbu.l_flag": subfield.AssertShowDecimal(fastBindingUpdate.LinkLocalAddressCompatibility); break; case "fmip6.fbu.k_flag": subfield.AssertShowDecimal(fastBindingUpdate.KeyManagementMobilityCapability); break; case "fmip6.fbu.lifetime": subfield.AssertShowDecimal(fastBindingUpdate.Lifetime); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Fast Binding Update mobility header field {0}", subfield.Name())); } } break; case "Handover Acknowledge ": var handoverAcknowledgeMessage = (IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.hack.seqnr": subfield.AssertShowDecimal(handoverAcknowledgeMessage.SequenceNumber); break; case "mip6.hack.code": subfield.AssertShowDecimal((byte)handoverAcknowledgeMessage.Code); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Handover Acknowledge mobility header field {0}", subfield.Name())); } } break; case "Handover Initiate": var handoverInitiateMessage = (IpV6ExtensionHeaderMobilityHandoverInitiateMessage)mobilityHeader; foreach (XElement subfield in field.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "mip6.hi.seqnr": subfield.AssertShowDecimal(handoverInitiateMessage.SequenceNumber); break; case "mip6.hi.s_flag": subfield.AssertShowDecimal(handoverInitiateMessage.AssignedAddressConfiguration); break; case "mip6.hi.u_flag": subfield.AssertShowDecimal(handoverInitiateMessage.Buffer); break; case "mip6.hi.code": subfield.AssertShowDecimal((byte)handoverInitiateMessage.Code); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 mobility header field {0}", subfield.Name())); } } break; case "Mobility Options": int optionIndex = 0; foreach (XElement optionField in field.Fields()) { IpV6MobilityOption option = mobilityHeader.MobilityOptions[optionIndex]; switch (optionField.Name()) { case "": switch (option.OptionType) { case IpV6MobilityOptionType.LinkLayerAddress: optionField.AssertShow("Mobility Header Link-Layer Address"); IpV6MobilityOptionLinkLayerAddress linkLayerAddress = (IpV6MobilityOptionLinkLayerAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("Mobility Header Link-Layer Address option"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubsubfield, option)) continue; switch (optionSubsubfield.Name()) { case "mip6.lla.optcode": optionSubsubfield.AssertShowDecimal((byte)linkLayerAddress.Code); break; case "": // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10627 is fixed. // optionSubsubfield.AssertValue(linkLayerAddress.LinkLayerAddress); break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Link Layer Address option subfield {0}", optionSubsubfield.Name())); } } break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Link Layer Address option field {0}", optionSubfield.Name())); } } // TODO: Change to break when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10627 is fixed. return false; case IpV6MobilityOptionType.IpV4DefaultRouterAddress: var ipV4DefaultRouterAddress = (IpV6MobilityOptionIpV4DefaultRouterAddress)option; optionField.AssertShow("IPv4 Default-Router Address: " + ipV4DefaultRouterAddress.DefaultRouterAddress); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ipv4dra.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.ipv4dra.dra": optionSubfield.AssertShow(ipV4DefaultRouterAddress.DefaultRouterAddress.ToString()); break; default: throw new InvalidOperationException( string.Format("Invalid IPv6 IPv4 Default Router Address option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Pad1: optionField.AssertShow("Pad1"); optionField.AssertNoFields(); break; case IpV6MobilityOptionType.PadN: if (optionField.Show() != "PadN" && optionIndex == mobilityHeader.MobilityOptions.Count - 1) { Assert.IsFalse(mobilityHeader.IsValid); return true; } optionField.AssertShow("PadN"); IpV6MobilityOptionPadN padN = (IpV6MobilityOptionPadN)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow(string.Format("PadN: {0} bytes", padN.PaddingDataLength)); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.IpV4HomeAddressReply: IpV6MobilityOptionIpV4HomeAddressReply ipV4HomeAddressReply = (IpV6MobilityOptionIpV4HomeAddressReply)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ipv4aa.sts": optionSubfield.AssertShowDecimal((byte)ipV4HomeAddressReply.Status); break; default: ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubfield, ipV4HomeAddressReply); break; } } break; case IpV6MobilityOptionType.IpV4HomeAddressRequest: var ipV4HomeAddressRequest = (IpV6MobilityOptionIpV4HomeAddressRequest)option; optionField.AssertShow("IPv4 Home Address Request: " + ipV4HomeAddressRequest.HomeAddress); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubfield, ipV4HomeAddressRequest); } break; case IpV6MobilityOptionType.IpV4AddressAcknowledgement: optionField.AssertShow("IPv4 Address Acknowledgement"); var ipV4AddressAcknowledgement = (IpV6MobilityOptionIpV4AddressAcknowledgement)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("IPv4 Address Acknowledgement"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { optionSubsubfield.AssertNoFields(); switch (optionSubsubfield.Name()) { case "mip6.ipv4aa.sts": optionSubsubfield.AssertShowDecimal((byte)ipV4AddressAcknowledgement.Status); break; default: ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubsubfield, ipV4AddressAcknowledgement); break; } } break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.MobileNetworkPrefix: optionField.AssertShow("Mobile Network Prefix"); var mobileNetworkPrefix = (IpV6MobilityOptionMobileNetworkPrefix)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("Mobile Network Prefix"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { optionSubsubfield.AssertNoFields(); switch (optionSubsubfield.Name()) { case "mip6.nemo.mnp.mnp": optionSubsubfield.AssertShow(mobileNetworkPrefix.NetworkPrefix.ToString("x")); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subsubfield {0}", optionSubsubfield.Name())); } } break; case "mip6.nemo.mnp.pfl": optionSubfield.AssertNoFields(); optionSubfield.AssertShowDecimal(mobileNetworkPrefix.PrefixLength); break; default: optionSubfield.AssertNoFields(); throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.HomeNetworkPrefix: optionField.AssertShow("Home Network Prefix"); var homeNetworkPrefix = (IpV6MobilityOptionHomeNetworkPrefix)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("Home Network Prefix"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { switch (optionSubsubfield.Name()) { case "mip6.nemo.mnp.mnp": optionSubsubfield.AssertShow(homeNetworkPrefix.NetworkPrefix.ToString("x")); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Network Prefix option subfield {0}", optionSubsubfield.Name())); } } break; case "mip6.nemo.mnp.pfl": optionSubfield.AssertShowDecimal(homeNetworkPrefix.PrefixLength); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Network Prefix option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.VendorSpecific: Assert.IsTrue(optionField.Show().StartsWith("Vendor Specific: ")); IpV6MobilityOptionVendorSpecific vendorSpecific = (IpV6MobilityOptionVendorSpecific)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.vsm.vendorId": optionSubfield.AssertShowDecimal(vendorSpecific.VendorId); break; case "mip6.vsm.subtype": optionSubfield.AssertShowDecimal(vendorSpecific.Subtype); break; case "": optionSubfield.AssertValue(vendorSpecific.Data); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Vendor Specific option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.NonceIndexes: optionField.AssertShow("Nonce Indices"); IpV6MobilityOptionNonceIndexes nonceIndexes = (IpV6MobilityOptionNonceIndexes)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("Nonce Indices"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { optionSubsubfield.AssertNoFields(); switch (optionSubsubfield.Name()) { case "mip6.ni.hni": optionSubsubfield.AssertShowDecimal(nonceIndexes.HomeNonceIndex); break; case "mip6.ni.cni": optionSubsubfield.AssertShowDecimal(nonceIndexes.CareOfNonceIndex); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Nonce Indices option subfield {0}", optionSubsubfield.Name())); } } break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Nonce Indices option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.LinkLocalAddress: optionField.AssertShow("Link-local Address"); IpV6MobilityOptionLinkLocalAddress linkLocalAddress = (IpV6MobilityOptionLinkLocalAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": optionSubfield.AssertShow("Link-local Address"); foreach (XElement optionSubsubfield in optionSubfield.Fields()) { optionSubsubfield.AssertNoFields(); switch (optionSubsubfield.Name()) { case "mip6.lila_lla": optionSubsubfield.AssertShow(linkLocalAddress.LinkLocalAddress.ToString("x")); break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Link-local Address option field {0}", optionSubsubfield.Name())); } } break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Link-local Address option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.MobileNodeIdentifier: Assert.IsTrue(optionField.Show().StartsWith("Mobile Node Identifier")); IpV6MobilityOptionMobileNodeIdentifier mobileNodeIdentifier = (IpV6MobilityOptionMobileNodeIdentifier)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.mnid.subtype": optionSubfield.AssertShowDecimal((byte)mobileNodeIdentifier.Subtype); break; case "": optionSubfield.AssertValue(mobileNodeIdentifier.Identifier); break; default: throw new InvalidOperationException( string.Format("Invalid IPv6 Mobile Node Identifier option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.BindingAuthorizationData: optionField.AssertShow("Authorization Data"); IpV6MobilityOptionBindingAuthorizationData authorizationData = (IpV6MobilityOptionBindingAuthorizationData)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": foreach (XElement authSubfield in optionSubfield.Fields()) { switch (authSubfield.Name()) { case "mip6.bad.auth": authSubfield.AssertValue(authorizationData.Authenticator); break; default: throw new InvalidOperationException( string.Format("Invalid IPv6 Authorization Data option subfield {0}", authSubfield.Name())); } } break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Authorization Data option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.IpV4HomeAddress: optionField.AssertShow("IPv4 Home Address"); IpV6MobilityOptionIpV4HomeAddress ipV4HomeAddress = (IpV6MobilityOptionIpV4HomeAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "": foreach (XElement optionSubsubfield in optionSubfield.Fields()) { optionSubsubfield.AssertNoFields(); switch (optionSubsubfield.Name()) { case "mip6.ipv4ha.p_flag": optionSubsubfield.AssertShowDecimal(ipV4HomeAddress.RequestPrefix); break; default: ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubsubfield, ipV4HomeAddress); break; } } break; default: throw new InvalidOperationException(string.Format( "Invalid IPv6 Authorization Data option field {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.ServiceSelection: IpV6MobilityOptionServiceSelection serviceSelection = (IpV6MobilityOptionServiceSelection)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ss.identifier": optionSubfield.AssertValue(serviceSelection.Identifier); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.RedirectCapability: IpV6MobilityOptionRedirectCapability redirectCapability = (IpV6MobilityOptionRedirectCapability)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.recap.reserved": optionSubfield.AssertShowDecimal(0); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.BindingIdentifier: IpV6MobilityOptionBindingIdentifier bindingIdentifier = (IpV6MobilityOptionBindingIdentifier)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.bi.bid": optionSubfield.AssertShowDecimal(bindingIdentifier.BindingId); break; case "mip6.bi.status": optionSubfield.AssertShowDecimal((byte)bindingIdentifier.Status); break; case "mip6.bi.h_flag": optionSubfield.AssertShowDecimal(bindingIdentifier.SimultaneousHomeAndForeignBinding); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.LoadInformation: IpV6MobilityOptionLoadInformation loadInformation = (IpV6MobilityOptionLoadInformation)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.load_inf.priority": optionSubfield.AssertShowDecimal(loadInformation.Priority); break; case "mip6.load_inf.sessions_in_use": optionSubfield.AssertShowDecimal(loadInformation.SessionsInUse); break; case "mip6.load_inf.maximum_sessions": optionSubfield.AssertShowDecimal(loadInformation.MaximumSessions); break; case "mip6.load_inf.used_capacity": optionSubfield.AssertShowDecimal(loadInformation.UsedCapacity); break; case "mip6.load_inf.maximum_capacity": optionSubfield.AssertShowDecimal(loadInformation.MaximumCapacity); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.IpV4CareOfAddress: IpV6MobilityOptionIpV4CareOfAddress ipV4CareOfAddress = (IpV6MobilityOptionIpV4CareOfAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ipv4coa.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.ipv4coa.addr": optionSubfield.AssertShow(ipV4CareOfAddress.CareOfAddress.ToString()); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.CryptographicallyGeneratedAddressParametersRequest: foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.IpV6AddressPrefix: var ipV6AddressPrefix = (IpV6MobilityOptionIpV6AddressPrefix)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.mhipv6ap.opt_code": optionSubfield.AssertShowDecimal((byte)ipV6AddressPrefix.Code); break; case "mip6.mhipv6ap.len": optionSubfield.AssertShowDecimal(ipV6AddressPrefix.PrefixLength); break; case "mip6.mhipv6ap.ipv6_address": optionSubfield.AssertValue(ipV6AddressPrefix.AddressOrPrefix.ToValue()); break; case "mip6.mhipv6ap.ipv6_address_prefix": Assert.IsTrue(optionSubfield.Value().EndsWith(ipV6AddressPrefix.AddressOrPrefix.ToValue().ToString("x32"))); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.MobileNodeGroupIdentifier: var mobileNodeGroupIdentifier = (IpV6MobilityOptionMobileNodeGroupIdentifier)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.mng.sub_type": optionSubfield.AssertShowDecimal((byte)mobileNodeGroupIdentifier.Subtype); break; case "mip6.mng.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.mng._mng_id": optionSubfield.AssertShowDecimal(mobileNodeGroupIdentifier.MobileNodeGroupIdentifier); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.BindingAuthorizationDataForFmIpV6: var bindingAuthorizationDataForFmIpV6 = (IpV6MobilityOptionBindingAuthorizationDataForFmIpV6)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.badff.spi": optionSubfield.AssertShowDecimal(bindingAuthorizationDataForFmIpV6.SecurityParameterIndex); break; case "mip6.badff.auth": optionSubfield.AssertValue(bindingAuthorizationDataForFmIpV6.Authenticator); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.MobileNodeLinkLayerIdentifier: var mobileNodeLinkLayerIdentifier = (IpV6MobilityOptionMobileNodeLinkLayerIdentifier)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.mnlli.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.mnlli.lli": optionSubfield.AssertValue(mobileNodeLinkLayerIdentifier.LinkLayerIdentifier); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.AccessTechnologyType: var accessTechnologyType = (IpV6MobilityOptionAccessTechnologyType)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.att.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.att": optionSubfield.AssertShowDecimal((byte)accessTechnologyType.AccessTechnologyType); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.AccessNetworkIdentifier: foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.BindingRefreshAdvice: var bindingRefreshAdvice = (IpV6MobilityOptionBindingRefreshAdvice)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.bra.interval": optionSubfield.AssertShowDecimal(bindingRefreshAdvice.RefreshInterval); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.PermanentHomeKeygenToken: var permanentHomeKeygenToken = (IpV6MobilityOptionPermanentHomeKeygenToken)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.phkt.phkt": optionSubfield.AssertValue(permanentHomeKeygenToken.PermanentHomeKeygenToken); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Redirect: var redirect = (IpV6MobilityOptionRedirect)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.redir.k": optionSubfield.AssertShowDecimal(redirect.LocalMobilityAddressIpV6 != null); break; case "mip6.redir.n": optionSubfield.AssertShowDecimal(redirect.LocalMobilityAddressIpV4 != null); break; case "mip6.redir.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.redir.addr_r2lma_ipv4": optionSubfield.AssertShow(redirect.LocalMobilityAddressIpV4.ToString()); break; case "mip6.redir.addr_r2lma_ipv6": optionSubfield.AssertValue(redirect.LocalMobilityAddressIpV6.Value.ToValue()); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.CareOfTest: var careOfTestOption = (IpV6MobilityOptionCareOfTest)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.mocot.co_keygen_tok": optionSubfield.AssertValue(careOfTestOption.CareOfKeygenToken); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.ReplayProtection: var replayProtection = (IpV6MobilityOptionReplayProtection)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "mip6.mseg_id.timestamp": optionSubfield.AssertValue(replayProtection.Timestamp); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Authentication: var authentication = (IpV6MobilityOptionAuthentication)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.auth.subtype": optionSubfield.AssertShowDecimal((byte)authentication.Subtype); break; case "mip6.auth.mobility_spi": optionSubfield.AssertShowDecimal(authentication.MobilitySecurityParameterIndex); break; case "mip6.auth.auth_data": optionSubfield.AssertValue(authentication.AuthenticationData); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.HandoffIndicator: var handoffIndicator = (IpV6MobilityOptionHandoffIndicator)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.hi.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.hi": optionSubfield.AssertShowDecimal((byte)handoffIndicator.HandoffIndicator); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.IpV4DhcpSupportMode: var ipV4DhcpSupportMode = (IpV6MobilityOptionIpV4DhcpSupportMode)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ipv4dsm.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.ipv4dsm.s_flag": optionSubfield.AssertShowDecimal(ipV4DhcpSupportMode.IsServer); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.DnsUpdate: var dnsUpdate = (IpV6MobilityOptionDnsUpdate)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.dnsu.status": optionSubfield.AssertShowDecimal((byte)dnsUpdate.Status); break; case "mip6.dnsu.flag.r": optionSubfield.AssertShowDecimal(dnsUpdate.Remove); break; case "mip6.dnsu.mn_id": optionSubfield.AssertValue(dnsUpdate.MobileNodeIdentity); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.LocalMobilityAnchorAddress: var localMobilityAnchorAddress = (IpV6MobilityOptionLocalMobilityAnchorAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mmip6.lmaa.opt_code": optionSubfield.AssertShowDecimal((byte)localMobilityAnchorAddress.Code); break; case "mmip6.lmaa.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.lmaa.ipv6": optionSubfield.AssertValue(localMobilityAnchorAddress.LocalMobilityAnchorAddressIpV6.Value.ToValue()); break; case "mip6.lmaa.ipv4": optionSubfield.AssertShow(localMobilityAnchorAddress.LocalMobilityAnchorAddressIpV4.Value.ToString()); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.ContextRequest: var contextRequest = (IpV6MobilityOptionContextRequest)option; optionField.AssertShow("Context Request" + (contextRequest.Requests.Any() ? "" : " (with option length = 2 bytes; should be >= 4)")); int requestIndex = 0; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.cr.reserved": optionSubfield.AssertShowDecimal(0); break; case "mmip6.cr.req_type": optionSubfield.AssertShowDecimal(contextRequest.Requests[requestIndex].RequestType); break; case "mmip6.cr.req_length": optionSubfield.AssertShowDecimal(contextRequest.Requests[requestIndex].OptionLength); if (contextRequest.Requests[requestIndex].OptionLength == 0) ++requestIndex; break; case "mip6.vsm.vendorId": optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option.Subsegment(0, 4)); break; case "mip6.vsm.subtype": optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option.Subsegment(4, 1)); ++requestIndex; break; case "": optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option); ++requestIndex; break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.AlternateIpV4CareOfAddress: var alternateIpV4CareOfAddress = (IpV6MobilityOptionAlternateIpV4CareOfAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.alt_ip4": optionSubfield.AssertShow(alternateIpV4CareOfAddress.AlternateCareOfAddress.ToString()); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Signature: var signature = (IpV6MobilityOptionSignature)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.sign.sign": optionSubfield.AssertValue(signature.Signature); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.TransientBinding: optionField.AssertShow("Transient Binding(2 bytes)"); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Timestamp: var timestamp = (IpV6MobilityOptionTimestamp)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.timestamp_tmp": optionSubfield.AssertValue(timestamp.Timestamp); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.RestartCounter: var restartCounter = (IpV6MobilityOptionRestartCounter)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.rc": optionSubfield.AssertShowDecimal(restartCounter.RestartCounter); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.CryptographicallyGeneratedAddressParameters: var cryptographicallyGeneratedAddressParameters = (IpV6MobilityOptionCryptographicallyGeneratedAddressParameters)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.cgar.cga_par": optionSubfield.AssertValue(cryptographicallyGeneratedAddressParameters.CryptographicallyGeneratedAddressParameters); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.FlowIdentification: optionField.AssertShow("Flow Identification(" + (option.Length - 2) + " bytes)"); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.NatDetection: optionField.AssertShow("NAT Detection"); var natDetection = (IpV6MobilityOptionNatDetection)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.natd.f_flag": optionSubfield.AssertShowDecimal(natDetection.UdpEncapsulationRequired); break; case "mip6.natd.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.natd.refresh_t": optionSubfield.AssertShowDecimal(natDetection.RefreshTime); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.FlowSummary: optionField.AssertShow("Flow Summary(" + (option.Length - 2) + " bytes)"); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.Experimental: optionField.AssertShow("Experimental" + (option.Length == 2 ? " (with option length = 0 bytes; should be >= 1)" : "")); var experimental = (IpV6MobilityOptionExperimental)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.em.data": optionSubfield.AssertValue(experimental.Data); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.MobileAccessGatewayIpV6Address: optionField.AssertShow("MAG IPv6 Address(18 bytes)"); // TODO: Dedup this code. foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.CareOfTestInit: optionField.AssertShow("Care-of Test Init"); foreach (XElement optionSubfield in optionField.Fields()) { Assert.IsTrue(HandleCommonMobilityOptionSubfield(optionSubfield, option)); } break; case IpV6MobilityOptionType.MobileNodeLinkLocalAddressInterfaceIdentifier: optionField.AssertShow("Mobile Node Link-local Address Interface Identifier(10 bytes)"); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; switch (optionSubfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.AlternateCareOfAddress: optionField.AssertShow("Alternate Care-of Address"); var alternateCareOfAddress = (IpV6MobilityOptionAlternateCareOfAddress)option; foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.acoa.acoa": optionSubfield.AssertValue(alternateCareOfAddress.AlternateCareOfAddress.ToValue()); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; case IpV6MobilityOptionType.GreKey: var greKey = (IpV6MobilityOptionGreKey)option; optionField.AssertShow("GRE Key: " + greKey.GreKeyIdentifier); foreach (XElement optionSubfield in optionField.Fields()) { if (HandleCommonMobilityOptionSubfield(optionSubfield, option)) continue; optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "mip6.ipv4dra.reserved": optionSubfield.AssertShowDecimal(0); break; case "mip6.gre_key": optionSubfield.AssertShowDecimal(greKey.GreKeyIdentifier); break; default: throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}", optionSubfield.Name())); } } break; default: throw new InvalidOperationException(string.Format("Unsupported IPv6 mobility option type {0}", option.OptionType)); } ++optionIndex; break; default: throw new InvalidOperationException(string.Format("Invalid ipv6 mobility header option field {0}", optionField.Name())); } } break; default: field.AssertShow("Unknown MH Type"); Assert.IsTrue(mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.Experimental || mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.HomeAgentSwitchMessage || mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.LocalizedRoutingInitiation || mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.LocalizedRoutingAcknowledgement); field.AssertNoFields(); break; } break; default: throw new InvalidOperationException(string.Format("Invalid ipv6 mobility header field {0}", field.Name())); } return true; }
private static void CompareTcpOptions(XElement element, TcpOptions options) { int currentOptionIndex = 0; foreach (var field in element.Fields()) { if (field.Name() == "_ws.expert") continue; if (currentOptionIndex >= options.Count) { Assert.IsFalse(options.IsValid, "Options IsValid"); Assert.IsTrue( field.Show().StartsWith("Unknown (0x09) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net. field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net. field.Show().StartsWith("Unknown (0x19) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net. field.Show().StartsWith("Unknown (0x2d) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net. field.Show().StartsWith("Unknown (0xa9) ") || // Unknown in Wireshark and unknown and invalid in Pcap.Net. field.Show().StartsWith("Echo reply (with option length = ") || field.Show().Contains("bytes says option goes past end of options") || field.Show().Contains(") (with too-short option length = ") || field.Show().EndsWith(" (length byte past end of options)"), "Options show: " + field.Show()); Assert.AreEqual(options.Count, currentOptionIndex, "Options Count"); return; } TcpOption option = options[currentOptionIndex]; switch (field.Name()) { case "": switch (option.OptionType) { case TcpOptionType.WindowScale: TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option; byte scaleFactorLog = windowScale.ScaleFactorLog; field.AssertShow(string.Format("Window scale: {0} (multiply by {1})", scaleFactorLog, (1L << (scaleFactorLog % 32)))); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; switch (subField.Name()) { case "tcp.options.wscale.shift": subField.AssertShowDecimal(windowScale.ScaleFactorLog); break; case "tcp.options.wscale.multiplier": subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32)); break; default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.SelectiveAcknowledgment: var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option; IEnumerable<TcpOptionSelectiveAcknowledgmentBlock> blocks = selectiveAcknowledgmentOption.Blocks; field.AssertShow("SACK:" + (blocks.Count() == 0 ? string.Empty : ((TcpOptionSelectiveAcknowledgment)option).Blocks.SequenceToString(" ", " "))); int blockIndex = 0; foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { case "tcp.options.sack": subField.AssertShowDecimal(true); break; case "tcp.options.sack_le": subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge); break; case "tcp.options.sack_re": subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge); ++blockIndex; break; case "tcp.options.sack.count": subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks.Count); break; default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.Timestamp: var timestampOption = (TcpOptionTimestamp)option; field.AssertShow("Timestamps: TSval " + timestampOption.TimestampValue + ", TSecr " + timestampOption.TimestampEchoReply); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { case "tcp.options.timestamp.tsval": subField.AssertShowDecimal(timestampOption.TimestampValue); break; case "tcp.options.timestamp.tsecr": subField.AssertShowDecimal(timestampOption.TimestampEchoReply); break; default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.ConnectionCount: field.AssertShow("CC: " + ((TcpOptionConnectionCount)option).ConnectionCount); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.Echo: field.AssertShow("Echo: " + ((TcpOptionEcho)option).Info); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.ConnectionCountNew: field.AssertShow("CC.NEW: " + ((TcpOptionConnectionCountNew)option).ConnectionCount); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.EndOfOptionList: field.AssertShow("End of Option List (EOL)"); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; switch (subField.Name()) { default: subField.AssertNoFields(); throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.ConnectionCountEcho: field.AssertShow("CC.ECHO: " + ((TcpOptionConnectionCountEcho)option).ConnectionCount); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { default: throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.Md5Signature: field.AssertShow("TCP MD5 signature"); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; switch (subField.Name()) { case "tcp.options.type": subField.AssertShowDecimal((byte)TcpOptionType.Md5Signature); break; default: subField.AssertNoFields(); throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } } break; case TcpOptionType.NoOperation: field.AssertShow("No-Operation (NOP)"); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } break; case TcpOptionType.EchoReply: field.AssertShow("Echo reply: " + ((TcpOptionEchoReply)option).Info); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name()); } break; case TcpOptionType.SelectiveAcknowledgmentPermitted: field.AssertShow("SACK permitted"); field.AssertNoFields(); break; case TcpOptionType.SelectiveNegativeAcknowledgements: // TODO: Support Selective Negative Acknowledgements. Assert.IsTrue(field.Show().StartsWith("SACK permitted")); field.AssertNoFields(); break; case (TcpOptionType)20: // TODO: Support 20. field.AssertShow("SCPS capabilities" + (option.Length >= 4 ? string.Empty : " (with option length = " + option.Length + " bytes; should be >= 4)")); break; case (TcpOptionType)22: field.AssertShow("SCPS record boundary (with option length = " + option.Length + " bytes; should be 2)"); // TODO: Support 22. break; case (TcpOptionType)23: field.AssertShow("SCPS corruption experienced (with option length = " + option.Length + " bytes; should be 2)"); // TODO: Support 23. break; case (TcpOptionType)30: // TODO: Support 30. Assert.IsTrue(field.Show().StartsWith("Multipath TCP")); break; case (TcpOptionType)78: field.AssertShow("Riverbed Transparency (with option length = " + option.Length + " bytes; should be 16)"); // TODO: Support 78 - Support Riverbed. break; case TcpOptionType.PartialOrderConnectionPermitted: // 9. case TcpOptionType.PartialOrderServiceProfile: // 10. case TcpOptionType.AlternateChecksumRequest: // 14. case TcpOptionType.AlternateChecksumData: // 15. case TcpOptionType.Mood: // 25. case TcpOptionType.TcpAuthentication: // 29. field.AssertShow(string.Format("Unknown (0x{0}) ({1} bytes)", ((byte)option.OptionType).ToString("x2"), option.Length)); field.AssertNoFields(); break; default: field.AssertNoFields(); field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x") + ") (" + option.Length + " bytes)"); break; } ++currentOptionIndex; break; case "tcp.options.mss": Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType); var maximumSegmentSize = (TcpOptionMaximumSegmentSize)option; field.AssertShowname("Maximum segment size: " + maximumSegmentSize.MaximumSegmentSize + " bytes"); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); switch (subField.Name()) { case "tcp.options.mss_val": subField.AssertShowDecimal(maximumSegmentSize.MaximumSegmentSize); break; default: throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); } } ++currentOptionIndex; break; case "tcp.options.mss_val": field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize); field.AssertNoFields(); ++currentOptionIndex; break; case "tcp.options.echo": Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho); field.AssertShowDecimal(1); field.AssertNoFields(); break; case "tcp.options.cc": Assert.IsTrue(option is TcpOptionConnectionCountBase); field.AssertShowDecimal(1); field.AssertNoFields(); break; case "tcp.options.scps.vector": // TODO: Support 20. Assert.AreEqual((TcpOptionType)20, option.OptionType); // if (field.Show() == "0") // ++currentOptionIndex; ++currentOptionIndex; break; case "tcp.options.scps": // TODO: Support 20. Assert.AreEqual((TcpOptionType)20, option.OptionType); Assert.IsFalse(field.Fields().Any()); break; case "tcp.options.snack": // TODO: Support Selective Negative Acknowledgements. case "tcp.options.snack.offset": case "tcp.options.snack.size": Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType); field.AssertNoFields(); break; case "tcp.options.sack_perm": Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType); foreach (var subField in field.Fields()) { if (HandleOptionCommonFields(subField, option)) continue; subField.AssertNoFields(); throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); } ++currentOptionIndex; break; case "tcp.options.rvbd.probe": Assert.AreEqual((TcpOptionType)76, option.OptionType); // TODO: Support Riverbed. ++currentOptionIndex; break; case "tcp.options.rvbd.trpy": Assert.AreEqual((TcpOptionType)78, option.OptionType); // TODO: Support Riverbed. ++currentOptionIndex; break; case "tcp.options.experimental": Assert.IsTrue(new []{(TcpOptionType)253, (TcpOptionType)254}.Contains(option.OptionType)); // TODO: Support Experimental. ++currentOptionIndex; break; default: throw new InvalidOperationException("Invalid tcp options field " + field.Name()); } } }
private void CompareOptions(XElement field, ref int optionsIndex, IpV6Datagram ipV6Datagram, IpV6ExtensionHeaderOptions header) { foreach (var headerField in field.Fields()) { switch (headerField.Name()) { case "ipv6.nxt": headerField.AssertNoFields(); headerField.AssertShowDecimal((byte)header.NextHeader); break; case "ipv6.opt.length": headerField.AssertNoFields(); headerField.AssertShowDecimal((header.Length - 8) / 8); break; case "ipv6.opt": foreach (XElement headerSubfield in headerField.Fields()) { IpV6Option option = header.Options[optionsIndex]; var optionCalipso = option as IpV6OptionCalipso; var optionQuickStart = option as IpV6OptionQuickStart; switch (headerSubfield.Name()) { case "ipv6.opt.type": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal((byte)option.OptionType); break; case "ipv6.opt.length": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(option.Length - 2); break; case "ipv6.opt.tel": headerSubfield.AssertNoFields(); IpV6OptionTunnelEncapsulationLimit optionTunnelEncapsulationLimit = (IpV6OptionTunnelEncapsulationLimit)option; headerSubfield.AssertShowDecimal(optionTunnelEncapsulationLimit.TunnelEncapsulationLimit); ++optionsIndex; break; case "ipv6.opt.rpl.flag": IpV6OptionRoutingProtocolLowPowerAndLossyNetworks optionRoutingProtocolLowPowerAndLossyNetworks = (IpV6OptionRoutingProtocolLowPowerAndLossyNetworks)option; foreach (XElement optionSubfield in headerSubfield.Fields()) { optionSubfield.AssertNoFields(); switch (optionSubfield.Name()) { case "ipv6.opt.rpl.flag.o": optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.Down); break; case "ipv6.opt.rpl.flag.r": optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.RankError); break; case "ipv6.opt.rpl.flag.f": optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.ForwardingError); break; case "ipv6.opt.rpl.flag.rsv": optionSubfield.AssertShowDecimal(0); break; case "ipv6.opt.rpl.instance_id": optionSubfield.AssertShowDecimal( optionRoutingProtocolLowPowerAndLossyNetworks.RoutingProtocolLowPowerAndLossyNetworksInstanceId); break; case "ipv6.opt.rpl.sender_rank": optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.SenderRank); break; default: throw new InvalidOperationException("Invalid ipv6 option subfield " + optionSubfield.Name()); } } ++optionsIndex; // TODO: change to break; after https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10559 is fixed. return; case "ipv6.opt.calipso.doi": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal((uint)optionCalipso.DomainOfInterpretation); break; case "ipv6.opt.calipso.cmpt.length": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionCalipso.CompartmentLength); break; case "ipv6.opt.calipso.sens_level": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionCalipso.SensitivityLevel); break; case "ipv6.opt.calipso.checksum": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionCalipso.Checksum); break; case "ipv6.opt.calipso.cmpt_bitmap": headerSubfield.AssertNoFields(); headerSubfield.AssertValue(optionCalipso.CompartmentBitmap); ++optionsIndex; break; case "ipv6.opt.router_alert": headerSubfield.AssertNoFields(); var optionRouterAlert = (IpV6OptionRouterAlert)option; headerSubfield.AssertShowDecimal((ushort)optionRouterAlert.RouterAlertType); ++optionsIndex; break; case "ipv6.opt.padn": headerSubfield.AssertNoFields(); var optionPadN = (IpV6OptionPadN)option; headerSubfield.AssertValue(new byte[optionPadN.PaddingDataLength]); ++optionsIndex; break; case "ipv6.opt.qs_func": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal((byte)optionQuickStart.QuickStartFunction); break; case "ipv6.opt.qs_rate": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionQuickStart.Rate); break; case "ipv6.opt.qs_ttl": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionQuickStart.Ttl); break; case "ipv6.opt.qs_ttl_diff": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal((256 + ipV6Datagram.HopLimit - optionQuickStart.Ttl) % 256); break; case "ipv6.opt.qs_unused": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionQuickStart.Ttl); break; case "ipv6.opt.qs_nonce": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(optionQuickStart.Nonce); break; case "ipv6.opt.qs_reserved": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(0); ++optionsIndex; break; case "ipv6.opt.pad1": headerSubfield.AssertNoFields(); headerSubfield.AssertShow(""); Assert.IsTrue(option is IpV6OptionPad1); ++optionsIndex; break; case "ipv6.opt.jumbo": headerSubfield.AssertNoFields(); headerSubfield.AssertShowDecimal(((IpV6OptionJumboPayload)option).JumboPayloadLength); ++optionsIndex; break; case "ipv6.mipv6_home_address": headerSubfield.AssertNoFields(); headerSubfield.AssertShow(((IpV6OptionHomeAddress)option).HomeAddress.GetWiresharkString()); ++optionsIndex; break; case "ipv6.opt.unknown": headerSubfield.AssertNoFields(); Assert.IsTrue(new[] { IpV6OptionType.LineIdentification, IpV6OptionType.IdentifierLocatorNetworkProtocolNonce, IpV6OptionType.SimplifiedMulticastForwardingDuplicatePacketDetection, IpV6OptionType.EndpointIdentification, }.Contains(option.OptionType), option.OptionType.ToString()); ++optionsIndex; break; default: throw new InvalidOperationException("Invalid ipv6 header subfield " + headerSubfield.Name()); } } break; default: throw new InvalidOperationException("Invalid ipv6 options field " + headerField.Name()); } } }
protected override bool CompareField(XElement field, Datagram parentDatagram, Datagram datagram) { IpDatagram ipDatagram = (IpDatagram)parentDatagram; TcpDatagram tcpDatagram = (TcpDatagram)datagram; switch (field.Name()) { case "tcp.len": field.AssertShowDecimal(tcpDatagram.Length - tcpDatagram.HeaderLength); field.AssertNoFields(); break; case "tcp.srcport": field.AssertShowDecimal(tcpDatagram.SourcePort); field.AssertNoFields(); break; case "tcp.dstport": field.AssertShowDecimal(tcpDatagram.DestinationPort); field.AssertNoFields(); break; case "tcp.port": Assert.IsTrue(ushort.Parse(field.Show()) == tcpDatagram.SourcePort || ushort.Parse(field.Show()) == tcpDatagram.DestinationPort); field.AssertNoFields(); break; case "tcp.seq": field.AssertShowDecimal(tcpDatagram.SequenceNumber); field.AssertNoFields(); break; case "tcp.nxtseq": field.AssertShowDecimal(tcpDatagram.NextSequenceNumber); field.AssertNoFields(); break; case "tcp.ack": field.AssertShowDecimal(tcpDatagram.AcknowledgmentNumber); foreach (XElement subfield in field.Fields()) { switch (subfield.Name()) { case "_ws.expert": break; default: subfield.AssertNoFields(); throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name()); } } break; case "tcp.hdr_len": field.AssertShowDecimal(tcpDatagram.HeaderLength); field.AssertNoFields(); break; case "tcp.flags": ushort flags = (ushort)((tcpDatagram.Reserved << 9) | (((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) | (byte)tcpDatagram.ControlBits); field.AssertShowDecimal(flags); foreach (var flagField in field.Fields()) { switch (flagField.Name()) { case "tcp.flags.res": flagField.AssertNoFields(); break; case "tcp.flags.ns": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsNonceSum); break; case "tcp.flags.cwr": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced); break; case "tcp.flags.ecn": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho); break; case "tcp.flags.urg": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsUrgent); break; case "tcp.flags.ack": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment); break; case "tcp.flags.push": flagField.AssertNoFields(); flagField.AssertShowDecimal(tcpDatagram.IsPush); break; case "tcp.flags.reset": flagField.AssertShowDecimal(tcpDatagram.IsReset); foreach (XElement subfield in flagField.Fields()) { switch (subfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name()); } } break; case "tcp.flags.syn": flagField.AssertShowDecimal(tcpDatagram.IsSynchronize); foreach (XElement subfield in flagField.Fields()) { switch (subfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name()); } } break; case "tcp.flags.fin": flagField.AssertShowDecimal(tcpDatagram.IsFin); foreach (XElement subfield in flagField.Fields()) { switch (subfield.Name()) { case "_ws.expert": break; default: throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name()); } } break; default: throw new InvalidOperationException("Invalid TCP flag field name " + flagField.Name()); } } break; case "tcp.window_size_value": field.AssertShowDecimal(tcpDatagram.Window); field.AssertNoFields(); break; case "tcp.checksum": field.AssertShowDecimal(tcpDatagram.Checksum); IpV4Datagram ipV4Datagram = ipDatagram as IpV4Datagram; if (ipV4Datagram != null) { foreach (var checksumField in field.Fields()) { // When TCP checksum is zero Wireshark assumes it's Checksum Offloading and puts false in both checksum_good and checksum_bad. switch (checksumField.Name()) { case "tcp.checksum_good": checksumField.AssertNoFields(); checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && ipDatagram.IsTransportChecksumCorrect); break; case "tcp.checksum_bad": checksumField.AssertShowDecimal(!ipDatagram.IsTransportChecksumCorrect); if (checksumField.Fields().Any()) { checksumField.AssertNumFields(1); checksumField.Fields().First().AssertName("_ws.expert"); } break; case "tcp.checksum_calculated": checksumField.AssertNoFields(); if (ipDatagram.IsTransportChecksumCorrect) checksumField.AssertShowDecimal(tcpDatagram.Checksum); break; default: throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name()); } } } break; case "tcp.urgent_pointer": field.AssertShowDecimal(tcpDatagram.UrgentPointer); break; case "tcp.options": CompareTcpOptions(field, tcpDatagram.Options); break; case "tcp.stream": case "tcp.pdu.size": case "tcp.window_size": case "tcp.window_size_scalefactor": field.AssertNoFields(); break; case "": if (field.Show() == "Short segment. Segment/fragment does not contain a full TCP header (might be NMAP or someone else deliberately sending unusual packets)") { field.AssertNumFields(1); field.Fields().First().AssertName("_ws.expert"); } else { field.AssertNoFields(); } break; default: throw new InvalidOperationException("Invalid tcp field " + field.Name()); } return true; }
protected override bool CompareField(XElement field, Datagram datagram) { IpV6Datagram ipV6Datagram = (IpV6Datagram)datagram; SkipAuthenticationHeaders(ipV6Datagram); int optionsIndex = 0; switch (field.Name()) { case "ipv6.version": // TODO: Remove this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10706 is fixed. if (field.Show() != ipV6Datagram.Version.ToString()) return false; 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: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed. // headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.Addresses.Count); break; case "ipv6.routing_hdr.rpl.address": headerField.AssertNoFields(); // TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed. break; case "ipv6.routing_hdr.rpl.full_address": headerField.AssertNoFields(); // TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10673 is fixed. ++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; }
private static void CompareHttpFirstLine(XElement httpFirstLineElement, HttpDatagram httpDatagram) { foreach (var field in httpFirstLineElement.Fields()) { switch (field.Name()) { case "http.request.method": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); field.AssertShow(((HttpRequestDatagram)httpDatagram).Method.Method); break; case "http.request.uri": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10681 is fixed. // field.AssertShow(((HttpRequestDatagram)httpDatagram).Uri.ToWiresharkLiteral()); break; case "http.request.version": field.AssertNoFields(); if (httpDatagram.Version == null) { if (field.Show() != string.Empty) Assert.IsTrue(field.Show().Contains(" ") || field.Show().Length < 8); } else field.AssertShow(httpDatagram.Version.ToString()); break; case "http.response.code": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsResponse, field.Name() + " IsResponse"); field.AssertShowDecimal(IsBadHttp(httpDatagram) ? 0 : ((HttpResponseDatagram)httpDatagram).StatusCode.Value); break; case "http.response.phrase": field.AssertNoFields(); Datagram reasonPhrase = ((HttpResponseDatagram)httpDatagram).ReasonPhrase; if (reasonPhrase == null) Assert.IsTrue(IsBadHttp(httpDatagram)); else field.AssertValue(reasonPhrase); break; case "_ws.expert": break; default: throw new InvalidOperationException("Invalid HTTP first line field " + field.Name()); } } }
protected override bool CompareField(XElement field, Datagram datagram) { DnsDatagram dnsDatagram = (DnsDatagram)datagram; switch (field.Name()) { case "dns.id": field.AssertShowDecimal(dnsDatagram.Id); break; case "dns.flags": field.AssertShowDecimal(dnsDatagram.Subsegment(2, 2).ToArray().ReadUShort(0, Endianity.Big)); foreach (var flagField in field.Fields()) { switch (flagField.Name()) { case "dns.flags.response": flagField.AssertShowDecimal(dnsDatagram.IsResponse); break; case "dns.flags.opcode": flagField.AssertShowDecimal((byte)dnsDatagram.OpCode); break; case "dns.flags.conflict": // TODO: Support LLMNR. case "dns.flags.authoritative": flagField.AssertShowDecimal(dnsDatagram.IsAuthoritativeAnswer); break; case "dns.flags.truncated": flagField.AssertShowDecimal(dnsDatagram.IsTruncated); break; case "dns.flags.tentative": // TODO: Support LLMNR. case "dns.flags.recdesired": flagField.AssertShowDecimal(dnsDatagram.IsRecursionDesired); break; case "dns.flags.recavail": flagField.AssertShowDecimal(dnsDatagram.IsRecursionAvailable); break; case "dns.flags.z": flagField.AssertShowDecimal(dnsDatagram.FutureUse); break; case "dns.flags.authenticated": flagField.AssertShowDecimal(dnsDatagram.IsAuthenticData); break; case "dns.flags.checkdisable": flagField.AssertShowDecimal(dnsDatagram.IsCheckingDisabled); break; case "dns.flags.rcode": flagField.AssertShowDecimal((ushort)dnsDatagram.ResponseCode); break; default: throw new InvalidOperationException("Invalid DNS flag field " + flagField.Name()); } } break; case "dns.count.queries": case "dns.count.zones": field.AssertShowDecimal(dnsDatagram.QueryCount); break; case "dns.count.answers": case "dns.count.prerequisites": field.AssertShowDecimal(dnsDatagram.AnswerCount); break; case "dns.count.auth_rr": case "dns.count.updates": field.AssertShowDecimal(dnsDatagram.AuthorityCount); break; case "dns.count.add_rr": field.AssertShowDecimal(dnsDatagram.AdditionalCount); break; case "": var resourceRecordsFields = field.Fields(); switch (field.Show()) { case "Queries": case "Zone": CompareResourceRecords(resourceRecordsFields, dnsDatagram.Queries); break; case "Answers": case "Prerequisites": CompareResourceRecords(resourceRecordsFields, dnsDatagram.Answers); break; case "Authoritative nameservers": case "Updates": CompareResourceRecords(resourceRecordsFields, dnsDatagram.Authorities); break; case "Additional records": CompareResourceRecords(resourceRecordsFields, dnsDatagram.Additionals); break; default: throw new InvalidOperationException("Invalid DNS resource records field " + field.Show()); } break; case "dns.response_to": case "dns.time": break; default: throw new InvalidOperationException("Invalid DNS field " + field.Name()); } return true; }
private static void CompareTcpOptions(XElement element, TcpOptions options) { int currentOptionIndex = 0; foreach (var field in element.Fields()) { if (currentOptionIndex >= options.Count) { Assert.IsFalse(options.IsValid, "Options IsValid"); Assert.IsTrue( field.Show().StartsWith("Unknown (0x0a) ") || // Unknown in Wireshark but known (and invalid) in Pcap.Net field.Show().Contains("bytes says option goes past end of options") || field.Show().Contains(") (with too-short option length = "), "Options show: " + field.Show()); Assert.AreEqual(options.Count, currentOptionIndex, "Options Count"); return; } TcpOption option = options[currentOptionIndex]; switch (field.Name()) { case "": switch (option.OptionType) { case TcpOptionType.SelectiveNegativeAcknowledgements: // TODO: Support Selective Negative Acknowledgements. Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString())); field.AssertNoFields(); break; case (TcpOptionType)78: // TODO: Support Riverbed. break; default: field.AssertShow(option.GetWiresharkString()); break; } switch (option.OptionType) { case TcpOptionType.WindowScale: TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option; foreach (var subField in field.Fields()) { switch (subField.Name()) { case "tcp.option_kind": subField.AssertShowDecimal((byte)windowScale.OptionType); break; case "tcp.option_len": subField.AssertShowDecimal(windowScale.Length); break; case "tcp.options.wscale.shift": subField.AssertShowDecimal(windowScale.ScaleFactorLog); break; case "tcp.options.wscale.multiplier": subField.AssertShowDecimal(1L << (windowScale.ScaleFactorLog % 32)); break; default: throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); } } break; case TcpOptionType.SelectiveAcknowledgment: var selectiveAcknowledgmentOption = (TcpOptionSelectiveAcknowledgment)option; int blockIndex = 0; foreach (var subField in field.Fields()) { switch (subField.Name()) { case "tcp.options.sack": subField.AssertShowDecimal(true); break; case "tcp.options.sack_le": subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].LeftEdge); break; case "tcp.options.sack_re": subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks[blockIndex].RightEdge); ++blockIndex; break; default: throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); } } break; case TcpOptionType.Timestamp: var timestampOption = (TcpOptionTimestamp)option; foreach (var subField in field.Fields()) { switch (subField.Name()) { case "tcp.option_kind": subField.AssertShowDecimal((byte)option.OptionType); break; case "tcp.option_len": subField.AssertShowDecimal(option.Length); break; case "tcp.options.timestamp.tsval": subField.AssertShowDecimal(timestampOption.TimestampValue); break; case "tcp.options.timestamp.tsecr": subField.AssertShowDecimal(timestampOption.TimestampEchoReply); break; default: throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); } } break; default: field.AssertNoFields(); break; } ++currentOptionIndex; break; case "tcp.options.mss": Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType); field.AssertShowDecimal(true); field.AssertNoFields(); break; case "tcp.options.mss_val": field.AssertShowDecimal(((TcpOptionMaximumSegmentSize)option).MaximumSegmentSize); field.AssertNoFields(); ++currentOptionIndex; break; case "tcp.options.echo": Assert.IsTrue(option is TcpOptionEchoReply || option is TcpOptionEcho); field.AssertShowDecimal(1); field.AssertNoFields(); break; case "tcp.options.cc": Assert.IsTrue(option is TcpOptionConnectionCountBase); field.AssertShowDecimal(1); field.AssertNoFields(); break; case "tcp.options.scps.vector": Assert.AreEqual((TcpOptionType)20, option.OptionType); if (field.Show() == "0") ++currentOptionIndex; ++currentOptionIndex; break; case "tcp.options.scps": Assert.AreEqual((TcpOptionType)20, option.OptionType); Assert.IsFalse(field.Fields().Any()); break; case "tcp.options.snack": // TODO: Support Selective Negative Acknowledgements. case "tcp.options.snack.offset": case "tcp.options.snack.size": Assert.AreEqual(TcpOptionType.SelectiveNegativeAcknowledgements, option.OptionType); field.AssertNoFields(); break; case "tcp.options.sack_perm": Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType); field.AssertNoFields(); ++currentOptionIndex; break; case "tcp.options.rvbd.probe": Assert.AreEqual((TcpOptionType)76, option.OptionType); // TODO: Support Riverbed. ++currentOptionIndex; break; case "tcp.options.rvbd.trpy": Assert.AreEqual((TcpOptionType)78, option.OptionType); // TODO: Support Riverbed. ++currentOptionIndex; break; default: throw new InvalidOperationException("Invalid tcp options field " + field.Name()); } } }
private bool CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord) { var data = resourceRecord.Data; string dataFieldName = dataField.Name(); string dataFieldShow = dataField.Show(); string dataFieldShowUntilColon = dataFieldShow.Split(':')[0]; switch (resourceRecord.DnsType) { case DnsType.A: dataField.AssertNoFields(); switch (dataFieldName) { case "dns.a": dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString()); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Ns: dataField.AssertNoFields(); switch (dataFieldName) { case "dns.ns": dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Mailbox: dataField.AssertName("dns.mb"); dataField.AssertNoFields(); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); break; case DnsType.Md: dataField.AssertName("dns.md"); dataField.AssertNoFields(); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); break; case DnsType.MailForwarder: dataField.AssertName("dns.mf"); dataField.AssertNoFields(); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); break; case DnsType.MailGroup: // 8. dataField.AssertName("dns.mg"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.MailRename: // 9. dataField.AssertName("dns.mr"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.CName: dataField.AssertName("dns.cname"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.StartOfAuthority: var startOfAuthority = (DnsResourceDataStartOfAuthority)data; dataField.AssertNoFields(); switch (dataField.Name()) { case "dns.soa.mname": dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.MainNameServer)); break; case "dns.soa.rname": dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.ResponsibleMailbox)); break; case "dns.soa.serial_number": dataField.AssertShowDecimal(startOfAuthority.Serial.Value); break; case "dns.soa.refresh_interval": dataField.AssertShowDecimal(startOfAuthority.Refresh); break; case "dns.soa.retry_interval": dataField.AssertShowDecimal(startOfAuthority.Retry); break; case "dns.soa.expire_limit": dataField.AssertShowDecimal(startOfAuthority.Expire); break; case "dns.soa.mininum_ttl": dataField.AssertShowDecimal(startOfAuthority.MinimumTtl); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.WellKnownService: var wksData = (DnsResourceDataWellKnownService)data; dataField.AssertNoFields(); switch (dataField.Name()) { case "dns.wks.address": dataField.AssertShow(wksData.Address.ToString()); break; case "dns.wks.protocol": dataField.AssertShowDecimal((byte)wksData.Protocol); break; case "dns.wks.bits": while (wksData.Bitmap[_wksBitmapIndex] == 0x00) ++_wksBitmapIndex; dataField.AssertShowDecimal(wksData.Bitmap[_wksBitmapIndex++]); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.Ptr: dataField.AssertName("dns.ptr.domain_name"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.HInfo: dataField.AssertNoFields(); var hInfoData = (DnsResourceDataHostInformation)data; switch (dataFieldName) { case "dns.hinfo.cpu_length": dataField.AssertShowDecimal(hInfoData.Cpu.Length); break; case "dns.hinfo.cpu": dataField.AssertValue(hInfoData.Cpu); break; case "dns.hinfo.os_length": dataField.AssertShowDecimal(hInfoData.OperatingSystem.Length); break; case "dns.hinfo.os": dataField.AssertValue(hInfoData.OperatingSystem); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.MInfo: dataField.AssertNoFields(); var mInfoData = (DnsResourceDataMailingListInfo)data; switch (dataFieldName) { case "dns.minfo.r": dataField.AssertShow(GetWiresharkDomainName(mInfoData.MailingList)); break; case "dns.minfo.e": dataField.AssertShow(GetWiresharkDomainName(mInfoData.ErrorMailbox)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.MailExchange: var mxData = (DnsResourceDataMailExchange)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.mx.preference": dataField.AssertShowDecimal(mxData.Preference); break; case "dns.mx.mail_exchange": dataField.AssertShow(GetWiresharkDomainName(mxData.MailExchangeHost)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Txt: // 16. var txtData = (DnsResourceDataText)data; dataField.AssertNoFields(); switch (dataField.Name()) { case "dns.txt.length": dataField.AssertShowDecimal(txtData.Text[_txtTypeIndex].Length); break; case "dns.txt": dataField.AssertValue(txtData.Text[_txtTypeIndex]); ++_txtTypeIndex; break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.SenderPolicyFramework: // 99. var spfData = (DnsResourceDataText)data; dataField.AssertNoFields(); switch (dataField.Name()) { case "dns.spf.length": dataField.AssertShowDecimal(spfData.Text[_spfTypeIndex].Length); break; case "dns.spf": dataField.AssertValue(spfData.Text[_spfTypeIndex]); ++_spfTypeIndex; break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.ResponsiblePerson: var rpData = (DnsResourceDataResponsiblePerson)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.rp.mailbox": dataField.AssertShow(GetWiresharkDomainName(rpData.Mailbox)); break; case "dns.rp.txt_rr": dataField.AssertShow(GetWiresharkDomainName(rpData.TextDomain)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.AfsDatabase: var afsDbData = (DnsResourceDataAfsDatabase)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.afsdb.subtype": dataField.AssertShowDecimal((ushort)afsDbData.Subtype); break; case "dns.afsdb.hostname": dataField.AssertShow(GetWiresharkDomainName(afsDbData.HostName)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.X25: var x25 = (DnsResourceDataString)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.x25.length": dataField.AssertShowDecimal(x25.String.Length); break; case "dns.x25.psdn_address": dataField.AssertValue(x25.String); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.Isdn: var isdnData = (DnsResourceDataIsdn)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.idsn.length": dataField.AssertShowDecimal(isdnData.IsdnAddress.Length); break; case "dns.idsn.address": dataField.AssertValue(isdnData.IsdnAddress); break; case "dns.idsn.sa.length": dataField.AssertShowDecimal(isdnData.Subaddress.Length); break; case "dns.idsn.sa.address": dataField.AssertValue(isdnData.Subaddress); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.RouteThrough: dataField.AssertNoFields(); var rtData = (DnsResourceDataRouteThrough)data; switch (dataFieldName) { case "dns.rt.subtype": dataField.AssertShowDecimal(rtData.Preference); break; case "dns.rt.intermediate_host": dataField.AssertShow(GetWiresharkDomainName(rtData.IntermediateHost)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.NetworkServiceAccessPoint: var nsapData = (DnsResourceDataNetworkServiceAccessPoint)data; switch (dataFieldName) { case "dns.nsap.rdata": byte[] nsapId = new byte[6]; nsapId.Write(0, nsapData.SystemIdentifier, Endianity.Big); dataField.AssertValue(nsapData.AreaAddress.Concat(nsapId).Concat(nsapData.Selector)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.NetworkServiceAccessPointPointer: dataField.AssertName("dns.nsap_ptr.owner"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.Key: var keyData = (DnsResourceDataKey)data; switch (dataFieldName) { case "dns.key.flags": foreach (var flagField in dataField.Fields()) { flagField.AssertNoFields(); int flagCount = GetFlagCount(flagField); switch (flagCount) { case 0: flagField.AssertShowDecimal(keyData.AuthenticationProhibited); break; case 1: flagField.AssertShowDecimal(keyData.ConfidentialityProhibited); break; case 2: flagField.AssertShowDecimal(keyData.Experimental); break; case 5: flagField.AssertShowDecimal(keyData.UserAssociated); break; case 6: flagField.AssertShowDecimal(keyData.NameType == DnsKeyNameType.NonZoneEntity); break; case 8: flagField.AssertShowDecimal(keyData.IpSec); break; case 9: flagField.AssertShowDecimal(keyData.Email); break; case 12: flagField.AssertShowDecimal((byte)keyData.Signatory); break; default: throw new InvalidOperationException("Invalid flag count " + flagCount); } } break; case "dns.key.protocol": dataField.AssertNoFields(); dataField.AssertShowDecimal((byte)keyData.Protocol); break; case "dns.key.algorithm": dataField.AssertNoFields(); dataField.AssertShowDecimal((byte)keyData.Algorithm); break; case "dns.key.key_id": dataField.AssertNoFields(); dataField.AssertShowDecimal(keyData.KeyTag); break; case "dns.key.public_key": dataField.AssertNoFields(); byte[] flagsExtension; if (keyData.FlagsExtension == null) { flagsExtension = new byte[0]; } else { flagsExtension = new byte[2]; flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big); } dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey)); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Signature: // 24. case DnsType.ResourceRecordSignature: // 46. dataField.AssertNoFields(); var sigData = (DnsResourceDataSignature)data; switch (dataFieldName) { case "dns.rrsig.type_covered": dataField.AssertShowDecimal((ushort)sigData.TypeCovered); break; case "dns.rrsig.algorithm": dataField.AssertShowDecimal((byte)sigData.Algorithm); break; case "dns.rrsig.labels": dataField.AssertShowDecimal(sigData.Labels); break; case "dns.rrsig.original_ttl": dataField.AssertShowDecimal(sigData.OriginalTtl); break; case "dns.rrsig.signature_expiration": dataField.AssertValue(sigData.SignatureExpiration); break; case "dns.rrsig.signature_inception": dataField.AssertValue(sigData.SignatureInception); break; case "dns.rrsig.key_tag": dataField.AssertShowDecimal(sigData.KeyTag); break; case "dns.rrsig.signers_name": dataField.AssertShow(GetWiresharkDomainName(sigData.SignersName)); break; case "dns.rrsig.signature": dataField.AssertValue(sigData.Signature); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.PointerX400: var pxData = (DnsResourceDataX400Pointer)data; switch (dataField.Name()) { case "dns.px.preference": dataField.AssertShowDecimal(pxData.Preference); break; case "dns.px.map822": dataField.AssertShow(GetWiresharkDomainName(pxData.Map822)); break; case "dns.px.map400": dataField.AssertShow(GetWiresharkDomainName(pxData.MapX400)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } dataField.AssertNoFields(); break; case DnsType.GeographicalPosition: dataField.AssertNoFields(); var gposData = (DnsResourceDataGeographicalPosition)data; switch (dataFieldName) { case "dns.gpos.longitude_length": dataField.AssertShowDecimal(gposData.Longitude.Length); break; case "dns.gpos.longitude": dataField.AssertShow(gposData.Longitude); break; case "dns.gpos.latitude_length": dataField.AssertShowDecimal(gposData.Latitude.Length); break; case "dns.gpos.latitude": dataField.AssertShow(gposData.Latitude); break; case "dns.gpos.altitude_length": dataField.AssertShowDecimal(gposData.Altitude.Length); break; case "dns.gpos.altitude": dataField.AssertShow(gposData.Altitude); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.Aaaa: dataField.AssertName("dns.aaaa"); dataField.AssertShow(GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data)); dataField.AssertNoFields(); break; case DnsType.Location: var locData = (DnsResourceDataLocationInformation)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.loc.version": dataField.AssertShowDecimal(locData.Version); break; case "dns.loc.unknown_data": Assert.AreNotEqual(0, locData.Version); break; case "dns.loc.size": Assert.AreEqual(0, locData.Version); string sizeValue = dataField.Showname().Split('(', ')')[1]; Assert.AreEqual(GetPrecisionValueString(locData.Size), sizeValue); break; case "dns.loc.horizontal_precision": Assert.AreEqual(0, locData.Version); string horizontalPrecisionValue = dataField.Showname().Split('(', ')')[1]; Assert.AreEqual(GetPrecisionValueString(locData.HorizontalPrecision), horizontalPrecisionValue); break; case "dns.loc.vertial_precision": Assert.AreEqual(0, locData.Version); string verticalPrecisionValue = dataField.Showname().Split('(', ')')[1]; Assert.AreEqual(GetPrecisionValueString(locData.VerticalPrecision), verticalPrecisionValue); break; case "dns.loc.latitude": Assert.AreEqual(0, locData.Version); dataField.AssertShowDecimal(locData.Latitude); break; case "dns.loc.longitude": Assert.AreEqual(0, locData.Version); dataField.AssertShowDecimal(locData.Longitude); break; case "dns.loc.altitude": Assert.AreEqual(0, locData.Version); dataField.AssertShowDecimal(locData.Altitude); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.NextDomain: var nxtData = (DnsResourceDataNextDomain)data; switch (dataField.Name()) { case "dns.nxt.next_domain_name": dataField.AssertShow(GetWiresharkDomainName(nxtData.NextDomainName)); break; case "": // TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10615 is fixed. // DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First(); // DnsType expectedType; // if (!TryGetDnsType(dataFieldShow, out expectedType)) // throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType)); // Assert.AreEqual(expectedType, actualType); return false; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } dataField.AssertNoFields(); break; case DnsType.ServerSelection: dataField.AssertNoFields(); var srvData = (DnsResourceDataServerSelection)data; switch (dataFieldName) { case "dns.srv.priority": dataField.AssertShowDecimal(srvData.Priority); break; case "dns.srv.weight": dataField.AssertShowDecimal(srvData.Weight); break; case "dns.srv.port": dataField.AssertShowDecimal(srvData.Port); break; case "dns.srv.target": dataField.AssertShow(GetWiresharkDomainName(srvData.Target)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.NaPtr: var naPtrData = (DnsResourceDataNamingAuthorityPointer)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.naptr.order": dataField.AssertShowDecimal(naPtrData.Order); break; case "dns.naptr.preference": dataField.AssertShowDecimal(naPtrData.Preference); break; case "dns.naptr.flags_length": dataField.AssertShowDecimal(naPtrData.Flags.Length); break; case "dns.naptr.flags": dataField.AssertValue(naPtrData.Flags); break; case "dns.naptr.service_length": dataField.AssertShowDecimal(naPtrData.Services.Length); break; case "dns.naptr.service": dataField.AssertValue(naPtrData.Services); break; case "dns.naptr.regex_length": dataField.AssertShowDecimal(naPtrData.RegularExpression.Length); break; case "dns.naptr.regex": dataField.AssertValue(naPtrData.RegularExpression); break; case "dns.naptr.replacement_length": dataField.AssertShowDecimal(naPtrData.Replacement.NonCompressedLength); break; case "dns.naptr.replacement": dataField.AssertShow(GetWiresharkDomainName(naPtrData.Replacement)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.KeyExchanger: dataField.AssertNoFields(); var kxData = (DnsResourceDataKeyExchanger)data; switch (dataFieldName) { case "dns.kx.preference": dataField.AssertShowDecimal(kxData.Preference); break; case "dns.kx.key_exchange": dataField.AssertShow(GetWiresharkDomainName(kxData.KeyExchangeHost)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.Cert: dataField.AssertNoFields(); var certData = (DnsResourceDataCertificate)data; switch (dataFieldName) { case "dns.cert.type": dataField.AssertShowDecimal((ushort)certData.CertificateType); break; case "dns.cert.key_tag": dataField.AssertShowDecimal(certData.KeyTag); break; case "dns.cert.algorithm": dataField.AssertShowDecimal((byte)certData.Algorithm); break; case "dns.cert.certificate": dataField.AssertValue(certData.Certificate); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.A6: var a6Data = (DnsResourceDataA6)data; switch (dataFieldName) { case "dns.a6.prefix_len": dataField.AssertShowDecimal(a6Data.PrefixLength); break; case "dns.a6.address_suffix": Assert.AreEqual(new IpV6Address(dataFieldShow), a6Data.AddressSuffix); break; case "dns.a6.prefix_name": dataField.AssertShow(GetWiresharkDomainName(a6Data.PrefixName)); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.DName: dataField.AssertName("dns.dname"); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertNoFields(); break; case DnsType.Opt: var optResourceRecord = (DnsOptResourceRecord)resourceRecord; var optData = (DnsResourceDataOptions)data; switch (dataFieldName) { case "dns.rr.udp_payload_size": _optOptionIndex = 0; dataField.AssertNoFields(); dataField.AssertShowDecimal(optResourceRecord.SendersUdpPayloadSize); break; case "dns.resp.ext_rcode": dataField.AssertNoFields(); dataField.AssertShowDecimal(optResourceRecord.ExtendedReturnCode); break; case "dns.resp.edns0_version": dataField.AssertNoFields(); dataField.AssertShowDecimal((byte)optResourceRecord.Version); break; case "dns.resp.z": DnsOptFlags flags = optResourceRecord.Flags; dataField.AssertShowDecimal((ushort)flags); foreach (XElement subfield in dataField.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "dns.resp.z.do": subfield.AssertShowDecimal((flags & DnsOptFlags.DnsSecOk) == DnsOptFlags.DnsSecOk); break; case "dns.resp.z.reserved": subfield.AssertShowDecimal(0); break; default: throw new InvalidOperationException("Invalid DNS data subfield name " + subfield.Name()); } } break; case "dns.opt": foreach (XElement subfield in dataField.Fields()) { DnsOption dnsOption = optData.Options.Options[_optOptionIndex]; var clientSubnet = dnsOption as DnsOptionClientSubnet; switch (subfield.Name()) { case "dns.opt.code": subfield.AssertNoFields(); subfield.AssertShowDecimal((ushort)dnsOption.Code); break; case "dns.opt.len": subfield.AssertShowDecimal(dnsOption.DataLength); if (subfield.Fields().Any()) { Assert.AreEqual(1, subfield.Fields().Count()); subfield.Fields().First().AssertName("_ws.expert"); } break; case "dns.opt.data": subfield.AssertNoFields(); switch (dnsOption.Code) { case DnsOptionCode.UpdateLease: subfield.AssertValue((uint)((DnsOptionUpdateLease)dnsOption).Lease); break; case DnsOptionCode.LongLivedQuery: byte[] expectedLongLivedQueryValue = new byte[dnsOption.DataLength]; var longLivedQuery = (DnsOptionLongLivedQuery)dnsOption; int longLivedQueryOffset = 0; expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.Version, Endianity.Big); expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, (ushort)longLivedQuery.OpCode, Endianity.Big); expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, (ushort)longLivedQuery.ErrorCode, Endianity.Big); expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.Id, Endianity.Big); expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.LeaseLife, Endianity.Big); subfield.AssertValue(expectedLongLivedQueryValue); break; case DnsOptionCode.ClientSubnet: byte[] expectedClientSubnetValue = new byte[dnsOption.DataLength]; int clientSubnetOffset = 0; expectedClientSubnetValue.Write(ref clientSubnetOffset, (ushort)clientSubnet.Family, Endianity.Big); expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.SourceNetmask); expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.ScopeNetmask); expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.Address); subfield.AssertValue(expectedClientSubnetValue); break; default: subfield.AssertValue(((DnsOptionAnything)dnsOption).Data); break; } if (dnsOption.Code != DnsOptionCode.ClientSubnet) ++_optOptionIndex; break; case "dns.opt.client.family": subfield.AssertNoFields(); subfield.AssertShowDecimal((ushort)clientSubnet.Family); break; case "dns.opt.client.netmask": subfield.AssertNoFields(); subfield.AssertShowDecimal(clientSubnet.SourceNetmask); break; case "dns.opt.client.scope": subfield.AssertNoFields(); subfield.AssertShowDecimal(clientSubnet.ScopeNetmask); break; case "dns.opt.client.addr": case "dns.opt.client.addr4": case "dns.opt.client.addr6": subfield.AssertNoFields(); if (clientSubnet.Address.Length <= 16) { subfield.AssertValue(clientSubnet.Address); } else { subfield.AssertValue(clientSubnet.Address.Take(16)); // TODO: Remove this return when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10988 is fixed. return false; } ++_optOptionIndex; break; default: throw new InvalidOperationException("Invalid DNS data subfield name " + subfield.Name()); } } break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.AddressPrefixList: var aplData = (DnsResourceDataAddressPrefixList)data; switch (dataFieldName) { case "dns.apl.address_family": dataField.AssertNoFields(); dataField.AssertShowDecimal((ushort)aplData.Items[_aplItemIndex++].AddressFamily); break; case "dns.apl.coded_prefix": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength); break; case "dns.apl.negation": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].Negation); break; case "dns.apl.afdlength": dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length); break; case "dns.apl.afdpart.data": case "dns.apl.afdpart.ipv4": case "dns.apl.afdpart.ipv6": if (dataFieldName != "dns.apl.afdpart.data") { Assert.AreEqual(dataFieldName == "dns.apl.afdpart.ipv4" ? AddressFamily.IpV4 : AddressFamily.IpV6, aplData.Items[_aplItemIndex - 1].AddressFamily); } dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.DelegationSigner: // 43. case DnsType.DnsSecLookAsideValidation: // 32769. dataField.AssertNoFields(); var dsData = (DnsResourceDataDelegationSigner)data; switch (dataFieldName) { case "dns.ds.key_id": dataField.AssertShowDecimal(dsData.KeyTag); break; case "dns.ds.algorithm": dataField.AssertShowDecimal((byte)dsData.Algorithm); break; case "dns.ds.digest_type": dataField.AssertShowDecimal((byte)dsData.DigestType); break; case "dns.ds.digest": dataField.AssertValue(dsData.Digest); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.SshFingerprint: var sshFpData = (DnsResourceDataSshFingerprint)data; dataField.AssertNoFields(); switch (dataFieldName) { case "dns.sshfp.algorithm": dataField.AssertShowDecimal((byte)sshFpData.Algorithm); break; case "dns.sshfp.fingerprint.type": dataField.AssertShowDecimal((byte)sshFpData.FingerprintType); break; case "dns.sshfp.fingerprint": dataField.AssertValue(sshFpData.Fingerprint); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.IpSecKey: dataField.AssertNoFields(); var ipSecKeyData = (DnsResourceDataIpSecKey)data; switch (dataField.Name()) { case "dns.ipseckey.gateway_precedence": dataField.AssertShowDecimal(ipSecKeyData.Precedence); break; case "dns.ipseckey.gateway_type": dataField.AssertShowDecimal((byte)ipSecKeyData.GatewayType); break; case "dns.ipseckey.gateway_algorithm": dataField.AssertShowDecimal((byte)ipSecKeyData.Algorithm); break; case "dns.ipseckey.gateway_ipv4": dataField.AssertShow(((DnsGatewayIpV4)ipSecKeyData.Gateway).Value.ToString()); break; case "dns.ipseckey.gateway_ipv6": dataField.AssertValue(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value.ToValue()); break; case "dns.ipseckey.gateway_dns": dataField.AssertShow(GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value)); break; case "dns.ipseckey.public_key": dataField.AssertValue(ipSecKeyData.PublicKey); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } break; case DnsType.NSec: var nSecData = (DnsResourceDataNextDomainSecure)data; switch (dataField.Name()) { case "dns.nsec.next_domain_name": dataField.AssertShow(GetWiresharkDomainName(nSecData.NextDomainName)); break; case "": DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++]; DnsType expectedType; if (!TryGetDnsType(dataFieldShow, out expectedType)) throw new InvalidOperationException(string.Format("Failed parsing type from {0} : {1}", dataFieldShow, actualType)); Assert.AreEqual(expectedType, actualType); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataField.Name()); } dataField.AssertNoFields(); break; case DnsType.DnsKey: var dnsKeyData = (DnsResourceDataDnsKey)data; switch (dataFieldName) { case "dns.dnskey.flags": foreach (XElement subfield in dataField.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "dns.dnskey.flags.zone_key": subfield.AssertShowDecimal(dnsKeyData.ZoneKey); break; case "dns.dnskey.flags.key_revoked": subfield.AssertShowDecimal(dnsKeyData.Revoke); break; case "dns.dnskey.flags.secure_entry_point": subfield.AssertShowDecimal(dnsKeyData.SecureEntryPoint); break; case "dns.dnskey.flags.reserved": subfield.AssertShowDecimal(0); break; case "dns.dnskey.protocol": subfield.AssertShowDecimal(dnsKeyData.Protocol); break; case "dns.dnskey.algorithm": subfield.AssertShowDecimal((byte)dnsKeyData.Algorithm); break; default: throw new InvalidOperationException("Invalid DNS flags subfield name " + subfield.Name()); } } break; case "dns.dnskey.key_id": dataField.AssertNoFields(); dataField.AssertShowDecimal(dnsKeyData.KeyTag); break; case "dns.dnskey.public_key": dataField.AssertNoFields(); dataField.AssertValue(dnsKeyData.PublicKey); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } break; case DnsType.DynamicHostConfigurationId: switch (dataFieldName) { case "dns.dhcid.rdata": dataField.AssertValue(((DnsResourceDataAnything)data).Data); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.NSec3: var nSec3Data = (DnsResourceDataNextDomainSecure3)data; switch (dataFieldName) { case "dns.nsec3.algo": dataField.AssertShowDecimal((byte)nSec3Data.HashAlgorithm); dataField.AssertNoFields(); break; case "dns.nsec3.flags": dataField.AssertShowDecimal((byte)nSec3Data.Flags); foreach (var flagField in dataField.Fields()) { string flagFieldName = flagField.Name(); switch (flagFieldName) { case "dns.nsec3.flags.opt_out": dataField.AssertShowDecimal((nSec3Data.Flags & DnsSecNSec3Flags.OptOut) == DnsSecNSec3Flags.OptOut); break; default: throw new InvalidOperationException("Invalid DNS resource data flag field name " + flagFieldName); } } break; case "dns.nsec3.iterations": dataField.AssertShowDecimal(nSec3Data.Iterations); dataField.AssertNoFields(); break; case "dns.nsec3.salt_length": dataField.AssertShowDecimal(nSec3Data.Salt.Length); dataField.AssertNoFields(); break; case "dns.nsec3.salt_value": dataField.AssertValue(nSec3Data.Salt); dataField.AssertNoFields(); break; case "dns.nsec3.hash_length": dataField.AssertShowDecimal(nSec3Data.NextHashedOwnerName.Length); dataField.AssertNoFields(); break; case "dns.nsec3.hash_value": dataField.AssertValue(nSec3Data.NextHashedOwnerName); dataField.AssertNoFields(); break; case "": DnsType expectedType = nSec3Data.TypesExist[_nSec3TypeIndex++]; Assert.IsTrue(dataField.Show().StartsWith("RR type in bit map: ")); if (dataField.Show().EndsWith(string.Format("({0})", (ushort)expectedType))) dataField.AssertShow(string.Format("RR type in bit map: Unknown ({0})", (ushort)expectedType)); else Assert.IsTrue( dataFieldShow.Replace("-", "").StartsWith("RR type in bit map: " + GetWiresharkDnsType(expectedType).Replace("-", "")), string.Format("{0} : {1}", dataFieldShow, GetWiresharkDnsType(expectedType))); dataField.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } break; case DnsType.NSec3Parameters: var nSec3ParamData = (DnsResourceDataNextDomainSecure3Parameters)data; switch (dataFieldName) { case "dns.nsec3.algo": dataField.AssertShowDecimal((byte)nSec3ParamData.HashAlgorithm); break; case "dns.nsec3.flags": dataField.AssertShowDecimal((byte)nSec3ParamData.Flags); break; case "dns.nsec3.iterations": dataField.AssertShowDecimal(nSec3ParamData.Iterations); break; case "dns.nsec3.salt_length": dataField.AssertShowDecimal(nSec3ParamData.Salt.Length); break; case "dns.nsec3.salt_value": dataField.AssertShow(nSec3ParamData.Salt); break; default: throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.Hip: var hipData = (DnsResourceDataHostIdentityProtocol)data; switch (dataFieldName) { case "dns.hip.hit": dataField.AssertShow(hipData.HostIdentityTag); break; case "dns.hip.pk": dataField.AssertShow(hipData.PublicKey); break; case "dns.hip.hit.length": dataField.AssertShowDecimal(hipData.HostIdentityTag.Length); break; case "dns.hip.hit.pk.algo": dataField.AssertShowDecimal((byte)hipData.PublicKeyAlgorithm); break; case "dns.hip.pk.length": dataField.AssertShowDecimal(hipData.PublicKey.Length); break; case "dns.hip.rendezvous_server": dataField.AssertShow(GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++])); break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } dataField.AssertNoFields(); break; case DnsType.TKey: dataField.AssertNoFields(); var tKeyData = (DnsResourceDataTransactionKey)data; switch (dataFieldName) { case "dns.tkey.algo_name": dataField.AssertShow(GetWiresharkDomainName(tKeyData.Algorithm)); break; case "dns.tkey.signature_inception": dataField.AssertValue(tKeyData.Inception); break; case "dns.tkey.signature_expiration": dataField.AssertValue(tKeyData.Expiration); break; case "dns.tkey.mode": dataField.AssertShowDecimal((ushort)tKeyData.Mode); break; case "dns.tkey.error": dataField.AssertShowDecimal((ushort)tKeyData.Error); break; case "dns.tkey.key_size": dataField.AssertShowDecimal(tKeyData.Key.Length); break; case "dns.tkey.key_data": dataField.AssertValue(tKeyData.Key); break; case "dns.tkey.other_size": dataField.AssertShowDecimal(tKeyData.Other.Length); break; case "dns.tkey.other_data": dataField.AssertValue(tKeyData.Other); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldName); } break; case DnsType.TransactionSignature: var tSigData = (DnsResourceDataTransactionSignature)data; switch (dataFieldName) { case "dns.tsig.algorithm_name": dataField.AssertShow(GetWiresharkDomainName(tSigData.Algorithm)); dataField.AssertNoFields(); break; case "": switch (dataFieldShowUntilColon) { case "Time signed": dataField.AssertValue(tSigData.TimeSigned); break; default: throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); } dataField.AssertNoFields(); break; case "dns.tsig.fudge": dataField.AssertShowDecimal(tSigData.Fudge); dataField.AssertNoFields(); break; case "dns.tsig.mac_size": dataField.AssertShowDecimal(tSigData.MessageAuthenticationCode.Length); dataField.AssertNoFields(); break; case "dns.tsig.mac": dataField.AssertShow(""); Assert.AreEqual(1, dataField.Fields().Count()); var tsigSubfield = dataField.Fields().First(); tsigSubfield.AssertName("_ws.expert"); break; case "dns.tsig.original_id": dataField.AssertShowDecimal(tSigData.OriginalId); dataField.AssertNoFields(); break; case "dns.tsig.error": dataField.AssertShowDecimal((ushort)tSigData.Error); dataField.AssertNoFields(); break; case "dns.tsig.other_len": dataField.AssertShowDecimal(tSigData.Other.Length); dataField.AssertNoFields(); break; case "dns.tsig.other_data": dataField.AssertValue(tSigData.Other); dataField.AssertNoFields(); break; case "dns.tsig.time_signed": dataField.AssertValue(tSigData.TimeSigned); dataField.AssertNoFields(); break; case "_ws.expert": break; default: throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); } break; case DnsType.Null: dataField.AssertNoFields(); dataField.AssertName("dns.null"); dataField.AssertValue(((DnsResourceDataAnything)data).Data); break; case DnsType.CertificationAuthorityAuthorization: var certificationAuthorityAuthorization = (DnsResourceDataCertificationAuthorityAuthorization)data; switch (dataField.Name()) { case "dns.caa.flags": dataField.AssertShowDecimal((byte)certificationAuthorityAuthorization.Flags); foreach (XElement subfield in dataField.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "dns.caa.flags.issuer_critical": subfield.AssertShowDecimal((certificationAuthorityAuthorization.Flags & DnsCertificationAuthorityAuthorizationFlags.Critical) == DnsCertificationAuthorityAuthorizationFlags.Critical); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case "dns.caa.unknown": case "dns.caa.issue": foreach (XElement subfield in dataField.Fields()) { subfield.AssertNoFields(); switch (subfield.Name()) { case "dns.caa.tag_length": subfield.AssertShowDecimal(certificationAuthorityAuthorization.Tag.Length); break; case "dns.caa.tag": subfield.AssertValue(certificationAuthorityAuthorization.Tag); break; case "dns.caa.value": subfield.AssertValue(certificationAuthorityAuthorization.Value); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; default: throw new InvalidOperationException("Invalid field " + dataField.Name()); } break; case DnsType.EId: // 31. case DnsType.NimrodLocator: // 32. case DnsType.AsynchronousTransferModeAddress: // 34. case DnsType.Sink: // 40. case DnsType.NInfo: // 56. case DnsType.RKey: // 57. case DnsType.TrustAnchorLink: // 58. case DnsType.ChildDelegationSigner: // 59. case DnsType.UInfo: // 100. case DnsType.Uid: // 101. case DnsType.Gid: // 102. case DnsType.Unspecified: // 103. case DnsType.Ixfr: // 251. case DnsType.Axfr: // 252. case DnsType.MailB: // 253. case DnsType.MailA: // 254. case DnsType.Any: // 255. case DnsType.Uri: // 256. case DnsType.TrustAnchor: // 32768. default: if (dataField.Name() == "_ws.expert") { dataField.AssertShowname("Expert Info (Note/Undecoded): Dissector for DNS Type (" + (ushort)resourceRecord.DnsType + ") code not implemented, Contact Wireshark developers if you want this supported"); } else { dataField.AssertName("dns.data"); } break; } return true; }
protected override bool CompareField(XElement field, Datagram parentDatagram, Datagram datagram) { IpV4Datagram ipV4Datagram = (IpV4Datagram)parentDatagram; TcpDatagram tcpDatagram = (TcpDatagram)datagram; switch (field.Name()) { case "tcp.len": if (tcpDatagram.Payload == null) { // todo seems like a bug in tshark https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5235 break; // field.AssertShowDecimal(tcpDatagram.Length); } else field.AssertShowDecimal(tcpDatagram.Payload.Length); field.AssertNoFields(); break; case "tcp.srcport": field.AssertShowDecimal(tcpDatagram.SourcePort); field.AssertNoFields(); break; case "tcp.dstport": field.AssertShowDecimal(tcpDatagram.DestinationPort); field.AssertNoFields(); break; case "tcp.port": Assert.IsTrue(ushort.Parse(field.Show()) == tcpDatagram.SourcePort || ushort.Parse(field.Show()) == tcpDatagram.DestinationPort); field.AssertNoFields(); break; case "tcp.seq": field.AssertShowDecimal(tcpDatagram.SequenceNumber); field.AssertNoFields(); break; case "tcp.nxtseq": field.AssertShowDecimal(tcpDatagram.NextSequenceNumber); field.AssertNoFields(); break; case "tcp.ack": field.AssertShowDecimal(tcpDatagram.AcknowledgmentNumber); field.AssertNoFields(); break; case "tcp.hdr_len": field.AssertShowDecimal(tcpDatagram.HeaderLength); field.AssertNoFields(); break; case "tcp.flags": ushort flags = (ushort)((tcpDatagram.Reserved << 9) | (((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) | (byte)tcpDatagram.ControlBits); field.AssertShow("0x" + flags.ToString("x" + 4 * sizeof(byte))); foreach (var flagField in field.Fields()) { switch (flagField.Name()) { case "tcp.flags.cwr": flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced); break; case "tcp.flags.ecn": flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho); break; case "tcp.flags.urg": flagField.AssertShowDecimal(tcpDatagram.IsUrgent); break; case "tcp.flags.ack": flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment); break; case "tcp.flags.push": flagField.AssertShowDecimal(tcpDatagram.IsPush); break; case "tcp.flags.reset": flagField.AssertShowDecimal(tcpDatagram.IsReset); break; case "tcp.flags.syn": flagField.AssertShowDecimal(tcpDatagram.IsSynchronize); break; case "tcp.flags.fin": flagField.AssertShowDecimal(tcpDatagram.IsFin); break; } flagField.AssertNoFields(); } break; case "tcp.window_size_value": field.AssertShowDecimal(tcpDatagram.Window); field.AssertNoFields(); break; case "tcp.checksum": field.AssertShowHex(tcpDatagram.Checksum); if (!ipV4Datagram.Options.IsBadForWireshark()) { foreach (var checksumField in field.Fields()) { // When TCP checksum is zero Wireshark assumes it's Checksum Offloading and puts false in both checksum_good and checksum_bad. switch (checksumField.Name()) { case "tcp.checksum_good": checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && ipV4Datagram.IsTransportChecksumCorrect); break; case "tcp.checksum_bad": checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && !ipV4Datagram.IsTransportChecksumCorrect); break; default: throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name()); } checksumField.AssertNoFields(); } } break; case "tcp.urgent_pointer": field.AssertShowDecimal(tcpDatagram.UrgentPointer); field.AssertNoFields(); break; case "tcp.options": CompareTcpOptions(field, tcpDatagram.Options); break; case "tcp.stream": case "tcp.pdu.size": case "tcp.window_size": case "tcp.window_size_scalefactor": case "": field.AssertNoFields(); break; default: throw new InvalidOperationException("Invalid tcp field " + field.Name()); } return true; }
private static void CompareIgmpGroupRecord(XElement groupRecord, IgmpGroupRecordDatagram groupRecordDatagram) { int sourceAddressIndex = 0; foreach (var field in groupRecord.Fields()) { switch (field.Name()) { case "igmp.record_type": field.AssertShowDecimal((byte)groupRecordDatagram.RecordType); break; case "igmp.aux_data_len": field.AssertShowDecimal(groupRecordDatagram.AuxiliaryDataLength / 4); break; case "igmp.num_src": field.AssertShowDecimal(groupRecordDatagram.NumberOfSources); break; case "igmp.maddr": field.AssertShow(groupRecordDatagram.MulticastAddress.ToString()); break; case "igmp.saddr": field.AssertShow(groupRecordDatagram.SourceAddresses[sourceAddressIndex++].ToString()); break; case "igmp.aux_data": field.AssertShow(groupRecordDatagram.AuxiliaryData); break; default: throw new InvalidOperationException("Invalid igmp group record field " + field.Name()); } } }
private static void CompareIpV4Options(XElement element, IpV4Options options) { int currentOptionIndex = 0; foreach (var field in element.Fields()) { if (currentOptionIndex >= options.Count) { Assert.IsFalse(options.IsValid); Assert.IsTrue(field.Show() == "Commercial IP security option" || field.Show() == "Loose source route (length byte past end of options)" || field.Show() == "Time stamp:" || field.Show().StartsWith("Unknown") || field.Show().StartsWith("Security") || field.Show().StartsWith("Router Alert (with option length = ") || field.Show().StartsWith("Stream identifier (with option length = ") || field.Show().Contains("with too") || field.Show().Contains(" bytes says option goes past end of options") || field.Show().Contains("(length byte past end of options)") || XElementExtensions.Show(field.Fields().First()).StartsWith("Pointer: ") && XElementExtensions.Show(field.Fields().First()).EndsWith(" (points to middle of address)") || field.Fields().Where(value => value.Show() == "(suboption would go past end of option)").Count() != 0, field.Show()); break; } IpV4Option option = options[currentOptionIndex++]; if (option.OptionType == IpV4OptionType.BasicSecurity || option.OptionType == IpV4OptionType.TraceRoute) { Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString())); continue; // Wireshark doesn't support } field.AssertShow(option.GetWiresharkString()); if ((option is IpV4OptionUnknown)) continue; var optionShows = from f in field.Fields() select f.Show(); MoreAssert.AreSequenceEqual(optionShows, option.GetWiresharkSubfieldStrings()); } }