Commit dcaa5dd0 authored by Brickner_cp's avatar Brickner_cp

DNS

parent 847d3411
......@@ -39,6 +39,5 @@
/// Query class.
/// </summary>
Any = 255,
}
}
\ No newline at end of file
......@@ -92,75 +92,4 @@ namespace PcapDotNet.Packets.Dns
return length;
}
}
public enum DnsOptVersion : byte
{
Version0 = 0,
}
[Flags]
public enum DnsOptFlags : ushort
{
DnsSecOk = 0x8000,
}
/// <summary>
/// RFC 2671.
/// <pre>
/// +------+----------------+----------+
/// | bit | 0-7 | 8-15 |
/// +------+----------------+----------+
/// | 0 | Name |
/// | ... | |
/// +------+---------------------------+
/// | | Type = OPT |
/// +------+---------------------------+
/// | | Sender's UDP payload size |
/// +------+----------------+----------+
/// | | EXTENDED-RCODE | VERSION |
/// +------+----------------+----------+
/// | | Flags |
/// +------+---------------------------+
/// | | Resource Data Length |
/// +------+---------------------------+
/// | | Resource Data |
/// | ... | |
/// +------+---------------------------+
/// </pre>
/// </summary>
public sealed class DnsOptResourceRecord : DnsDataResourceRecord
{
public DnsOptResourceRecord(DnsDomainName domainName, ushort sendersUdpPayloadSize, byte extendedRcode, DnsOptVersion version, DnsOptFlags flags, DnsResourceDataOptions data)
: this(domainName, (DnsClass)sendersUdpPayloadSize, (extendedRcode << 24) | ((byte)version << 16) | (ushort)flags, data)
{
}
/// <summary>
/// The number of octets of the largest UDP payload that can be reassembled and delivered in the sender's network stack.
/// Note that path MTU, with or without fragmentation, may be smaller than this.
/// </summary>
public ushort SendersUdpPayloadSize { get { return (ushort)DnsClass; } }
/// <summary>
/// Forms upper 8 bits of extended 12-bit RCODE.
/// Note that EXTENDED-RCODE value "0" indicates that an unextended RCODE is in use (values "0" through "15").
/// </summary>
public byte ExtendedRcode { get { return (byte)(Ttl >> 24); } }
/// <summary>
/// Indicates the implementation level of whoever sets it.
/// Full conformance with this specification is indicated by version "0".
/// Requestors are encouraged to set this to the lowest implemented level capable of expressing a transaction,
/// to minimize the responder and network load of discovering the greatest common implementation level between requestor and responder.
/// A requestor's version numbering strategy should ideally be a run time configuration option.
/// </summary>
public DnsOptVersion Version { get { return (DnsOptVersion)(Ttl >> 16); }}
public DnsOptFlags Flags { get { return (DnsOptFlags)Ttl; } }
internal DnsOptResourceRecord(DnsDomainName domainName, DnsClass dnsClass, int ttl, DnsResourceData data)
: base(domainName, DnsType.Opt, dnsClass, ttl, data)
{
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
[Flags]
public enum DnsOptFlags : ushort
{
DnsSecOk = 0x8000,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2671.
/// <pre>
/// +------+----------------+----------+
/// | bit | 0-7 | 8-15 |
/// +------+----------------+----------+
/// | 0 | Name |
/// | ... | |
/// +------+---------------------------+
/// | | Type = OPT |
/// +------+---------------------------+
/// | | Sender's UDP payload size |
/// +------+----------------+----------+
/// | | EXTENDED-RCODE | VERSION |
/// +------+----------------+----------+
/// | | Flags |
/// +------+---------------------------+
/// | | Resource Data Length |
/// +------+---------------------------+
/// | | Resource Data |
/// | ... | |
/// +------+---------------------------+
/// </pre>
/// </summary>
public sealed class DnsOptResourceRecord : DnsDataResourceRecord
{
public DnsOptResourceRecord(DnsDomainName domainName, ushort sendersUdpPayloadSize, byte extendedRcode, DnsOptVersion version, DnsOptFlags flags, DnsResourceDataOptions data)
: this(domainName, (DnsClass)sendersUdpPayloadSize, (extendedRcode << 24) | ((byte)version << 16) | (ushort)flags, data)
{
}
/// <summary>
/// The number of octets of the largest UDP payload that can be reassembled and delivered in the sender's network stack.
/// Note that path MTU, with or without fragmentation, may be smaller than this.
/// </summary>
public ushort SendersUdpPayloadSize { get { return (ushort)DnsClass; } }
/// <summary>
/// Forms upper 8 bits of extended 12-bit RCODE.
/// Note that EXTENDED-RCODE value "0" indicates that an unextended RCODE is in use (values "0" through "15").
/// </summary>
public byte ExtendedRcode { get { return (byte)(Ttl >> 24); } }
/// <summary>
/// Indicates the implementation level of whoever sets it.
/// Full conformance with this specification is indicated by version "0".
/// Requestors are encouraged to set this to the lowest implemented level capable of expressing a transaction,
/// to minimize the responder and network load of discovering the greatest common implementation level between requestor and responder.
/// A requestor's version numbering strategy should ideally be a run time configuration option.
/// </summary>
public DnsOptVersion Version { get { return (DnsOptVersion)(Ttl >> 16); }}
public DnsOptFlags Flags { get { return (DnsOptFlags)Ttl; } }
internal DnsOptResourceRecord(DnsDomainName domainName, DnsClass dnsClass, int ttl, DnsResourceData data)
: base(domainName, DnsType.Opt, dnsClass, ttl, data)
{
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsOptVersion : byte
{
Version0 = 0,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFCs 1035, 1183, 1348, 1706, 1712, 1876, 1995, 2163, 2168, 2230, 2535, 2672, 2782, 2845, 2874, 2915, 2930, 3123, 3226, 3403, 3596, 3658, 3755, 4025,
/// 4034, 4255, 4398, 4408, 4431, 4701, 5155, 5205, 5864, 5936.
/// RFCs 1035, 1183, 1348, 1706, 1712, 1876, 1995, 2065, 2163, 2168, 2230, 2535, 2671, 2672, 2782, 2845, 2874, 2915, 2930, 3123, 3226, 3403, 3596, 3658,
/// 3755, 4025, 4034, 4255, 4398, 4408, 4431, 4701, 5011, 5155, 5205, 5864, 5936.
/// Other sources: ATMDOC, Barwood, Eastlake, Faltstrom, Hallam-Baker, PATTON, Reid, Weiler, Wijngaards.
/// Type fields are used in resource records.
/// </summary>
......
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFCs 2453, 2858.
/// </summary>
public enum AddressFamily : ushort
{
/// <summary>
/// IP (IP version 4).
/// </summary>
IpV4 = 1,
/// <summary>
/// IP6 (IP version 6).
/// </summary>
IpV6 = 2,
/// <summary>
/// Network Service Access Point.
/// </summary>
Nsap = 3,
/// <summary>
/// High-Level Data Link (8-bit multidrop).
/// </summary>
Hdlc = 4,
/// <summary>
/// BBN Report 1822.
/// </summary>
Bbn1822 = 5,
/// <summary>
/// 802 (includes all 802 media plus Ethernet "canonical format").
/// </summary>
Media802 = 6,
/// <summary>
/// E.163.
/// </summary>
E163 = 7,
/// <summary>
/// E.164 (SMDS, Frame Relay, ATM).
/// </summary>
E164 = 8,
/// <summary>
/// F.69 (Telex).
/// </summary>
F69 = 9,
/// <summary>
/// X.121 (X.25, Frame Relay).
/// </summary>
X121 = 10,
/// <summary>
/// IPX.
/// </summary>
Ipx = 11,
/// <summary>
/// Appletalk.
/// </summary>
AppleTalk = 12,
/// <summary>
/// Decnet IV.
/// </summary>
DecnetIv = 13,
/// <summary>
/// Banyan Vines.
/// </summary>
BanyanVines = 14,
/// <summary>
/// E.164 with NSAP format subaddress.
/// ATM Forum UNI 3.1. October 1995.
/// Andy Malis.
/// </summary>
E164WithNsapFormatSubaddresses = 15,
/// <summary>
/// DNS (Domain Name System).
/// </summary>
Dns = 16,
/// <summary>
/// Distinguished Name.
/// Charles Lynn.
/// </summary>
DistinguishedName = 17,
/// <summary>
/// AS Number.
/// Charles Lynn.
/// </summary>
AsNumber = 18,
/// <summary>
/// XTP over IP version 4.
/// Mike Saul.
/// </summary>
XtpOverIpV4 = 19,
/// <summary>
/// XTP over IP version 6.
/// Mike Saul.
/// </summary>
XtpOverIpV6 = 20,
/// <summary>
/// XTP native mode XTP.
/// Mike Saul.
/// </summary>
XtpNativeModeXtp = 21,
/// <summary>
/// Fibre Channel World-Wide Port Name.
/// Mark Bakke.
/// </summary>
FibreChannelWorldWidePortName = 22,
/// <summary>
/// Fibre Channel World-Wide Node Name.
/// Mark Bakke.
/// </summary>
FibreChannelWorldWideNodeName = 23,
/// <summary>
/// GWID.
/// Subra Hegde.
/// </summary>
Gwis = 24,
/// <summary>
/// RFCs 4761, 6074.
/// AFI for L2VPN information.
/// </summary>
AfiForL2VpnInformation = 25,
/// <summary>
/// EIGRP Common Service Family.
/// Donnie Savage.
/// </summary>
EigrpCommonServiceFamily = 16384,
/// <summary>
/// EIGRP IPv4 Service Family.
/// Donnie Savage.
/// </summary>
EigrpIpV4ServiceFamily = 16385,
/// <summary>
/// EIGRP IPv6 Service Family.
/// Donnie Savage.
/// </summary>
EigrpIpV6ServiceFamily = 16386,
/// <summary>
/// LISP Canonical Address Format (LCAF).
/// David Meyer.
/// </summary>
LispCanonicalAddressFormat = 16387,
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 3123.
/// <pre>
/// +-----+--------+---+-----------+
/// | bit | 0-7 | 8 | 9-15 |
/// +-----+--------+---+-----------+
/// | 0 | ADDRESSFAMILY |
/// +-----+--------+---+-----------+
/// | 16 | PREFIX | N | AFDLENGTH |
/// +-----+--------+---+-----------+
/// | 32 | AFDPART |
/// | ... | |
/// +-----+------------------------+
/// </pre>
/// </summary>
public class DnsAddressPrefix : IEquatable<DnsAddressPrefix>
{
private static class Offset
{
public const int AddressFamily = 0;
public const int PrefixLength = AddressFamily + sizeof(ushort);
public const int Negation = PrefixLength + sizeof(byte);
public const int AddressFamilyDependentPartLength = Negation;
public const int AddressFamilyDependentPart = AddressFamilyDependentPartLength + sizeof(byte);
}
public const int MinimumLength = Offset.AddressFamilyDependentPart;
private static class Mask
{
public const byte Negation = 0x80;
public const byte AddressFamilyDependentPartLength = 0x7F;
}
public const int AddressFamilyDependentPartMaxLength = (1 << 7) - 1;
public DnsAddressPrefix(AddressFamily addressFamily, byte prefixLength, bool negation, DataSegment addressFamilyDependentPart)
{
if (addressFamilyDependentPart.Length > AddressFamilyDependentPartMaxLength)
throw new ArgumentOutOfRangeException("addressFamilyDependentPart", addressFamilyDependentPart, "Cannot be longer than " + AddressFamilyDependentPartMaxLength);
AddressFamily = addressFamily;
PrefixLength = prefixLength;
Negation = negation;
AddressFamilyDependentPart = addressFamilyDependentPart;
}
public AddressFamily AddressFamily { get; private set; }
/// <summary>
/// Prefix length.
/// Upper and lower bounds and interpretation of this value are address family specific.
///
/// For IPv4, specifies the number of bits of the IPv4 address starting at the most significant bit.
/// Legal values range from 0 to 32.
///
/// For IPv6, specifies the number of bits of the IPv6 address starting at the most significant bit.
/// Legal values range from 0 to 128.
/// </summary>
public byte PrefixLength { get; private set; }
/// <summary>
/// Negation flag, indicates the presence of the "!" character in the textual format.
/// </summary>
public bool Negation { get; private set; }
/// <summary>
/// For IPv4, the encoding follows the encoding specified for the A RR by RFC 1035.
/// Trailing zero octets do not bear any information (e.g., there is no semantic difference between 10.0.0.0/16 and 10/16) in an address prefix,
/// so the shortest possible AddressFamilyDependentPart can be used to encode it.
/// However, for DNSSEC (RFC 2535) a single wire encoding must be used by all.
/// Therefore the sender must not include trailing zero octets in the AddressFamilyDependentPart regardless of the value of PrefixLength.
/// This includes cases in which AddressFamilyDependentPart length times 8 results in a value less than PrefixLength.
/// The AddressFamilyDependentPart is padded with zero bits to match a full octet boundary.
/// An IPv4 AddressFamilyDependentPart has a variable length of 0 to 4 octets.
///
/// For IPv6, the 128 bit IPv6 address is encoded in network byte order (high-order byte first).
/// The sender must not include trailing zero octets in the AddressFamilyDependentPart regardless of the value of PrefixLength.
/// This includes cases in which AddressFamilyDependentPart length times 8 results in a value less than PrefixLength.
/// The AddressFamilyDependentPart is padded with zero bits to match a full octet boundary.
/// An IPv6 AddressFamilyDependentPart has a variable length of 0 to 16 octets.
/// </summary>
public DataSegment AddressFamilyDependentPart { get; private set; }
public int Length
{
get { return MinimumLength + AddressFamilyDependentPart.Length; }
}
public bool Equals(DnsAddressPrefix other)
{
return other != null &&
AddressFamily.Equals(other.AddressFamily) &&
PrefixLength.Equals(other.PrefixLength) &&
Negation.Equals(other.Negation) &&
AddressFamilyDependentPart.Equals(other.AddressFamilyDependentPart);
}
public override bool Equals(object obj)
{
return Equals(obj as DnsAddressPrefix);
}
public static DnsAddressPrefix Read(DataSegment data)
{
if (data.Length < MinimumLength)
return null;
AddressFamily addressFamily = (AddressFamily)data.ReadUShort(Offset.AddressFamily, Endianity.Big);
byte prefixLength = data[Offset.PrefixLength];
bool negation = data.ReadBool(Offset.Negation, Mask.Negation);
byte addressFamilyDependentPartLength = (byte)(data[Offset.AddressFamilyDependentPartLength] & Mask.AddressFamilyDependentPartLength);
if (data.Length < MinimumLength + addressFamilyDependentPartLength)
return null;
DataSegment addressFamilyDependentPart = data.SubSegment(Offset.AddressFamilyDependentPart, addressFamilyDependentPartLength);
return new DnsAddressPrefix(addressFamily, prefixLength, negation, addressFamilyDependentPart);
}
public void Write(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.AddressFamily, (ushort)AddressFamily, Endianity.Big);
buffer.Write(offset + Offset.PrefixLength, PrefixLength);
buffer.Write(offset + Offset.Negation, (byte)((Negation ? Mask.Negation : 0) | AddressFamilyDependentPart.Length));
AddressFamilyDependentPart.Write(buffer, offset + Offset.AddressFamilyDependentPart);
offset += MinimumLength + AddressFamilyDependentPart.Length;
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFCs 2535, 2536, 2537, 2539, 3110, 3755, 4034, 5155, 5702, 5933.
/// The key algorithm.
/// </summary>
public enum DnsAlgorithm : byte
{
/// <summary>
/// RFC 4034.
/// Field is not used or indicates that the algorithm is unknown to a secure DNS,
/// which may simply be the result of the algorithm not having been standardized for DNSSEC.
/// </summary>
None = 0,
/// <summary>
/// RFCs 2537, 4034.
/// RSA/MD5.
/// Deprecated.
/// </summary>
RsaMd5 = 1,
/// <summary>
/// RFC 2539.
/// Diffie-Hellman.
/// Implementation is optional, key only.
/// </summary>
DiffieHellman = 2,
/// <summary>
/// RFCs 2536, 3755.
/// DSA - Digital Signature Algorithm.
/// Implementation is mandatory.
/// </summary>
Dsa = 3,
/// <summary>
/// Reserved for elliptic curve crypto.
/// </summary>
Ecc = 4,
/// <summary>
/// RFCs 3110, 3755.
/// RSA/SHA-1.
/// </summary>
RsaSha1 = 5,
/// <summary>
/// RFC 5155.
/// DSA-NSEC3-SHA1.
/// </summary>
DsaNsec3Sha1 = 6,
/// <summary>
/// RFC 5155.
/// RSASHA1-NSEC3-SHA1.
/// </summary>
RsaSha1Nsec3Sha1 = 7,
/// <summary>
/// RFC 5702.
/// RSA/SHA-256.
/// </summary>
RsaSha256 = 8,
/// <summary>
/// RFC 5702.
/// RSA/SHA-512.
/// </summary>
RsaSha512 = 10,
/// <summary>
/// RFC 5933.
/// GOST R 34.10-2001.
/// </summary>
EccGost = 12,
/// <summary>
/// RFC 4034.
/// Reserved for Indirect Keys.
/// </summary>
Indirect = 252,
/// <summary>
/// RFCs 2535, 3755.
/// Private algorithms - domain name.
/// </summary>
PrivateDns = 253,
/// <summary>
/// RFCs 2535, 3755.
/// Private algorithms - OID.
/// </summary>
PrivateOid = 254,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsAtmAddressFormat : byte
{
/// <summary>
/// ATM End System Address (AESA) format.
/// </summary>
AtmEndSystemAddress = 0,
/// <summary>
/// E.164 format.
/// </summary>
E164 = 1,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsCertificateType : ushort
{
/// <summary>
/// RFC 4398.
/// Indicates an X.509 certificate conforming to the profile defined by the IETF PKIX working group.
/// The certificate section will start with a one-octet unsigned OID length and then an X.500 OID indicating the nature of the remainder of the certificate section.
/// Note: X.509 certificates do not include their X.500 directory-type-designating OID as a prefix.
/// </summary>
Pkix = 1,
/// <summary>
/// RFC 4398.
/// SPKI certificate.
/// </summary>
Spki = 2,
/// <summary>
/// RFC 4398.
/// Indicates an OpenPGP packet.
/// This is used to transfer public key material and revocation signatures.
/// The data is binary and must not be encoded into an ASCII armor.
/// An implementation should process transferable public keys, but it may handle additional OpenPGP packets.
/// </summary>
Pgp = 3,
/// <summary>
/// RFC 4398.
/// The URL of an X.509 data object.
/// Must be used when the content is too large to fit in the CERT RR and may be used at the implementer's discretion.
/// Should not be used where the DNS message is 512 octets or smaller and could thus be expected to fit a UDP packet.
/// </summary>
IPkix = 4,
/// <summary>
/// RFC 4398.
/// The URL of an SPKI certificate.
/// Must be used when the content is too large to fit in the CERT RR and may be used at the implementer's discretion.
/// Should not be used where the DNS message is 512 octets or smaller and could thus be expected to fit a UDP packet.
/// </summary>
ISpki = 5,
/// <summary>
/// RFC 4398.
/// Contains both an OpenPGP fingerprint for the key in question, as well as a URL.
/// The certificate portion of the IPgp CERT RR is defined as a one-octet fingerprint length, followed by the OpenPGP fingerprint, followed by the URL.
/// The OpenPGP fingerprint is calculated as defined in RFC 2440.
/// A zero-length fingerprint or a zero-length URL are legal, and indicate URL-only IPGP data or fingerprint-only IPGP data, respectively.
/// A zero-length fingerprint and a zero-length URL are meaningless and invalid.
/// Must be used when the content is too large to fit in the CERT RR and may be used at the implementer's discretion.
/// Should not be used where the DNS message is 512 octets or smaller and could thus be expected to fit a UDP packet.
/// </summary>
Ipgp = 6,
/// <summary>
/// RFC 4398.
/// Attribute Certificate.
/// </summary>
AcPkix = 7,
/// <summary>
/// RFC 4398.
/// The URL of an Attribute Certificate.
/// Must be used when the content is too large to fit in the CERT RR and may be used at the implementer's discretion.
/// Should not be used where the DNS message is 512 octets or smaller and could thus be expected to fit a UDP packet.
/// </summary>
IAcPkix = 8,
/// <summary>
/// RFC 4398.
/// Indicates a certificate format defined by an absolute URI.
/// The certificate portion of the CERT RR must begin with a null-terminated URI, and the data after the null is the private format certificate itself.
/// The URI should be such that a retrieval from it will lead to documentation on the format of the certificate.
/// Recognition of private certificate types need not be based on URI equality but can use various forms of pattern matching so that, for example, subtype or version information can also be encoded into the URI.
/// </summary>
Uri = 253,
/// <summary>
/// RFC 4398.
/// Indicates a private format certificate specified by an ISO OID prefix.
/// The certificate section will start with a one-octet unsigned OID length and then a BER-encoded OID indicating the nature of the remainder of the certificate section.
/// This can be an X.509 certificate format or some other format.
/// X.509 certificates that conform to the IETF PKIX profile should be indicated by the PKIX type, not the OID private type.
/// Recognition of private certificate types need not be based on OID equality but can use various forms of pattern matching such as OID prefix.
/// </summary>
Oid = 254,
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
[Flags]
public enum DnsCertificationAuthorityAuthorizationFlags : byte
{
/// <summary>
/// If set, the critical flag is asserted and the property must be understood if the CAA record is to be correctly processed by a certificate issuer.
/// A Certification Authority must not issue certificates for any Domain that contains a CAA critical property for an unknown or unsupported property type that has the issuer flag set.
/// </summary>
Critical = 0x80,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsDigestType : byte
{
/// <summary>
/// RFC 3658.
/// SHA-1.
/// </summary>
Sha1 = 1,
/// <summary>
/// RFC 4509.
/// SHA-256.
/// </summary>
Sha256 = 2,
/// <summary>
/// RFC 5933.
/// GOST R 34.11-94.
/// </summary>
GostR341194 = 3,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4255.
/// Describes the algorithm of the public key.
/// </summary>
public enum DnsFingerprintPublicKeyAlgorithm : byte
{
Rsa = 1,
Dss = 2,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4255.
/// </summary>
public enum DnsFingerprintType : byte
{
/// <summary>
/// RFC 4255.
/// </summary>
Sha1 = 1,
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.IpV6;
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsGateway : IEquatable<DnsGateway>
{
public static DnsGatewayNone None { get { return _none; } }
public abstract DnsGatewayType Type { get; }
public abstract int Length { get; }
public abstract bool Equals(DnsGateway other);
public override bool Equals(object obj)
{
return Equals(obj as DnsGateway);
}
internal abstract void Write(byte[] buffer, int offset);
internal static DnsGateway CreateInstance(DnsGatewayType gatewayType, DnsDatagram dns, int offsetInDns, int length)
{
switch (gatewayType)
{
case DnsGatewayType.None:
return None;
case DnsGatewayType.IpV4:
if (length < IpV4Address.SizeOf)
return null;
return new DnsGatewayIpV4(dns.ReadIpV4Address(offsetInDns, Endianity.Big));
case DnsGatewayType.IpV6:
if (length < IpV6Address.SizeOf)
return null;
return new DnsGatewayIpV6(dns.ReadIpV6Address(offsetInDns, Endianity.Big));
case DnsGatewayType.DomainName:
DnsDomainName domainName;
int numBytesRead;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out numBytesRead))
return null;
return new DnsGatewayDomainName(domainName);
default:
return null;
}
}
private static DnsGatewayNone _none = new DnsGatewayNone();
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
public class DnsGatewayDomainName : DnsGateway, IEquatable<DnsGatewayDomainName>
{
public DnsGatewayDomainName(DnsDomainName value)
{
Value = value;
}
public DnsDomainName Value { get; private set; }
public override DnsGatewayType Type
{
get { return DnsGatewayType.DomainName; }
}
public override int Length
{
get { return Value.NonCompressedLength; }
}
public bool Equals(DnsGatewayDomainName other)
{
return other != null &&
Value.Equals(other.Value);
}
public override bool Equals(DnsGateway other)
{
return Equals(other as DnsGatewayDomainName);
}
internal override void Write(byte[] buffer, int offset)
{
Value.WriteUncompressed(buffer, offset);
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Dns
{
public class DnsGatewayIpV4 : DnsGateway, IEquatable<DnsGatewayIpV4>
{
public DnsGatewayIpV4(IpV4Address value)
{
Value = value;
}
public IpV4Address Value { get; private set; }
public override DnsGatewayType Type
{
get { return DnsGatewayType.IpV4; }
}
public override int Length
{
get { return IpV4Address.SizeOf; }
}
public bool Equals(DnsGatewayIpV4 other)
{
return other != null &&
Value.Equals(other.Value);
}
public override bool Equals(DnsGateway other)
{
return Equals(other as DnsGatewayIpV4);
}
internal override void Write(byte[] buffer, int offset)
{
buffer.Write(offset, Value, Endianity.Big);
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV6;
namespace PcapDotNet.Packets.Dns
{
public class DnsGatewayIpV6 : DnsGateway, IEquatable<DnsGatewayIpV6>
{
public DnsGatewayIpV6(IpV6Address value)
{
Value = value;
}
public IpV6Address Value { get; private set; }
public override DnsGatewayType Type
{
get { return DnsGatewayType.IpV6; }
}
public override int Length
{
get { return IpV6Address.SizeOf; }
}
public bool Equals(DnsGatewayIpV6 other)
{
return other != null &&
Value.Equals(other.Value);
}
public override bool Equals(DnsGateway other)
{
return Equals(other as DnsGatewayIpV6);
}
internal override void Write(byte[] buffer, int offset)
{
buffer.Write(offset, Value, Endianity.Big);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
public class DnsGatewayNone : DnsGateway, IEquatable<DnsGatewayNone>
{
public override DnsGatewayType Type
{
get { return DnsGatewayType.None; }
}
public override int Length
{
get { return 0; }
}
public bool Equals(DnsGatewayNone other)
{
return other != null;
}
public override bool Equals(DnsGateway other)
{
return Equals(other as DnsGatewayNone);
}
internal DnsGatewayNone()
{
}
internal override void Write(byte[] buffer, int offset)
{
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// Indicates the format of the information that is stored in the gateway field.
/// </summary>
public enum DnsGatewayType : byte
{
/// <summary>
/// No gateway is present.
/// </summary>
None = 0,
/// <summary>
/// A 4-byte IPv4 address is present.
/// </summary>
IpV4 = 1,
/// <summary>
/// A 16-byte IPv6 address is present.
/// </summary>
IpV6 = 2,
/// <summary>
/// A wire-encoded domain name is present.
/// The wire-encoded format is self-describing, so the length is implicit.
/// The domain name must not be compressed.
/// </summary>
DomainName = 3,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2535.
/// </summary>
public enum DnsKeyNameType : byte
{
/// <summary>
/// Indicates that this is a key associated with a "user" or "account" at an end entity, usually a host.
/// The coding of the owner name is that used for the responsible individual mailbox in the SOA and RP RRs:
/// The owner name is the user name as the name of a node under the entity name.
/// For example, "j_random_user" on host.subdomain.example could have a public key associated through a KEY RR with name j_random_user.host.subdomain.example.
/// It could be used in a security protocol where authentication of a user was desired.
/// This key might be useful in IP or other security for a user level service such a telnet, ftp, rlogin, etc.
/// </summary>
UserOrAccountAtEndEntity = 0,
/// <summary>
/// Indicates that this is a zone key for the zone whose name is the KEY RR owner name.
/// This is the public key used for the primary DNS security feature of data origin authentication.
/// Zone KEY RRs occur only at delegation points.
/// </summary>
ZoneKey = 1,
/// <summary>
/// Indicates that this is a key associated with the non-zone "entity" whose name is the RR owner name.
/// This will commonly be a host but could, in some parts of the DNS tree, be some other type of entity such as a telephone number [RFC 1530] or numeric IP address.
/// This is the public key used in connection with DNS request and transaction authentication services.
/// It could also be used in an IP-security protocol where authentication at the host, rather than user, level was desired, such as routing, NTP, etc.
/// </summary>
NonZoneEntity = 2,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2535.
/// </summary>
public enum DnsKeyProtocol : byte
{
/// <summary>
/// Connection with TLS.
/// </summary>
Tls = 1,
/// <summary>
/// Connection with email.
/// </summary>
Email = 2,
/// <summary>
/// DNS security.
/// The protocol field should be set to this value for zone keys and other keys used in DNS security.
/// Implementations that can determine that a key is a DNS security key by the fact that flags label it a zone key or the signatory flag field is non-zero are not required to check the protocol field.
/// </summary>
DnsSec = 3,
/// <summary>
/// Oakley/IPSEC [RFC 2401] protocol.
/// Indicates that this key is valid for use in conjunction with that security standard.
/// This key could be used in connection with secured communication on behalf of an end entity or user whose name is the owner name of the KEY RR if the entity or user flag bits are set.
/// The presence of a KEY resource with this protocol value is an assertion that the host speaks Oakley/IPSEC.
/// </summary>
IpSec = 4,
/// <summary>
/// The key can be used in connection with any protocol for which KEY RR protocol octet values have been defined.
/// The use of this value is discouraged and the use of different keys for different protocols is encouraged.
/// </summary>
All = 255,
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2137.
/// </summary>
[Flags]
public enum DnsKeySignatory : byte
{
/// <summary>
/// The general update signatory field bit has no special meaning.
/// If the other three bits are all zero, it must be one so that the field is non-zero to designate that the key is an update key.
/// The meaning of all values of the signatory field with the general bit and one or more other signatory field bits on is reserved.
/// </summary>
General = 1,
/// <summary>
/// If non-zero, this key is authorized to add and update RRs for only a single owner name.
/// If there already exist RRs with one or more names signed by this key, they may be updated but no new name created until the number of existing names is reduced to zero.
/// This bit is meaningful only for mode A dynamic zones and is ignored in mode B dynamic zones.
/// This bit is meaningful only if the owner name is a wildcard.
/// (Any dynamic update KEY with a non-wildcard name is, in effect, a unique name update key.)
/// </summary>
Unique = 2,
/// <summary>
/// If non-zero, this key is authorized to add and delete RRs even if there are other RRs with the same owner name and class that are authenticated by a SIG signed with a different dynamic update KEY.
/// If zero, the key can only authorize updates where any existing RRs of the same owner and class are authenticated by a SIG using the same key.
/// This bit is meaningful only for type A dynamic zones and is ignored in type B dynamic zones.
///
/// Keeping this bit zero on multiple KEY RRs with the same or nested wild card owner names permits multiple entities to exist that can create and delete names but can not effect RRs with different owner names from any they created.
/// In effect, this creates two levels of dynamic update key, strong and weak, where weak keys are limited in interfering with each other but a strong key can interfere with any weak keys or other strong keys.
/// </summary>
Strong = 4,
/// <summary>
/// If nonzero, this key is authorized to attach, detach, and move zones by creating and deleting NS, glue A, and zone KEY RR(s).
/// If zero, the key can not authorize any update that would effect such RRs.
/// This bit is meaningful for both type A and type B dynamic secure zones.
/// NOTE: do not confuse the "zone" signatory field bit with the "zone" key type bit.
/// </summary>
Zone = 8,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsLongLivedQueryErrorCode : ushort
{
/// <summary>
/// The LLQ Setup Request was successful.
/// </summary>
NoError = 0,
/// <summary>
/// The server cannot grant the LLQ request because it is overloaded,
/// or the request exceeds the server's rate limit (see Section 8 "Security Considerations").
/// Upon returning this error, the server MUST include in the LEASE-LIFE field a time interval, in seconds,
/// after which the client may re-try the LLQ Setup.
/// </summary>
ServerFull = 1,
/// <summary>
/// The data for this name and type is not expected to change frequently, and the server therefore does not support the requested LLQ.
/// The client must not poll for this name and type, nor should it re-try the LLQ Setup, and should instead honor the normal resource record TTLs returned.
/// To reduce server load, an administrator MAY return this error for all records with types other than PTR and TXT as a matter of course.
/// </summary>
Static = 2,
/// <summary>
/// The LLQ was improperly formatted.
/// Note that if the rest of the DNS message is properly formatted, the DNS header error code must not include a format error code,
/// as this would cause confusion between a server that does not understand the LLQ format, and a client that sends malformed LLQs.
/// </summary>
FormatError = 3,
/// <summary>
/// The client attempts to refresh an expired or non-existent LLQ (as determined by the LLQ-ID in the request).
/// </summary>
NoSuchLlq = 4,
/// <summary>
/// The protocol version specified in the client's request is not supported by the server.
/// </summary>
BadVersion = 5,
/// <summary>
/// The LLQ was not granted for an unknown reason.
/// </summary>
UnknownError = 6,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// http://files.dns-sd.org/draft-sekar-dns-llq.txt.
/// </summary>
public enum DnsLongLivedQueryOpcode : ushort
{
Setup = 1,
Refresh = 2,
Event = 3,
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsOption : IEquatable<DnsOption>
{
public const int MinimumLength = sizeof(ushort) + sizeof(ushort);
public DnsOptionCode Code { get; private set; }
public int Length { get { return MinimumLength + DataLength; } }
public abstract int DataLength { get; }
public bool Equals(DnsOption other)
{
return other != null &&
Code.Equals(other.Code) &&
GetType().Equals(other.GetType()) &&
EqualsData(other);
}
public override sealed bool Equals(object obj)
{
return Equals(obj as DnsOption);
}
internal DnsOption(DnsOptionCode code)
{
Code = code;
}
internal abstract bool EqualsData(DnsOption other);
internal void Write(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, (ushort)Code, Endianity.Big);
buffer.Write(ref offset, (ushort)DataLength, Endianity.Big);
WriteData(buffer, ref offset);
}
internal abstract void WriteData(byte[] buffer, ref int offset);
internal static DnsOption CreateInstance(DnsOptionCode code, DataSegment data)
{
switch (code)
{
case DnsOptionCode.LongLivedQuery:
if (data.Length < DnsOptionLongLivedQuery.MinimumDataLength)
return null;
return DnsOptionLongLivedQuery.Read(data);
case DnsOptionCode.UpdateLease:
if (data.Length < DnsOptionUpdateLease.MinimumDataLength)
return null;
return DnsOptionUpdateLease.Read(data);
case DnsOptionCode.NameServerIdentifier:
default:
return new DnsOptionAnything(code, data);
}
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public enum DnsOptionCode : ushort
{
/// <summary>
/// http://files.dns-sd.org/draft-sekar-dns-llq.txt.
/// LLQ.
/// </summary>
LongLivedQuery = 1,
/// <summary>
/// http://files.dns-sd.org/draft-sekar-dns-ul.txt.
/// UL.
/// </summary>
UpdateLease = 2,
/// <summary>
/// RFC 5001.
/// NSID.
/// </summary>
NameServerIdentifier = 3,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// http://files.dns-sd.org/draft-sekar-dns-llq.txt.
/// <pre>
/// +-----+------------+
/// | bit | 0-15 |
/// +-----+------------+
/// | 0 | VERSION |
/// +-----+------------+
/// | 16 | LLQ-OPCODE |
/// +-----+------------+
/// | 32 | ERROR-CODE |
/// +-----+------------+
/// | 48 | LLQ-ID |
/// | | |
/// | | |
/// | | |
/// +-----+------------+
/// | 112 | LEASE-LIFE |
/// | | |
/// +-----+------------+
/// </pre>
/// </summary>
public class DnsOptionLongLivedQuery : DnsOption
{
private static class Offset
{
public const int Version = 0;
public const int Opcode = Version + sizeof(ushort);
public const int ErrorCode = Opcode + sizeof(ushort);
public const int Id = ErrorCode + sizeof(ushort);
public const int LeaseLife = Id + sizeof(ulong);
}
public const int MinimumDataLength = Offset.LeaseLife + sizeof(uint);
public DnsOptionLongLivedQuery(ushort version, DnsLongLivedQueryOpcode opcode, DnsLongLivedQueryErrorCode errorCode, ulong id, uint leaseLife)
: base(DnsOptionCode.LongLivedQuery)
{
Version = version;
Opcode = opcode;
ErrorCode = errorCode;
Id = id;
LeaseLife = leaseLife;
}
public ushort Version { get; private set; }
public DnsLongLivedQueryOpcode Opcode { get; private set; }
public DnsLongLivedQueryErrorCode ErrorCode { get; private set; }
public ulong Id { get; private set; }
public uint LeaseLife { get; private set; }
public override int DataLength
{
get { return MinimumDataLength; }
}
internal override bool EqualsData(DnsOption other)
{
DnsOptionLongLivedQuery castedOther = (DnsOptionLongLivedQuery)other;
return Version.Equals(castedOther.Version) &&
Opcode.Equals(castedOther.Opcode) &&
ErrorCode.Equals(castedOther.ErrorCode) &&
Id.Equals(castedOther.Id) &&
LeaseLife.Equals(castedOther.LeaseLife);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(offset + Offset.Version, Version, Endianity.Big);
buffer.Write(offset + Offset.Opcode, (ushort)Opcode, Endianity.Big);
buffer.Write(offset + Offset.ErrorCode, (ushort)ErrorCode, Endianity.Big);
buffer.Write(offset + Offset.Id, Id, Endianity.Big);
buffer.Write(offset + Offset.LeaseLife, LeaseLife, Endianity.Big);
offset += DataLength;
}
internal static DnsOptionLongLivedQuery Read(DataSegment data)
{
if (data.Length < MinimumDataLength)
return null;
ushort version = data.ReadUShort(Offset.Version, Endianity.Big);
DnsLongLivedQueryOpcode opcode = (DnsLongLivedQueryOpcode)data.ReadUShort(Offset.Opcode, Endianity.Big);
DnsLongLivedQueryErrorCode errorCode = (DnsLongLivedQueryErrorCode)data.ReadUShort(Offset.ErrorCode, Endianity.Big);
ulong id = data.ReadULong(Offset.Id, Endianity.Big);
uint leaseLife = data.ReadUInt(Offset.LeaseLife, Endianity.Big);
return new DnsOptionLongLivedQuery(version, opcode, errorCode, id, leaseLife);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// http://files.dns-sd.org/draft-sekar-dns-ul.txt.
/// <pre>
/// +-----+-------+
/// | bit | 0-31 |
/// +-----+-------+
/// | 0 | LEASE |
/// +-----+-------+
/// </pre>
/// </summary>
public class DnsOptionUpdateLease : DnsOption
{
public const int MinimumDataLength = sizeof(int);
public DnsOptionUpdateLease(int lease)
: base(DnsOptionCode.UpdateLease)
{
Lease = lease;
}
/// <summary>
/// Indicating the lease life, in seconds, desired by the client.
/// In Update Responses, this field contains the actual lease granted by the server.
/// Note that the lease granted by the server may be less than, greater than, or equal to the value requested by the client.
/// To reduce network and server load, a minimum lease of 30 minutes (1800 seconds) is recommended.
/// Note that leases are expected to be sufficiently long as to make timer discrepancies (due to transmission latency, etc.)
/// between a client and server negligible.
/// Clients that expect the updated records to be relatively static may request appropriately longer leases.
/// Servers may grant relatively longer or shorter leases to reduce network traffic due to refreshes, or reduce stale data, respectively.
/// </summary>
public int Lease { get; private set; }
public override int DataLength
{
get { return MinimumDataLength; }
}
internal override bool EqualsData(DnsOption other)
{
return Lease.Equals(((DnsOptionUpdateLease)other).Lease);
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Lease, Endianity.Big);
}
internal static DnsOptionUpdateLease Read(DataSegment data)
{
if (data.Length < MinimumDataLength)
return null;
int lease = data.ReadInt(0, Endianity.Big);
return new DnsOptionUpdateLease(lease);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
public sealed class DnsOptions : IEquatable<DnsOptions>
{
public static DnsOptions None { get { return _none; } }
public DnsOptions(IList<DnsOption> options)
{
Options = options.AsReadOnly();
NumBytes = options.Sum(option => option.Length);
}
public DnsOptions(params DnsOption[] options)
: this((IList<DnsOption>)options)
{
}
public ReadOnlyCollection<DnsOption> Options { get; private set; }
public int NumBytes { get; private set; }
public bool Equals(DnsOptions other)
{
return other != null &&
Options.SequenceEqual(other.Options);
}
public override bool Equals(object obj)
{
return Equals(obj as DnsOptions);
}
private static readonly DnsOptions _none = new DnsOptions();
internal void Write(byte[] buffer, int offset)
{
foreach (DnsOption option in Options)
option.Write(buffer, ref offset);
}
public static DnsOptions Read(DataSegment data)
{
List<DnsOption> options = new List<DnsOption>();
while (data.Length != 0)
{
if (data.Length < DnsOption.MinimumLength)
return null;
DnsOptionCode code = (DnsOptionCode)data.ReadUShort(0, Endianity.Big);
ushort optionDataLength = data.ReadUShort(sizeof(ushort), Endianity.Big);
int optionLength = DnsOption.MinimumLength + optionDataLength;
if (data.Length < optionLength)
return null;
DnsOption option = DnsOption.CreateInstance(code, data.SubSegment(DnsOption.MinimumLength, optionDataLength));
if (option == null)
return null;
options.Add(option);
data = data.SubSegment(optionLength, data.Length - optionLength);
}
return new DnsOptions(options);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// Identifies the public key's cryptographic algorithm and determines the format of the public key field.
/// </summary>
public enum DnsPublicKeyAlgorithm : byte
{
/// <summary>
/// Indicates that no key is present.
/// </summary>
None = 0,
/// <summary>
/// A DSA key is present, in the format defined in RFC 2536.
/// </summary>
Dsa = 1,
/// <summary>
/// A RSA key is present, in the format defined in RFC 3110 with the following changes:
/// The earlier definition of RSA/MD5 in RFC 2065 limited the exponent and modulus to 2552 bits in length.
/// RFC 3110 extended that limit to 4096 bits for RSA/SHA1 keys
/// The IPSECKEY RR imposes no length limit on RSA public keys, other than the 65535 octet limit imposed by the two-octet length encoding.
/// This length extension is applicable only to IPSECKEY; it is not applicable to KEY RRs.
/// </summary>
Rsa = 2,
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsResourceData2DomainNames : DnsResourceDataDomainNames
{
private const int NumDomains = 2;
internal DnsResourceData2DomainNames(DnsDomainName first, DnsDomainName second)
: base(first, second)
{
}
internal DnsDomainName First { get { return DomainNames[0]; } }
internal DnsDomainName Second { get { return DomainNames[1]; } }
internal static bool TryRead(out DnsDomainName first, out DnsDomainName second,
DnsDatagram dns, int offsetInDns, int length)
{
List<DnsDomainName> domainNames = ReadDomainNames(dns, offsetInDns, length, NumDomains);
if (domainNames == null || domainNames.Count != NumDomains)
{
first = null;
second = null;
return false;
}
first = domainNames[0];
second = domainNames[1];
return true;
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV6;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2874.
/// <pre>
/// +-------------+----------------+-----------------+
/// | Prefix len. | Address suffix | Prefix name |
/// | (1 octet) | (0..16 octets) | (0..255 octets) |
/// +-------------+----------------+-----------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.A6)]
public sealed class DnsResourceDataA6 : DnsResourceDataNoCompression, IEquatable<DnsResourceDataA6>
{
public const byte MaxPrefixLength = 8 * IpV6Address.SizeOf;
private static class Offset
{
public const int PrefixLength = 0;
public const int AddressSuffix = PrefixLength + sizeof(byte);
}
public const int ConstantPartLength = Offset.AddressSuffix;
public DnsResourceDataA6(byte prefixLength, IpV6Address addressSuffix, DnsDomainName prefixName)
{
PrefixLength = prefixLength;
AddressSuffix = addressSuffix;
PrefixName = prefixName;
}
/// <summary>
/// Encoded as an eight-bit unsigned integer with value between 0 and 128 inclusive.
/// </summary>
public byte PrefixLength { get; private set; }
/// <summary>
/// An IPv6 address suffix, encoded in network order (high-order octet first).
/// There must be exactly enough octets in this field to contain a number of bits equal to 128 minus prefix length, with 0 to 7 leading pad bits to make this field an integral number of octets.
/// Pad bits, if present, must be set to zero when loading a zone file and ignored (other than for SIG verification) on reception.
/// </summary>
public IpV6Address AddressSuffix { get; private set; }
/// <summary>
/// The number of bytes the address suffix takes.
/// </summary>
public int AddressSuffixLength { get { return CalculateAddressSuffixLength(PrefixLength); } }
/// <summary>
/// The name of the prefix, encoded as a domain name.
/// This name must not be compressed.
/// </summary>
public DnsDomainName PrefixName { get; private set; }
public bool Equals(DnsResourceDataA6 other)
{
return other != null &&
PrefixLength.Equals(other.PrefixLength) &&
AddressSuffix.Equals(other.AddressSuffix) &&
PrefixName.Equals(other.PrefixName);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataA6);
}
internal DnsResourceDataA6()
: this(0, IpV6Address.Zero, DnsDomainName.Root)
{
}
internal override int GetLength()
{
return ConstantPartLength + AddressSuffixLength + PrefixName.NonCompressedLength;
}
internal override int WriteData(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.PrefixLength, PrefixLength);
buffer.WriteUnsigned(offset + Offset.AddressSuffix, AddressSuffix.ToValue(), AddressSuffixLength, Endianity.Big);
PrefixName.WriteUncompressed(buffer, offset + ConstantPartLength + AddressSuffixLength);
return GetLength();
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
if (length < ConstantPartLength)
return null;
byte prefixLength = dns[offsetInDns + Offset.PrefixLength];
if (prefixLength > MaxPrefixLength)
return null;
offsetInDns += ConstantPartLength;
length -= ConstantPartLength;
int addressSuffixLength = CalculateAddressSuffixLength(prefixLength);
if (length < addressSuffixLength)
return null;
IpV6Address addressSuffix = new IpV6Address((UInt128)dns.ReadUnsignedBigInteger(offsetInDns, addressSuffixLength, Endianity.Big));
offsetInDns += addressSuffixLength;
length -= addressSuffixLength;
DnsDomainName prefixName;
int prefixNameLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out prefixName, out prefixNameLength))
return null;
if (prefixNameLength != length)
return null;
return new DnsResourceDataA6(prefixLength, addressSuffix, prefixName);
}
private static int CalculateAddressSuffixLength(byte prefixLength)
{
return (MaxPrefixLength - prefixLength + 7) / 8;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 3123.
/// <pre>
/// 0 Or more of:
/// +-----+--------+---+-----------+
/// | bit | 0-7 | 8 | 9-15 |
/// +-----+--------+---+-----------+
/// | 0 | ADDRESSFAMILY |
/// +-----+--------+---+-----------+
/// | 16 | PREFIX | N | AFDLENGTH |
/// +-----+--------+---+-----------+
/// | 32 | AFDPART |
/// | ... | |
/// +-----+------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Apl)]
public sealed class DnsResourceDataAddressPrefixList: DnsResourceDataSimple, IEquatable<DnsResourceDataAddressPrefixList>
{
public DnsResourceDataAddressPrefixList(IList<DnsAddressPrefix> items)
{
Items = items.AsReadOnly();
}
public DnsResourceDataAddressPrefixList(params DnsAddressPrefix[] items)
: this((IList<DnsAddressPrefix>)items)
{
Length = items.Sum(item => item.Length);
}
public ReadOnlyCollection<DnsAddressPrefix> Items { get; private set; }
public int Length { get; private set; }
public bool Equals(DnsResourceDataAddressPrefixList other)
{
return other != null &&
Items.SequenceEqual(other.Items);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataAddressPrefixList);
}
internal DnsResourceDataAddressPrefixList()
: this(new DnsAddressPrefix[0])
{
}
internal override int GetLength()
{
return Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
foreach (DnsAddressPrefix item in Items)
item.Write(buffer, ref offset);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
List<DnsAddressPrefix> items = new List<DnsAddressPrefix>();
while (data.Length != 0)
{
DnsAddressPrefix item = DnsAddressPrefix.Read(data);
if (item == null)
return null;
items.Add(item);
data = data.SubSegment(item.Length, data.Length - item.Length);
}
return new DnsResourceDataAddressPrefixList(items);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+----------+
/// | bit | 0-15 |
/// +-----+----------+
/// | 0 | subtype |
/// +-----+----------+
/// | 16 | hostname |
/// | ... | |
/// +-----+----------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.AfsDb)]
public sealed class DnsResourceDataAfsDb : DnsResourceDataUShortDomainName
{
public DnsResourceDataAfsDb(ushort subType, DnsDomainName hostname)
: base(subType, hostname)
{
}
public ushort SubType { get { return Value; } }
public DnsDomainName Hostname { get { return DomainName; } }
internal DnsResourceDataAfsDb()
: this(0, DnsDomainName.Root)
{
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
ushort subType;
DnsDomainName hostName;
if (!TryRead(out subType, out hostName, dns, offsetInDns, length))
return null;
return new DnsResourceDataAfsDb(subType, hostName);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+---------+
/// | bit | 0-7 |
/// +-----+---------+
/// | 0 | FORMAT |
/// +-----+---------+
/// | 8 | ADDRESS |
/// | ... | |
/// +-----+---------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.AtmA)]
public sealed class DnsResourceDataAtmAddress : DnsResourceDataSimple, IEquatable<DnsResourceDataAtmAddress>
{
private static class Offset
{
public const int Format = 0;
public const int Address = Format + sizeof(byte);
}
public const int ConstantPartLength = Offset.Address;
public DnsResourceDataAtmAddress(DnsAtmAddressFormat format, DataSegment address)
{
Format = format;
Address = address;
}
/// <summary>
/// The format of Address.
/// </summary>
public DnsAtmAddressFormat Format { get; private set; }
/// <summary>
/// Variable length string of octets containing the ATM address of the node to which this RR pertains.
/// When the format is AESA, the address is coded as described in ISO 8348/AD 2 using the preferred binary encoding of the ISO NSAP format.
/// When the format value is E.164, the Address/Number Digits appear in the order in which they would be entered on a numeric keypad.
/// Digits are coded in IA5 characters with the leftmost bit of each digit set to 0.
/// This ATM address appears in ATM End System Address Octets field (AESA format) or the Address/Number Digits field (E.164 format) of the Called party number information element [ATMUNI3.1].
/// Subaddress information is intentionally not included because E.164 subaddress information is used for routing.
/// </summary>
public DataSegment Address { get; private set; }
public bool Equals(DnsResourceDataAtmAddress other)
{
return other != null &&
Format.Equals(other.Format) &&
Address.Equals(other.Address);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataAtmAddress);
}
internal DnsResourceDataAtmAddress()
: this(DnsAtmAddressFormat.AtmEndSystemAddress, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstantPartLength + Address.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.Format, (byte)Format);
Address.Write(buffer, offset + Offset.Address);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
DnsAtmAddressFormat format = (DnsAtmAddressFormat)data[Offset.Format];
DataSegment address = data.SubSegment(Offset.Address, data.Length - ConstantPartLength);
return new DnsResourceDataAtmAddress(format, address);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4398.
/// <pre>
/// +-----+-----------+------+------------+
/// | bit | 0-7 | 8-15 | 16-31 |
/// +-----+-----------+------+------------+
/// | 0 | type | key tag |
/// +-----+-----------+------+------------+
/// | 32 | algorithm | certificate or CRL|
/// +-----+-----------+ |
/// | | |
/// | ... | |
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Cert)]
public sealed class DnsResourceDataCertificate : DnsResourceDataSimple, IEquatable<DnsResourceDataCertificate>
{
private static class Offset
{
public const int Type = 0;
public const int KeyTag = Type + sizeof(ushort);
public const int Algorithm = KeyTag + sizeof(ushort);
public const int Certificate = Algorithm + sizeof(byte);
}
public const int ConstantPartLength = Offset.Certificate;
public DnsResourceDataCertificate(DnsCertificateType certificateType, ushort keyTag, DnsAlgorithm algorithm, DataSegment certificate)
{
CertificateType = certificateType;
KeyTag = keyTag;
Algorithm = algorithm;
Certificate = certificate;
}
/// <summary>
/// The certificate type.
/// </summary>
public DnsCertificateType CertificateType { get; private set; }
/// <summary>
/// Value computed for the key embedded in the certificate, using the RRSIG Key Tag algorithm.
/// This field is used as an efficiency measure to pick which CERT RRs may be applicable to a particular key.
/// The key tag can be calculated for the key in question, and then only CERT RRs with the same key tag need to be examined.
/// Note that two different keys can have the same key tag.
/// However, the key must be transformed to the format it would have as the public key portion of a DNSKEY RR before the key tag is computed.
/// This is only possible if the key is applicable to an algorithm and complies to limits (such as key size) defined for DNS security.
/// If it is not, the algorithm field must be zero and the tag field is meaningless and should be zero.
/// </summary>
public ushort KeyTag { get; private set; }
/// <summary>
/// Has the same meaning as the algorithm field in DNSKEY and RRSIG RRs,
/// except that a zero algorithm field indicates that the algorithm is unknown to a secure DNS,
/// which may simply be the result of the algorithm not having been standardized for DNSSEC.
/// </summary>
public DnsAlgorithm Algorithm { get; private set; }
/// <summary>
/// The certificate data according to the type.
/// </summary>
public DataSegment Certificate { get; private set; }
public bool Equals(DnsResourceDataCertificate other)
{
return other != null &&
CertificateType.Equals(other.CertificateType) &&
KeyTag.Equals(other.KeyTag) &&
Algorithm.Equals(other.Algorithm) &&
Certificate.Equals(other.Certificate);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataCertificate);
}
internal DnsResourceDataCertificate()
: this(DnsCertificateType.Pkix, 0, DnsAlgorithm.None, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstantPartLength + Certificate.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.Type, (ushort)CertificateType, Endianity.Big);
buffer.Write(offset + Offset.KeyTag, KeyTag, Endianity.Big);
buffer.Write(offset + Offset.Algorithm, (byte)Algorithm);
Certificate.Write(buffer, offset + Offset.Certificate);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
DnsCertificateType type = (DnsCertificateType)data.ReadUShort(Offset.Type, Endianity.Big);
ushort keyTag = data.ReadUShort(Offset.KeyTag, Endianity.Big);
DnsAlgorithm algorithm = (DnsAlgorithm)data[Offset.Algorithm];
DataSegment certificate = data.SubSegment(Offset.Certificate, data.Length - ConstantPartLength);
return new DnsResourceDataCertificate(type, keyTag, algorithm, certificate);
}
}
}
\ No newline at end of file
using System;
using System.Linq;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// Hallam-Baker.
/// <pre>
/// +-----+----------+----------+------------+
/// | bit | 0 | 1-7 | 8-15 |
/// +-----+----------+----------+------------+
/// | 0 | Critical | Reserved | Tag Length |
/// +-----+----------+----------+------------+
/// | 16 | Tag |
/// | ... | |
/// +-----+----------------------------------+
/// | ... | Value |
/// +-----+----------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Caa)]
public sealed class DnsResourceDataCertificationAuthorityAuthorization : DnsResourceDataSimple, IEquatable<DnsResourceDataCertificationAuthorityAuthorization>
{
private static class Offset
{
public const int Flags = 0;
public const int TagLength = Flags + sizeof(byte);
public const int Tag = TagLength + sizeof(byte);
}
private const int ConstantPartLength = Offset.Tag;
public DnsResourceDataCertificationAuthorityAuthorization(DnsCertificationAuthorityAuthorizationFlags flags, DataSegment tag, DataSegment value)
{
if (tag.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("tag", tag.Length, string.Format("Cannot be longer than {0}", byte.MaxValue));
Flags = flags;
Tag = tag;
Value = value;
}
/// <summary>
/// Flags of the record.
/// </summary>
public DnsCertificationAuthorityAuthorizationFlags Flags { get; private set; }
/// <summary>
/// The property identifier, a sequence of ASCII characters.
/// Tag values may contain ASCII characters a through z and the numbers 0 through 9.
/// Tag values must not contain any other characters.
/// Matching of tag values is case insensitive.
/// </summary>
public DataSegment Tag { get; private set; }
/// <summary>
/// Represents the property value.
/// Property values are encoded as binary values and may employ sub-formats.
/// </summary>
public DataSegment Value { get; private set; }
public bool Equals(DnsResourceDataCertificationAuthorityAuthorization other)
{
return other != null &&
Flags.Equals(other.Flags) &&
Tag.Equals(other.Tag) &&
Value.SequenceEqual(other.Value);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataCertificationAuthorityAuthorization);
}
internal DnsResourceDataCertificationAuthorityAuthorization()
: this(0, DataSegment.Empty, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstantPartLength + Tag.Length + Value.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.Flags, (byte)Flags);
buffer.Write(offset + Offset.TagLength, (byte)Tag.Length);
Tag.Write(buffer, offset + Offset.Tag);
Value.Write(buffer, offset + ConstantPartLength + Tag.Length);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
DnsCertificationAuthorityAuthorizationFlags flags = (DnsCertificationAuthorityAuthorizationFlags)data[Offset.Flags];
byte tagLength = data[Offset.TagLength];
int valueOffset = ConstantPartLength + tagLength;
if (data.Length < valueOffset)
return null;
DataSegment tag = data.SubSegment(Offset.Tag, tagLength);
DataSegment value = data.SubSegment(valueOffset, data.Length - valueOffset);
return new DnsResourceDataCertificationAuthorityAuthorization(flags, tag, value);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 3658.
/// <pre>
/// 0 Or more of:
/// +-----+---------+-----------+-------------+
/// | bit | 0-15 | 16-23 | 24-31 |
/// +-----+---------+-----------+-------------+
/// | 0 | key tag | algorithm | Digest type |
/// +-----+---------+-----------+-------------+
/// | 32 | digest |
/// | ... | |
/// +-----+-----------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Ds)]
[DnsTypeRegistration(Type = DnsType.Cds)]
[DnsTypeRegistration(Type = DnsType.Ta)]
[DnsTypeRegistration(Type = DnsType.Dlv)]
public sealed class DnsResourceDataDelegationSigner : DnsResourceDataSimple, IEquatable<DnsResourceDataDelegationSigner>
{
public static class Offset
{
public const int KeyTag = 0;
public const int Algorithm = KeyTag + sizeof(ushort);
public const int DigestType = Algorithm + sizeof(byte);
public const int Digest = DigestType + sizeof(byte);
}
public const int ConstPartLength = Offset.Digest;
public DnsResourceDataDelegationSigner(ushort keyTag, DnsAlgorithm algorithm, DnsDigestType digestType, DataSegment digest)
{
KeyTag = keyTag;
Algorithm = algorithm;
DigestType = digestType;
int maxDigestLength;
switch (DigestType)
{
case DnsDigestType.Sha1:
maxDigestLength = 20;
break;
case DnsDigestType.Sha256:
maxDigestLength = 32;
break;
default:
maxDigestLength = int.MaxValue;
break;
}
Digest = digest.SubSegment(0, Math.Min(digest.Length, maxDigestLength));
ExtraDigest = digest.SubSegment(Digest.Length, digest.Length - Digest.Length);
}
/// <summary>
/// Lists the key tag of the DNSKEY RR referred to by the DS record.
/// The Key Tag used by the DS RR is identical to the Key Tag used by RRSIG RRs.
/// Calculated as specified in RFC 2535.
/// </summary>
public ushort KeyTag { get; private set; }
/// <summary>
/// Algorithm must be allowed to sign DNS data.
/// </summary>
public DnsAlgorithm Algorithm { get; private set; }
/// <summary>
/// An identifier for the digest algorithm used.
/// </summary>
public DnsDigestType DigestType { get; private set; }
/// <summary>
/// Calculated over the canonical name of the delegated domain name followed by the whole RDATA of the KEY record (all four fields).
/// digest = hash(canonical FQDN on KEY RR | KEY_RR_rdata)
/// KEY_RR_rdata = Flags | Protocol | Algorithm | Public Key
/// The size of the digest may vary depending on the digest type.
/// </summary>
public DataSegment Digest { get; private set; }
/// <summary>
/// The extra digest bytes after number of bytes according to the digest type.
/// </summary>
public DataSegment ExtraDigest { get; private set; }
public bool Equals(DnsResourceDataDelegationSigner other)
{
return other != null &&
KeyTag.Equals(other.KeyTag) &&
Algorithm.Equals(other.Algorithm) &&
DigestType.Equals(other.DigestType) &&
Digest.Equals(other.Digest);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataDelegationSigner);
}
internal DnsResourceDataDelegationSigner()
: this(0, DnsAlgorithm.None, DnsDigestType.Sha1, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstPartLength + Digest.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.KeyTag, KeyTag, Endianity.Big);
buffer.Write(offset + Offset.Algorithm, (byte)Algorithm);
buffer.Write(offset + Offset.DigestType, (byte)DigestType);
Digest.Write(buffer, offset + Offset.Digest);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
ushort keyTag = data.ReadUShort(Offset.KeyTag, Endianity.Big);
DnsAlgorithm algorithm = (DnsAlgorithm)data[Offset.Algorithm];
DnsDigestType digestType = (DnsDigestType)data[Offset.DigestType];
DataSegment digest = data.SubSegment(Offset.Digest, data.Length - ConstPartLength);
return new DnsResourceDataDelegationSigner(keyTag, algorithm, digestType, digest);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4034, 5011.
/// <pre>
/// +-----+----------+----------+--------+----------+--------------------+
/// | bit | 0-6 | 7 | 8 | 9-14 | 15 |
/// +-----+----------+----------+--------+----------+--------------------+
/// | 0 | Reserved | Zone Key | Revoke | Reserved | Secure Entry Point |
/// +-----+----------+----------+--------+----------+--------------------+
/// | 16 | Protocol | Algorithm |
/// +-----+---------------------+----------------------------------------+
/// | 32 | Public Key |
/// | ... | |
/// +-----+--------------------------------------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.DnsKey)]
public sealed class DnsResourceDataDnsKey : DnsResourceDataSimple, IEquatable<DnsResourceDataDnsKey>
{
public const byte ProtocolValue = 3;
private static class Offset
{
public const int ZoneKey = 0;
public const int Revoke = 1;
public const int SecureEntryPoint = 1;
public const int Protocol = sizeof(ushort);
public const int Algorithm = Protocol + sizeof(byte);
public const int PublicKey = Algorithm + sizeof(byte);
}
private static class Mask
{
public const byte ZoneKey = 0x01;
public const byte Revoke = 0x80;
public const byte SecureEntryPoint = 0x01;
}
private const int ConstantPartLength = Offset.PublicKey;
public DnsResourceDataDnsKey(bool zoneKey, bool revoke, bool secureEntryPoint, byte protocol, DnsAlgorithm algorithm, DataSegment publicKey)
{
ZoneKey = zoneKey;
Revoke = revoke;
SecureEntryPoint = secureEntryPoint;
Protocol = protocol;
Algorithm = algorithm;
PublicKey = publicKey;
}
/// <summary>
/// If true, the DNSKEY record holds a DNS zone key, and the DNSKEY RR's owner name must be the name of a zone.
/// If false, then the DNSKEY record holds some other type of DNS public key and must not be used to verify RRSIGs that cover RRsets.
/// </summary>
public bool ZoneKey { get; private set; }
/// <summary>
/// If true, and the resolver sees an RRSIG(DNSKEY) signed by the associated key,
/// then the resolver must consider this key permanently invalid for all purposes except for validating the revocation.
/// </summary>
public bool Revoke { get; private set; }
/// <summary>
/// RFC 3757.
/// If true, then the DNSKEY record holds a key intended for use as a secure entry point.
/// This flag is only intended to be a hint to zone signing or debugging software as to the intended use of this DNSKEY record;
/// validators must not alter their behavior during the signature validation process in any way based on the setting of this bit.
/// This also means that a DNSKEY RR with the SEP bit set would also need the Zone Key flag set in order to be able to generate signatures legally.
/// A DNSKEY RR with the SEP set and the Zone Key flag not set MUST NOT be used to verify RRSIGs that cover RRsets.
/// </summary>
public bool SecureEntryPoint { get; private set; }
/// <summary>
/// Musthave value 3, and the DNSKEY RR MUST be treated as invalid during signature verification if it is found to be some value other than 3.
/// </summary>
public byte Protocol { get; private set; }
/// <summary>
/// Identifies the public key's cryptographic algorithm and determines the format of the Public Key field.
/// </summary>
public DnsAlgorithm Algorithm { get; private set; }
/// <summary>
/// The public key material.
/// The format depends on the algorithm of the key being stored.
/// </summary>
public DataSegment PublicKey { get; private set; }
public bool Equals(DnsResourceDataDnsKey other)
{
return other != null &&
ZoneKey.Equals(other.ZoneKey) &&
Revoke.Equals(other.Revoke) &&
SecureEntryPoint.Equals(other.SecureEntryPoint) &&
Protocol.Equals(other.Protocol) &&
Algorithm.Equals(other.Algorithm) &&
PublicKey.Equals(other.PublicKey);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataDnsKey);
}
internal DnsResourceDataDnsKey()
: this(false, false, false, ProtocolValue, DnsAlgorithm.None, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstantPartLength + PublicKey.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
byte flagsByte0 = 0;
if (ZoneKey)
flagsByte0 |= Mask.ZoneKey;
buffer.Write(offset + Offset.ZoneKey, flagsByte0);
byte flagsByte1 = 0;
if (Revoke)
flagsByte1 |= Mask.Revoke;
if (SecureEntryPoint)
flagsByte1 |= Mask.SecureEntryPoint;
buffer.Write(offset + Offset.SecureEntryPoint, flagsByte1);
buffer.Write(offset + Offset.Protocol, Protocol);
buffer.Write(offset + Offset.Algorithm, (byte)Algorithm);
PublicKey.Write(buffer, offset + Offset.PublicKey);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
bool zoneKey = data.ReadBool(Offset.ZoneKey, Mask.ZoneKey);
bool revoke = data.ReadBool(Offset.Revoke, Mask.Revoke);
bool secureEntryPoint = data.ReadBool(Offset.SecureEntryPoint, Mask.SecureEntryPoint);
byte protocol = data[Offset.Protocol];
DnsAlgorithm algorithm = (DnsAlgorithm)data[Offset.Algorithm];
DataSegment publicKey = data.SubSegment(Offset.PublicKey, data.Length - ConstantPartLength);
return new DnsResourceDataDnsKey(zoneKey, revoke, secureEntryPoint, protocol, algorithm, publicKey);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +------+
/// | NAME |
/// +------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Ns)]
[DnsTypeRegistration(Type = DnsType.Md)]
[DnsTypeRegistration(Type = DnsType.Mf)]
[DnsTypeRegistration(Type = DnsType.CName)]
[DnsTypeRegistration(Type = DnsType.Mb)]
[DnsTypeRegistration(Type = DnsType.Mg)]
[DnsTypeRegistration(Type = DnsType.Mr)]
[DnsTypeRegistration(Type = DnsType.Ptr)]
[DnsTypeRegistration(Type = DnsType.NsapPtr)]
[DnsTypeRegistration(Type = DnsType.DName)]
public sealed class DnsResourceDataDomainName : DnsResourceData, IEquatable<DnsResourceDataDomainName>
{
public DnsResourceDataDomainName(DnsDomainName data)
{
Data = data;
}
public DnsDomainName Data { get; private set; }
public bool Equals(DnsResourceDataDomainName other)
{
return other != null && Data.Equals(other.Data);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataDomainName);
}
internal DnsResourceDataDomainName()
: this(DnsDomainName.Root)
{
}
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return Data.GetLength(compressionData, offsetInDns);
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
return Data.Write(buffer, dnsOffset, compressionData, offsetInDns);
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
int numBytesRead;
DnsDomainName domainName;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out numBytesRead))
return null;
length -= numBytesRead;
if (length != 0)
return null;
return new DnsResourceDataDomainName(domainName);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsResourceDataDomainNames : DnsResourceData, IEquatable<DnsResourceDataDomainNames>
{
public bool Equals(DnsResourceDataDomainNames other)
{
return other != null &&
GetType() == other.GetType() &&
DomainNames.SequenceEqual(other.DomainNames);
}
public sealed override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataDomainNames);
}
internal DnsResourceDataDomainNames(ReadOnlyCollection<DnsDomainName> domainNames)
{
DomainNames = domainNames;
}
internal DnsResourceDataDomainNames(params DnsDomainName[] domainNames)
: this(domainNames.AsReadOnly())
{
}
internal ReadOnlyCollection<DnsDomainName> DomainNames { get; private set; }
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
int totalLength = 0;
foreach (DnsDomainName domainName in DomainNames)
{
int length = domainName.GetLength(compressionData, offsetInDns);
offsetInDns += length;
totalLength += length;
}
return totalLength;
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
int numBytesWritten = 0;
foreach (DnsDomainName domainName in DomainNames)
numBytesWritten += domainName.Write(buffer, dnsOffset, compressionData, offsetInDns + numBytesWritten);
return numBytesWritten;
}
internal static List<DnsDomainName> ReadDomainNames(DnsDatagram dns, int offsetInDns, int length, int numExpected = 0)
{
List<DnsDomainName> domainNames = new List<DnsDomainName>(numExpected);
while (length != 0)
{
DnsDomainName domainName;
int domainNameLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out domainNameLength))
return null;
offsetInDns += domainNameLength;
length -= domainNameLength;
domainNames.Add(domainName);
}
return domainNames;
}
}
}
\ No newline at end of file
using System;
using System.Text;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----------+
/// | LONGITUDE |
/// +-----------+
/// | LATITUDE |
/// +-----------+
/// | ALTITUDE |
/// +-----------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.GPos)]
public sealed class DnsResourceDataGeographicalPosition : DnsResourceDataSimple, IEquatable<DnsResourceDataGeographicalPosition>
{
public DnsResourceDataGeographicalPosition(string longitude, string latitude, string altitude)
{
Longitude = longitude;
Latitude = latitude;
Altitude = altitude;
}
/// <summary>
/// The real number describing the longitude encoded as a printable string.
/// The precision is limited by 256 charcters within the range -90..90 degrees.
/// Positive numbers indicate locations north of the equator.
/// </summary>
public string Longitude { get; private set; }
/// <summary>
/// The real number describing the latitude encoded as a printable string.
/// The precision is limited by 256 charcters within the range -180..180 degrees.
/// Positive numbers indicate locations east of the prime meridian.
/// </summary>
public string Latitude { get; private set; }
/// <summary>
/// The real number describing the altitude (in meters) from mean sea-level encoded as a printable string.
/// The precision is limited by 256 charcters.
/// Positive numbers indicate locations above mean sea-level.
/// </summary>
public string Altitude { get; private set; }
public bool Equals(DnsResourceDataGeographicalPosition other)
{
return other != null &&
Longitude.Equals(other.Longitude) &&
Latitude.Equals(other.Latitude) &&
Altitude.Equals(other.Altitude);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataGeographicalPosition);
}
internal DnsResourceDataGeographicalPosition()
: this(string.Empty, string.Empty, string.Empty)
{
}
internal override int GetLength()
{
return Encoding.ASCII.GetByteCount(Longitude) + 1 +
Encoding.ASCII.GetByteCount(Latitude) + 1 +
Encoding.ASCII.GetByteCount(Altitude) + 1;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
byte[] longtitudeBytes = Encoding.ASCII.GetBytes(Longitude);
byte[] latitudeBytes = Encoding.ASCII.GetBytes(Latitude);
byte[] altitudeBytes = Encoding.ASCII.GetBytes(Altitude);
buffer.Write(ref offset, (byte)longtitudeBytes.Length);
buffer.Write(ref offset, longtitudeBytes);
buffer.Write(ref offset, (byte)latitudeBytes.Length);
buffer.Write(ref offset, latitudeBytes);
buffer.Write(ref offset, (byte)altitudeBytes.Length);
buffer.Write(ref offset, altitudeBytes);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < 3)
return null;
int longtitudeNumBytes = data[0];
if (data.Length < longtitudeNumBytes + 3)
return null;
string longtitude = data.SubSegment(1, longtitudeNumBytes).ToString(Encoding.ASCII);
data = data.SubSegment(longtitudeNumBytes + 1, data.Length - longtitudeNumBytes - 1);
int latitudeNumBytes = data[0];
if (data.Length < latitudeNumBytes + 2)
return null;
string latitude = data.SubSegment(1, latitudeNumBytes).ToString(Encoding.ASCII);
data = data.SubSegment(latitudeNumBytes + 1, data.Length - latitudeNumBytes - 1);
int altitudeNumBytes = data[0];
if (data.Length != altitudeNumBytes + 1)
return null;
string altitude = data.SubSegment(1, altitudeNumBytes).ToString(Encoding.ASCII);
return new DnsResourceDataGeographicalPosition(longtitude, latitude, altitude);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using IListExtensions = PcapDotNet.Base.IListExtensions;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 5205.
/// <pre>
/// +-----+------------+--------------+-----------+
/// | bit | 0-7 | 8-15 | 16-31 |
/// +-----+------------+--------------+-----------+
/// | 0 | HIT Length | PK Algorithm | PK Length |
/// +-----+------------+--------------+-----------+
/// | 32 | HIT |
/// | ... | |
/// +-----+---------------------------------------+
/// | | Public Key |
/// | ... | |
/// +-----+---------------------------------------+
/// | | Rendezvous Servers |
/// | ... | |
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Hip)]
public sealed class DnsResourceDataHostIdentityProtocol: DnsResourceDataNoCompression, IEquatable<DnsResourceDataHostIdentityProtocol>
{
private static class Offset
{
public const int HostIdentityTagLength = 0;
public const int PublicKeyAlgorithm = HostIdentityTagLength + sizeof(byte);
public const int PublicKeyLength = PublicKeyAlgorithm + sizeof(byte);
public const int HostIdentityTag = PublicKeyLength + sizeof(ushort);
}
private const int ConstantPartLength = Offset.HostIdentityTag;
public DnsResourceDataHostIdentityProtocol(DataSegment hostIdentityTag, DnsPublicKeyAlgorithm publicKeyAlgorithm, DataSegment publicKey,
IEnumerable<DnsDomainName> rendezvousServers)
{
if (hostIdentityTag.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("hostIdentityTag", hostIdentityTag.Length, string.Format("Cannot be bigger than {0}.", byte.MaxValue));
if (hostIdentityTag.Length > ushort.MaxValue)
throw new ArgumentOutOfRangeException("publicKey", publicKey.Length, string.Format("Cannot be bigger than {0}.", ushort.MaxValue));
HostIdentityTag = hostIdentityTag;
PublicKeyAlgorithm = publicKeyAlgorithm;
PublicKey = publicKey;
RendezvousServers = IListExtensions.AsReadOnly<DnsDomainName>(rendezvousServers.ToArray());
}
/// <summary>
/// Stored as a binary value in network byte order.
/// </summary>
public DataSegment HostIdentityTag { get; private set; }
/// <summary>
/// Identifies the public key's cryptographic algorithm and determines the format of the public key field.
/// </summary>
public DnsPublicKeyAlgorithm PublicKeyAlgorithm { get; private set; }
/// <summary>
/// Contains the algorithm-specific portion of the KEY RR RDATA.
/// </summary>
public DataSegment PublicKey { get; private set; }
/// <summary>
/// Indicates one or more domain names of rendezvous server(s).
/// Must not be compressed.
/// The rendezvous server(s) are listed in order of preference (i.e., first rendezvous server(s) are preferred),
/// defining an implicit order amongst rendezvous servers of a single RR.
/// When multiple HIP RRs are present at the same owner name,
/// this implicit order of rendezvous servers within an RR must not be used to infer a preference order between rendezvous servers stored in different RRs.
/// </summary>
public ReadOnlyCollection<DnsDomainName> RendezvousServers { get; private set; }
public bool Equals(DnsResourceDataHostIdentityProtocol other)
{
return other != null &&
HostIdentityTag.Equals(other.HostIdentityTag) &&
PublicKeyAlgorithm.Equals(other.PublicKeyAlgorithm) &&
PublicKey.Equals(other.PublicKey) &&
RendezvousServers.SequenceEqual(RendezvousServers);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataHostIdentityProtocol);
}
internal DnsResourceDataHostIdentityProtocol()
: this(DataSegment.Empty, DnsPublicKeyAlgorithm.None, DataSegment.Empty, new DnsDomainName[0])
{
}
internal override int GetLength()
{
return ConstantPartLength + HostIdentityTag.Length + PublicKey.Length + RendezvousServers.Sum(rendezvousServer => rendezvousServer.NonCompressedLength);
}
internal override int WriteData(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.HostIdentityTagLength, (byte)HostIdentityTag.Length);
buffer.Write(offset + Offset.PublicKeyAlgorithm, (byte)PublicKeyAlgorithm);
buffer.Write(offset + Offset.PublicKeyLength, (ushort)PublicKey.Length, Endianity.Big);
HostIdentityTag.Write(buffer, offset + Offset.HostIdentityTag);
int numBytesWritten = ConstantPartLength + HostIdentityTag.Length;
PublicKey.Write(buffer, offset + numBytesWritten);
numBytesWritten += PublicKey.Length;
foreach (DnsDomainName rendezvousServer in RendezvousServers)
{
rendezvousServer.WriteUncompressed(buffer, offset + numBytesWritten);
numBytesWritten += rendezvousServer.NonCompressedLength;
}
return numBytesWritten;
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
if (length < ConstantPartLength)
return null;
int hostIdentityTagLength = dns[offsetInDns + Offset.HostIdentityTagLength];
DnsPublicKeyAlgorithm publicKeyAlgorithm = (DnsPublicKeyAlgorithm)dns[offsetInDns + Offset.PublicKeyAlgorithm];
int publicKeyLength = dns.ReadUShort(offsetInDns + Offset.PublicKeyLength, Endianity.Big);
if (length < ConstantPartLength + hostIdentityTagLength + publicKeyLength)
return null;
DataSegment hostIdentityTag = dns.SubSegment(offsetInDns + Offset.HostIdentityTag, hostIdentityTagLength);
int publicKeyOffset = offsetInDns + ConstantPartLength + hostIdentityTagLength;
DataSegment publicKey = dns.SubSegment(publicKeyOffset, publicKeyLength);
offsetInDns += ConstantPartLength + hostIdentityTagLength + publicKeyLength;
length -= ConstantPartLength + hostIdentityTagLength + publicKeyLength;
List<DnsDomainName> rendezvousServers = new List<DnsDomainName>();
while (length != 0)
{
DnsDomainName rendezvousServer;
int rendezvousServerLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out rendezvousServer, out rendezvousServerLength))
return null;
rendezvousServers.Add(rendezvousServer);
offsetInDns += rendezvousServerLength;
length -= rendezvousServerLength;
}
return new DnsResourceDataHostIdentityProtocol(hostIdentityTag, publicKeyAlgorithm, publicKey, rendezvousServers);
}
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+
/// | CPU |
/// +-----+
/// | OS |
/// +-----+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.HInfo)]
public sealed class DnsResourceDataHostInformation : DnsResourceDataStrings
{
private const int NumStrings = 2;
public DnsResourceDataHostInformation(DataSegment cpu, DataSegment os)
: base(cpu, os)
{
}
public DataSegment Cpu { get { return Strings[0]; } }
public DataSegment Os { get { return Strings[1]; } }
internal DnsResourceDataHostInformation()
: this(DataSegment.Empty, DataSegment.Empty)
{
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
List<DataSegment> strings = ReadStrings(data, NumStrings);
if (strings == null || strings.Count != NumStrings)
return null;
return new DnsResourceDataHostInformation(strings[0], strings[1]);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4025.
/// <pre>
/// +-----+--------------+
/// | bit | 0-7 |
/// +-----+--------------+
/// | 0 | precedence |
/// +-----+--------------+
/// | 8 | gateway type |
/// +-----+--------------+
/// | 16 | algorithm |
/// +-----+--------------+
/// | 24 | gateway |
/// | ... | |
/// +-----+--------------+
/// | | public key |
/// | ... | |
/// +-----+--------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.IpSecKey)]
public sealed class DnsResourceDataIpSecKey : DnsResourceDataNoCompression, IEquatable<DnsResourceDataIpSecKey>
{
public static class Offset
{
public const int Precedence = 0;
public const int GatewayType = Precedence + sizeof(byte);
public const int Algorithm = GatewayType + sizeof(byte);
public const int Gateway = Algorithm + sizeof(byte);
}
public const int ConstPartLength = Offset.Gateway;
public DnsResourceDataIpSecKey(byte precedence, DnsGateway gateway, DnsPublicKeyAlgorithm algorithm, DataSegment publicKey)
{
Precedence = precedence;
Gateway = gateway;
Algorithm = algorithm;
PublicKey = publicKey;
}
/// <summary>
/// Precedence for this record.
/// Gateways listed in IPSECKEY records with lower precedence are to be attempted first.
/// Where there is a tie in precedence, the order should be non-deterministic.
/// </summary>
public byte Precedence { get; private set; }
/// <summary>
/// Indicates the format of the information that is stored in the gateway field.
/// </summary>
public DnsGatewayType GatewayType { get { return Gateway.Type; } }
/// <summary>
/// Indicates a gateway to which an IPsec tunnel may be created in order to reach the entity named by this resource record.
/// </summary>
public DnsGateway Gateway { get; private set;}
/// <summary>
/// Identifies the public key's cryptographic algorithm and determines the format of the public key field.
/// </summary>
public DnsPublicKeyAlgorithm Algorithm { get; private set;}
/// <summary>
/// Contains the algorithm-specific portion of the KEY RR RDATA.
/// </summary>
public DataSegment PublicKey { get; private set; }
public bool Equals(DnsResourceDataIpSecKey other)
{
return other != null &&
Precedence.Equals(other.Precedence) &&
Gateway.Equals(other.Gateway) &&
Algorithm.Equals(other.Algorithm) &&
PublicKey.Equals(other.PublicKey);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataIpSecKey);
}
internal DnsResourceDataIpSecKey()
: this(0, DnsGateway.None, DnsPublicKeyAlgorithm.None, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstPartLength + Gateway.Length + PublicKey.Length;
}
internal override int WriteData(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.Precedence, Precedence);
buffer.Write(offset + Offset.GatewayType, (byte)GatewayType);
buffer.Write(offset + Offset.Algorithm, (byte)Algorithm);
Gateway.Write(buffer, offset + Offset.Gateway);
PublicKey.Write(buffer, offset + ConstPartLength + Gateway.Length);
return GetLength();
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
if (length < ConstPartLength)
return null;
byte precedence = dns[offsetInDns + Offset.Precedence];
DnsGatewayType gatewayType = (DnsGatewayType)dns[offsetInDns + Offset.GatewayType];
DnsPublicKeyAlgorithm algorithm = (DnsPublicKeyAlgorithm)dns[offsetInDns + Offset.Algorithm];
DnsGateway gateway = DnsGateway.CreateInstance(gatewayType, dns, offsetInDns + Offset.Gateway, length - ConstPartLength);
if (gateway == null)
return null;
DataSegment publicKey = dns.SubSegment(offsetInDns + ConstPartLength + gateway.Length, length - ConstPartLength - gateway.Length);
return new DnsResourceDataIpSecKey(precedence, gateway, algorithm, publicKey);
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+------+
/// | bit | 0-31 |
/// +-----+------+
/// | 0 | IP |
/// +-----+------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.A)]
public sealed class DnsResourceDataIpV4 : DnsResourceDataSimple, IEquatable<DnsResourceDataIpV4>
{
public DnsResourceDataIpV4(IpV4Address data)
{
Data = data;
}
public IpV4Address Data { get; private set; }
public bool Equals(DnsResourceDataIpV4 other)
{
return other != null && Data.Equals(other.Data);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataIpV4);
}
internal DnsResourceDataIpV4()
: this(IpV4Address.Zero)
{
}
internal override int GetLength()
{
return IpV4Address.SizeOf;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset, Data, Endianity.Big);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length != IpV4Address.SizeOf)
return null;
return new DnsResourceDataIpV4(data.ReadIpV4Address(0, Endianity.Big));
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV6;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+-------+
/// | bit | 0-127 |
/// +-----+-------+
/// | 0 | IP |
/// +-----+-------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Aaaa)]
public sealed class DnsResourceDataIpV6 : DnsResourceDataSimple, IEquatable<DnsResourceDataIpV6>
{
public DnsResourceDataIpV6(IpV6Address data)
{
Data = data;
}
public IpV6Address Data { get; private set; }
public bool Equals(DnsResourceDataIpV6 other)
{
return other != null && Data.Equals(other.Data);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataIpV6);
}
internal DnsResourceDataIpV6()
: this(IpV6Address.Zero)
{
}
internal override int GetLength()
{
return IpV6Address.SizeOf;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset, Data, Endianity.Big);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length != IpV6Address.SizeOf)
return null;
return new DnsResourceDataIpV6(data.ReadIpV6Address(0, Endianity.Big));
}
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +---------------+
/// | ISDN-address |
/// +---------------+
/// | sa (optional) |
/// +---------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Isdn)]
public sealed class DnsResourceDataIsdn : DnsResourceDataStrings
{
private const int MinNumStrings = 1;
private const int MaxNumStrings = 2;
public DnsResourceDataIsdn(DataSegment isdnAddress)
: base(isdnAddress)
{
}
public DnsResourceDataIsdn(DataSegment isdnAddress, DataSegment subAddress)
: base(isdnAddress, subAddress)
{
}
/// <summary>
/// Identifies the ISDN number of the owner and DDI (Direct Dial In) if any, as defined by E.164 and E.163,
/// the ISDN and PSTN (Public Switched Telephone Network) numbering plan.
/// E.163 defines the country codes, and E.164 the form of the addresses.
/// </summary>
public DataSegment IsdnAddress { get { return Strings[0]; } }
/// <summary>
/// Specifies the subaddress (SA).
/// </summary>
public DataSegment SubAddress { get { return Strings.Count == MaxNumStrings ? Strings[1] : null; } }
internal DnsResourceDataIsdn()
: this(DataSegment.Empty)
{
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
List<DataSegment> strings = ReadStrings(data, MaxNumStrings);
if (strings == null)
return null;
if (strings.Count == MinNumStrings)
return new DnsResourceDataIsdn(strings[0]);
if (strings.Count == MaxNumStrings)
return new DnsResourceDataIsdn(strings[0], strings[1]);
return null;
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2230.
/// <pre>
/// +-----+-------------------+
/// | bit | 0-15 |
/// +-----+-------------------+
/// | 0 | PREFERENCE |
/// +-----+-------------------+
/// | 16 | EXCHANGER |
/// | ... | |
/// +-----+-------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Kx)]
public sealed class DnsResourceDataKeyExchanger : DnsResourceDataUShortDomainName
{
public DnsResourceDataKeyExchanger(ushort preference, DnsDomainName keyExchanger)
: base(preference, keyExchanger)
{
}
/// <summary>
/// Specifies the preference given to this RR among other KX records at the same owner.
/// Lower values are preferred.
/// </summary>
public ushort Preference { get { return Value; } }
/// <summary>
/// Specifies a host willing to act as a key exchange for the owner name.
/// </summary>
public DnsDomainName KeyExchangeHost { get { return DomainName; } }
internal DnsResourceDataKeyExchanger()
: this(0, DnsDomainName.Root)
{
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
ushort preference;
DnsDomainName keyExchangeHost;
if (!TryRead(out preference, out keyExchangeHost, dns, offsetInDns, length))
return null;
return new DnsResourceDataKeyExchanger(preference, keyExchangeHost);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+------------+
/// | bit | 0-15 |
/// +-----+------------+
/// | 0 | PREFERENCE |
/// +-----+------------+
/// | 16 | EXCHANGE |
/// | ... | |
/// +-----+------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Mx)]
public sealed class DnsResourceDataMailExchange : DnsResourceDataUShortDomainName
{
public DnsResourceDataMailExchange(ushort preference, DnsDomainName mailExchangeHost)
: base(preference, mailExchangeHost)
{
}
/// <summary>
/// Specifies the preference given to this RR among others at the same owner.
/// Lower values are preferred.
/// </summary>
public ushort Preference { get { return Value; } }
/// <summary>
/// Specifies a host willing to act as a mail exchange for the owner name.
/// </summary>
public DnsDomainName MailExchangeHost { get { return DomainName; } }
internal DnsResourceDataMailExchange()
: this(0, DnsDomainName.Root)
{
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
ushort preference;
DnsDomainName mailExchangeHost;
if (!TryRead(out preference, out mailExchangeHost, dns, offsetInDns, length))
return null;
return new DnsResourceDataMailExchange(preference, mailExchangeHost);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +---------+
/// | RMAILBX |
/// +---------+
/// | EMAILBX |
/// +---------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.MInfo)]
public sealed class DnsResourceDataMailingListInfo : DnsResourceData2DomainNames
{
public DnsResourceDataMailingListInfo(DnsDomainName mailingList, DnsDomainName errorMailBox)
: base(mailingList, errorMailBox)
{
}
/// <summary>
/// Specifies a mailbox which is responsible for the mailing list or mailbox.
/// If this domain name names the root, the owner of the MINFO RR is responsible for itself.
/// Note that many existing mailing lists use a mailbox X-request for the RMAILBX field of mailing list X, e.g., Msgroup-request for Msgroup.
/// This field provides a more general mechanism.
/// </summary>
public DnsDomainName MailingList { get { return First; } }
/// <summary>
/// Specifies a mailbox which is to receive error messages related to the mailing list or mailbox specified by the owner of the MINFO RR
/// (similar to the ERRORS-TO: field which has been proposed).
/// If this domain name names the root, errors should be returned to the sender of the message.
/// </summary>
public DnsDomainName ErrorMailBox { get { return Second; } }
internal DnsResourceDataMailingListInfo()
: this(DnsDomainName.Root, DnsDomainName.Root)
{
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
DnsDomainName mailingList;
DnsDomainName errorMailBox;
if (!TryRead(out mailingList, out errorMailBox, dns, offsetInDns, length))
return null;
return new DnsResourceDataMailingListInfo(mailingList, errorMailBox);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +---------------------+
/// | One ore more strings|
/// +---------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.NInfo)]
public sealed class DnsResourceDataNInfo : DnsResourceDataStrings
{
private const int MinNumStrings = 1;
public DnsResourceDataNInfo(ReadOnlyCollection<DataSegment> strings)
: base(strings)
{
if (strings.Count < MinNumStrings)
throw new ArgumentOutOfRangeException("strings", strings.Count, "There must be at least one string.");
}
public DnsResourceDataNInfo(params DataSegment[] strings)
: this(strings.AsReadOnly())
{
}
internal DnsResourceDataNInfo()
: this(DataSegment.Empty)
{
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
List<DataSegment> strings = ReadStrings(data, MinNumStrings);
if (strings == null || strings.Count < 1)
return null;
return new DnsResourceDataNInfo(strings.AsReadOnly());
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +-----+-----+----------------------+----------+-----------+
/// | bit | 0-7 | 8-7+X | 8+X-55+X | 56+X-63+X |
/// +-----+-----+----------------------+----------+-----------+
/// | 0 | AFI | Domain Specific Area | ID | Sel |
/// +-----+-----+-----+----------------+----------+-----------+
/// | 0 | AFI | IDI | HO-DSP | ID | Sel |
/// +-----+-----+-----+----------------+----------+-----------+
/// | 0 | Area Address | ID | Sel |
/// +-----+-----------+----------------+----------+-----------+
/// | 0 | IDP | DSP |
/// +-----+-----------+---------------------------------------+
/// </pre>
/// IDP is Initial Domain Part.
/// DSP is Domain Specific Part.
/// HO-DSP may use any format as defined by the authority identified by IDP.
/// </summary>
[DnsTypeRegistration(Type = DnsType.Nsap)]
public sealed class DnsResourceDataNetworkServiceAccessPoint : DnsResourceDataSimple, IEquatable<DnsResourceDataNetworkServiceAccessPoint>
{
private static class Offset
{
public const int AreaAddress = 0;
}
private static class OffsetAfterArea
{
public const int SystemIdentifier = 0;
public const int Selector = SystemIdentifier + UInt48.SizeOf;
}
private const int MinAreaAddressLength = sizeof(byte);
private const int ConstantPartLength = MinAreaAddressLength + OffsetAfterArea.Selector + sizeof(byte);
public DnsResourceDataNetworkServiceAccessPoint(DataSegment areaAddress, UInt48 systemIdentifier, byte selector)
{
if (areaAddress.Length < MinAreaAddressLength)
throw new ArgumentOutOfRangeException("areaAddress", areaAddress.Length,
string.Format("Area Address length must be at least {0}.", MinAreaAddressLength));
AreaAddress = areaAddress;
SystemIdentifier = systemIdentifier;
Selector = selector;
}
/// <summary>
/// Authority and Format Identifier.
/// </summary>
public byte AuthorityAndFormatIdentifier { get { return AreaAddress[0]; } }
/// <summary>
/// The combination of [IDP, HO-DSP] identify both the routing domain and the area within the routing domain.
/// Hence the combination [IDP, HO-DSP] is called the "Area Address".
/// All nodes within the area must have same Area address.
/// </summary>
public DataSegment AreaAddress { get; private set; }
/// <summary>
/// System Identifier.
/// </summary>
public UInt48 SystemIdentifier { get; private set; }
/// <summary>
/// NSAP Selector
/// </summary>
public byte Selector { get; private set; }
public bool Equals(DnsResourceDataNetworkServiceAccessPoint other)
{
return other != null &&
AreaAddress.Equals(other.AreaAddress) &&
SystemIdentifier.Equals(other.SystemIdentifier) &&
Selector.Equals(other.Selector);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNetworkServiceAccessPoint);
}
internal DnsResourceDataNetworkServiceAccessPoint()
: this(new DataSegment(new byte[MinAreaAddressLength]), 0, 0)
{
}
internal override int GetLength()
{
return ConstantPartLength + AreaAddress.Length - MinAreaAddressLength;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
AreaAddress.Write(buffer, offset + Offset.AreaAddress);
int afterAreaOffset = offset + AreaAddress.Length;
buffer.Write(afterAreaOffset + OffsetAfterArea.SystemIdentifier, SystemIdentifier, Endianity.Big);
buffer.Write(afterAreaOffset + OffsetAfterArea.Selector, Selector);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
DataSegment areaAddress = data.SubSegment(Offset.AreaAddress, MinAreaAddressLength + data.Length - ConstantPartLength);
int afterAreaOffset = areaAddress.Length;
UInt48 systemIdentifier = data.ReadUInt48(afterAreaOffset + OffsetAfterArea.SystemIdentifier, Endianity.Big);
byte selector = data[afterAreaOffset + OffsetAfterArea.Selector];
return new DnsResourceDataNetworkServiceAccessPoint(areaAddress, systemIdentifier, selector);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2535.
/// <pre>
/// +------------------+
/// | next domain name |
/// | |
/// +------------------+
/// | type bit map |
/// | |
/// +------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Nxt)]
public sealed class DnsResourceDataNextDomain : DnsResourceData, IEquatable<DnsResourceDataNextDomain>
{
public const int MaxTypeBitMapLength = 16;
public const DnsType MaxTypeBitMapDnsType = (DnsType)(8 * MaxTypeBitMapLength);
public DnsResourceDataNextDomain(DnsDomainName nextDomainName, DataSegment typeBitMap)
{
if (typeBitMap.Length > MaxTypeBitMapLength)
throw new ArgumentOutOfRangeException("typeBitMap", typeBitMap.Length, string.Format("Cannot be longer than {0} bytes.", MaxTypeBitMapLength));
if (typeBitMap.Length > 0 && typeBitMap.Last == 0)
throw new ArgumentOutOfRangeException("typeBitMap", typeBitMap, "Last byte cannot be 0x00");
NextDomainName = nextDomainName;
TypeBitMap = typeBitMap;
}
/// <summary>
/// The next domain name according to the canonical DNS name order.
/// </summary>
public DnsDomainName NextDomainName { get; private set; }
/// <summary>
/// One bit per RR type present for the owner name.
/// A one bit indicates that at least one RR of that type is present for the owner name.
/// A zero indicates that no such RR is present.
/// All bits not specified because they are beyond the end of the bit map are assumed to be zero.
/// Note that bit 30, for NXT, will always be on so the minimum bit map length is actually four octets.
/// Trailing zero octets are prohibited in this format.
/// The first bit represents RR type zero (an illegal type which can not be present) and so will be zero in this format.
/// This format is not used if there exists an RR with a type number greater than 127.
/// If the zero bit of the type bit map is a one, it indicates that a different format is being used which will always be the case if a type number greater than 127 is present.
/// </summary>
public DataSegment TypeBitMap { get; private set; }
public IEnumerable<DnsType> TypesExist
{
get
{
ushort typeValue = 0;
for (int byteOffset = 0; byteOffset != TypeBitMap.Length; ++byteOffset)
{
byte mask = 0x80;
for (int i = 0; i != 8; ++i)
{
if (TypeBitMap.ReadBool(byteOffset, mask))
yield return (DnsType)typeValue;
++typeValue;
mask >>= 1;
}
}
}
}
public bool IsTypePresentForOwner(DnsType dnsType)
{
if (dnsType >= MaxTypeBitMapDnsType)
throw new ArgumentOutOfRangeException("dnsType", dnsType, string.Format("Cannot be bigger than {0}.", MaxTypeBitMapDnsType));
int byteOffset;
byte mask;
DnsTypeToByteOffsetAndMask(out byteOffset, out mask, dnsType);
if (byteOffset > TypeBitMap.Length)
return false;
return TypeBitMap.ReadBool(byteOffset, mask);
}
public static DataSegment CreateTypeBitMap(IEnumerable<DnsType> typesPresentForOwner)
{
DnsType maxDnsType = typesPresentForOwner.Max();
int length = (ushort)(maxDnsType + 7) / 8;
if (length == 0)
return DataSegment.Empty;
byte[] typeBitMapBuffer = new byte[length];
foreach (DnsType dnsType in typesPresentForOwner)
{
int byteOffset;
byte mask;
DnsTypeToByteOffsetAndMask(out byteOffset, out mask, dnsType);
typeBitMapBuffer[byteOffset] |= mask;
}
return new DataSegment(typeBitMapBuffer);
}
public bool Equals(DnsResourceDataNextDomain other)
{
return other != null &&
NextDomainName.Equals(other.NextDomainName) &&
TypeBitMap.Equals(other.TypeBitMap);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNextDomain);
}
internal DnsResourceDataNextDomain()
: this(DnsDomainName.Root, DataSegment.Empty)
{
}
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return NextDomainName.GetLength(compressionData, offsetInDns) + TypeBitMap.Length;
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
int numBytesWritten = NextDomainName.Write(buffer, dnsOffset, compressionData, offsetInDns);
TypeBitMap.Write(buffer, dnsOffset + offsetInDns + numBytesWritten);
return numBytesWritten + TypeBitMap.Length;
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
DnsDomainName nextDomainName;
int nextDomainNameLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out nextDomainName, out nextDomainNameLength))
return null;
offsetInDns += nextDomainNameLength;
length -= nextDomainNameLength;
if (length > MaxTypeBitMapLength)
return null;
DataSegment typeBitMap = dns.SubSegment(offsetInDns, length);
if (length != 0 && typeBitMap.Last == 0)
return null;
return new DnsResourceDataNextDomain(nextDomainName, typeBitMap);
}
private static void DnsTypeToByteOffsetAndMask(out int byteOffset, out byte mask, DnsType dnsType)
{
byteOffset = (ushort)dnsType / 8;
mask = (byte)(1 << ((ushort)dnsType % 8));
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 4034.
/// <pre>
/// +------------------+
/// | next domain name |
/// | |
/// +------------------+
/// | type bit map |
/// | |
/// +------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.NSec)]
public sealed class DnsResourceDataNextDomainSecure : DnsResourceDataNoCompression, IEquatable<DnsResourceDataNextDomainSecure>
{
public DnsResourceDataNextDomainSecure(DnsDomainName nextDomainName, IEnumerable<DnsType> typesExist)
: this(nextDomainName, new DnsTypeBitmaps(typesExist))
{
}
/// <summary>
/// Contains the next owner name (in the canonical ordering of the zone) that has authoritative data or contains a delegation point NS RRset;
/// The value of the Next Domain Name field in the last NSEC record in the zone is the name of the zone apex (the owner name of the zone's SOA RR).
/// This indicates that the owner name of the NSEC RR is the last name in the canonical ordering of the zone.
///
/// Owner names of RRsets for which the given zone is not authoritative (such as glue records) must not be listed in the Next Domain Name
/// unless at least one authoritative RRset exists at the same owner name.
/// </summary>
public DnsDomainName NextDomainName { get; private set; }
/// <summary>
/// Identifies the RRset types that exist at the NSEC RR's owner name.
/// Ordered by the DnsType value.
/// </summary>
public ReadOnlyCollection<DnsType> TypesExist { get { return _typeBitmaps.TypesExist.AsReadOnly(); } }
public bool IsTypePresentForOwner(DnsType dnsType)
{
return _typeBitmaps.Contains(dnsType);
}
public bool Equals(DnsResourceDataNextDomainSecure other)
{
return other != null &&
NextDomainName.Equals(other.NextDomainName) &&
_typeBitmaps.Equals(other._typeBitmaps);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNextDomainSecure);
}
internal DnsResourceDataNextDomainSecure()
: this(DnsDomainName.Root, new DnsType[0])
{
}
internal override int GetLength()
{
return NextDomainName.NonCompressedLength + _typeBitmaps.GetLength();
}
internal override int WriteData(byte[] buffer, int offset)
{
NextDomainName.WriteUncompressed(buffer, offset);
int nextDomainNameLength = NextDomainName.NonCompressedLength;
return nextDomainNameLength + _typeBitmaps.Write(buffer, offset + nextDomainNameLength);
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
DnsDomainName nextDomainName;
int nextDomainNameLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out nextDomainName, out nextDomainNameLength))
return null;
offsetInDns += nextDomainNameLength;
length -= nextDomainNameLength;
DnsTypeBitmaps typeBitmaps = DnsTypeBitmaps.CreateInstance(dns.Buffer, dns.StartOffset + offsetInDns, length);
if (typeBitmaps == null)
return null;
return new DnsResourceDataNextDomainSecure(nextDomainName, typeBitmaps);
}
private DnsResourceDataNextDomainSecure(DnsDomainName nextDomainName, DnsTypeBitmaps typeBitmaps)
{
NextDomainName = nextDomainName;
_typeBitmaps = typeBitmaps;
}
private readonly DnsTypeBitmaps _typeBitmaps;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 5155.
/// <pre>
/// +-----+-------------+----------+--------+------------+
/// | bit | 0-7 | 8-14 | 15 | 16-31 |
/// +-----+-------------+----------+--------+------------+
/// | 0 | Hash Alg | Reserved | OptOut | Iterations |
/// +-----+-------------+----------+--------+------------+
/// | 32 | Salt Length | Salt |
/// +-----+-------------+ |
/// | ... | |
/// +-----+-------------+--------------------------------+
/// | | Hash Length | Next Hashed Owner Name |
/// +-----+-------------+ |
/// | ... | |
/// +-----+----------------------------------------------+
/// | | Type Bit Maps |
/// | ... | |
/// +-----+----------------------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.NSec3)]
public sealed class DnsResourceDataNextDomainSecure3 : DnsResourceDataNextDomainSecure3Base, IEquatable<DnsResourceDataNextDomainSecure3>
{
public DnsResourceDataNextDomainSecure3(DnsSecNSec3HashAlgorithm hashAlgorithm, DnsSecNSec3Flags flags, ushort iterations, DataSegment salt,
DataSegment nextHashedOwnerName, IEnumerable<DnsType> existTypes)
: this(hashAlgorithm, flags, iterations, salt, nextHashedOwnerName, new DnsTypeBitmaps(existTypes))
{
}
/// <summary>
/// Contains the next hashed owner name in hash order.
/// This value is in binary format.
/// Given the ordered set of all hashed owner names, the Next Hashed Owner Name field contains the hash of an owner name that immediately follows the owner name of the given NSEC3 RR.
/// The value of the Next Hashed Owner Name field in the last NSEC3 RR in the zone is the same as the hashed owner name of the first NSEC3 RR in the zone in hash order.
/// Note that, unlike the owner name of the NSEC3 RR, the value of this field does not contain the appended zone name.
/// </summary>
public DataSegment NextHashedOwnerName { get; private set; }
/// <summary>
/// Identifies the RRSet types that exist at the original owner name of the NSEC3 RR.
/// </summary>
public ReadOnlyCollection<DnsType> TypesExist { get { return _typeBitmaps.TypesExist.AsReadOnly(); } }
public bool Equals(DnsResourceDataNextDomainSecure3 other)
{
return EqualsParameters(other) &&
NextHashedOwnerName.Equals(other.NextHashedOwnerName) &&
_typeBitmaps.Equals(other._typeBitmaps);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNextDomainSecure3);
}
internal DnsResourceDataNextDomainSecure3()
: this(DnsSecNSec3HashAlgorithm.Sha1, DnsSecNSec3Flags.None, 0, DataSegment.Empty, DataSegment.Empty, new DnsType[0])
{
}
internal override int GetLength()
{
return ParametersLength + sizeof(byte) + NextHashedOwnerName.Length + _typeBitmaps.GetLength();
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
WriteParameters(buffer, offset);
buffer.Write(offset + NextHashedOwnerNameLengthOffset, (byte)NextHashedOwnerName.Length);
NextHashedOwnerName.Write(buffer, offset + NextHashedOwnerNameOffset);
_typeBitmaps.Write(buffer, offset + TypeBitmapsOffset);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
DnsSecNSec3HashAlgorithm hashAlgorithm;
DnsSecNSec3Flags flags;
ushort iterations;
DataSegment salt;
if (!TryReadParameters(data, out hashAlgorithm, out flags, out iterations, out salt))
return null;
int nextHashedOwnerNameLengthOffset = GetParametersLength(salt.Length);
if (data.Length - nextHashedOwnerNameLengthOffset < sizeof(byte))
return null;
int nextHashedOwnerNameOffset = nextHashedOwnerNameLengthOffset + sizeof(byte);
int nextHashedOwnerNameLength = data[nextHashedOwnerNameLengthOffset];
if (data.Length - nextHashedOwnerNameOffset < nextHashedOwnerNameLength)
return null;
DataSegment nextHashedOwnerName = data.SubSegment(nextHashedOwnerNameOffset, nextHashedOwnerNameLength);
int typeBitmapsOffset = nextHashedOwnerNameOffset + nextHashedOwnerNameLength;
DnsTypeBitmaps typeBitmaps = DnsTypeBitmaps.CreateInstance(data.Buffer, data.StartOffset + typeBitmapsOffset, data.Length - typeBitmapsOffset);
if (typeBitmaps == null)
return null;
return new DnsResourceDataNextDomainSecure3(hashAlgorithm, flags, iterations, salt, nextHashedOwnerName, typeBitmaps);
}
private DnsResourceDataNextDomainSecure3(DnsSecNSec3HashAlgorithm hashAlgorithm, DnsSecNSec3Flags flags, ushort iterations, DataSegment salt,
DataSegment nextHashedOwnerName, DnsTypeBitmaps typeBitmaps)
: base(hashAlgorithm, flags, iterations, salt)
{
if (nextHashedOwnerName.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("nextHashedOwnerName", nextHashedOwnerName.Length, string.Format("Cannot bigger than {0}.", byte.MaxValue));
NextHashedOwnerName = nextHashedOwnerName;
_typeBitmaps = typeBitmaps;
}
private int NextHashedOwnerNameLengthOffset { get { return ParametersLength; } }
private int NextHashedOwnerNameOffset { get { return NextHashedOwnerNameLengthOffset + sizeof(byte); } }
private int TypeBitmapsOffset { get { return NextHashedOwnerNameOffset + NextHashedOwnerName.Length; } }
private readonly DnsTypeBitmaps _typeBitmaps;
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 5155.
/// <pre>
/// +-----+-------------+----------+--------+------------+
/// | bit | 0-7 | 8-14 | 15 | 16-31 |
/// +-----+-------------+----------+--------+------------+
/// | 0 | Hash Alg | Reserved | OptOut | Iterations |
/// +-----+-------------+----------+--------+------------+
/// | 32 | Salt Length | Salt |
/// +-----+-------------+ |
/// | ... | |
/// +-----+----------------------------------------------+
/// | ... | ... |
/// +-----+----------------------------------------------+
/// </pre>
/// </summary>
public abstract class DnsResourceDataNextDomainSecure3Base : DnsResourceDataSimple
{
private static class Offset
{
public const int HashAlgorithm = 0;
public const int Flags = HashAlgorithm + sizeof(byte);
public const int Iterations = Flags + sizeof(byte);
public const int SaltLength = Iterations + sizeof(ushort);
public const int Salt = SaltLength + sizeof(byte);
}
private const int ConstantPartLength = Offset.Salt;
/// <summary>
/// Identifies the cryptographic hash algorithm used to construct the hash-value.
/// </summary>
public DnsSecNSec3HashAlgorithm HashAlgorithm { get; private set; }
/// <summary>
/// Can be used to indicate different processing.
/// All undefined flags must be zero.
/// </summary>
public DnsSecNSec3Flags Flags { get; private set; }
/// <summary>
/// Defines the number of additional times the hash function has been performed.
/// More iterations result in greater resiliency of the hash value against dictionary attacks, but at a higher computational cost for both the server and resolver.
/// </summary>
public ushort Iterations { get; private set; }
/// <summary>
/// Appended to the original owner name before hashing in order to defend against pre-calculated dictionary attacks.
/// </summary>
public DataSegment Salt { get; private set; }
internal bool EqualsParameters(DnsResourceDataNextDomainSecure3Base other)
{
return other != null &&
HashAlgorithm.Equals(other.HashAlgorithm) &&
Flags.Equals(other.Flags) &&
Iterations.Equals(other.Iterations) &&
Salt.Equals(other.Salt);
}
internal DnsResourceDataNextDomainSecure3Base(DnsSecNSec3HashAlgorithm hashAlgorithm, DnsSecNSec3Flags flags, ushort iterations, DataSegment salt)
{
if (salt.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("salt", salt.Length, string.Format("Cannot bigger than {0}.", byte.MaxValue));
HashAlgorithm = hashAlgorithm;
Flags = flags;
Iterations = iterations;
Salt = salt;
}
internal int ParametersLength { get { return GetParametersLength(Salt.Length); } }
internal static int GetParametersLength(int saltLength)
{
return ConstantPartLength + saltLength;
}
internal void WriteParameters(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.HashAlgorithm, (byte)HashAlgorithm);
buffer.Write(offset + Offset.Flags, (byte)Flags);
buffer.Write(offset + Offset.Iterations, Iterations, Endianity.Big);
buffer.Write(offset + Offset.SaltLength, (byte)Salt.Length);
Salt.Write(buffer, offset + Offset.Salt);
}
internal static bool TryReadParameters(DataSegment data, out DnsSecNSec3HashAlgorithm hashAlgorithm, out DnsSecNSec3Flags flags, out ushort iterations, out DataSegment salt)
{
if (data.Length < ConstantPartLength)
{
hashAlgorithm = DnsSecNSec3HashAlgorithm.Sha1;
flags = DnsSecNSec3Flags.None;
iterations = 0;
salt = null;
return false;
}
hashAlgorithm = (DnsSecNSec3HashAlgorithm)data[Offset.HashAlgorithm];
flags = (DnsSecNSec3Flags)data[Offset.Flags];
iterations = data.ReadUShort(Offset.Iterations, Endianity.Big);
int saltLength = data[Offset.SaltLength];
if (data.Length - Offset.Salt < saltLength)
{
salt = null;
return false;
}
salt = data.SubSegment(Offset.Salt, saltLength);
return true;
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 5155.
/// <pre>
/// +-----+-------------+----------+--------+------------+
/// | bit | 0-7 | 8-14 | 15 | 16-31 |
/// +-----+-------------+----------+--------+------------+
/// | 0 | Hash Alg | Reserved | OptOut | Iterations |
/// +-----+-------------+----------+--------+------------+
/// | 32 | Salt Length | Salt |
/// +-----+-------------+ |
/// | ... | |
/// +-----+----------------------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.NSec3Param)]
public sealed class DnsResourceDataNextDomainSecure3Parameters : DnsResourceDataNextDomainSecure3Base, IEquatable<DnsResourceDataNextDomainSecure3Parameters>
{
public DnsResourceDataNextDomainSecure3Parameters(DnsSecNSec3HashAlgorithm hashAlgorithm, DnsSecNSec3Flags flags, ushort iterations, DataSegment salt)
: base(hashAlgorithm, flags, iterations, salt)
{
}
public bool Equals(DnsResourceDataNextDomainSecure3Parameters other)
{
return EqualsParameters(other);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNextDomainSecure3Parameters);
}
internal DnsResourceDataNextDomainSecure3Parameters()
: this(DnsSecNSec3HashAlgorithm.Sha1, DnsSecNSec3Flags.None, 0, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ParametersLength;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
WriteParameters(buffer, offset);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
DnsSecNSec3HashAlgorithm hashAlgorithm;
DnsSecNSec3Flags flags;
ushort iterations;
DataSegment salt;
if (!TryReadParameters(data, out hashAlgorithm, out flags, out iterations, out salt))
return null;
if (data.Length != GetParametersLength(salt.Length))
return null;
return new DnsResourceDataNextDomainSecure3Parameters(hashAlgorithm, flags, iterations, salt);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsResourceDataNoCompression : DnsResourceData
{
internal sealed override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return GetLength();
}
internal sealed override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
return WriteData(buffer, dnsOffset + offsetInDns);
}
internal abstract int GetLength();
internal abstract int WriteData(byte[] buffer, int offset);
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 2671.
/// <pre>
/// 0 Or more of:
/// +-----+---------------+
/// | bit | 0-15 |
/// +-----+---------------+
/// | 0 | OPTION-CODE |
/// +-----+---------------+
/// | 16 | OPTION-LENGTH |
/// +-----+---------------+
/// | 32 | OPTION-DATA |
/// | ... | |
/// +-----+---------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Opt)]
public sealed class DnsResourceDataOptions : DnsResourceDataSimple, IEquatable<DnsResourceDataOptions>
{
public DnsResourceDataOptions(DnsOptions options)
{
Options = options;
}
public DnsOptions Options { get; private set; }
public bool Equals(DnsResourceDataOptions other)
{
return other != null &&
Options.Equals(other.Options);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataOptions);
}
internal DnsResourceDataOptions()
: this(DnsOptions.None)
{
}
internal override int GetLength()
{
return Options.NumBytes;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
Options.Write(buffer, offset);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
DnsOptions options = DnsOptions.Read(data);
if (options == null)
return null;
return new DnsResourceDataOptions(options);
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// Reid.
/// <pre>
/// +-----+-------+----------+-----------+
/// | bit | 0-15 | 16-23 | 24-31 |
/// +-----+-------+----------+-----------+
/// | 0 | flags | protocol | algorithm |
/// +-----+-------+----------+-----------+
/// | 32 | public key |
/// | ... | |
/// +-----+------------------------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.RKey)]
public sealed class DnsResourceDataRKey : DnsResourceDataSimple, IEquatable<DnsResourceDataRKey>
{
private static class Offset
{
public const int Flags = 0;
public const int Protocol = Flags + sizeof(ushort);
public const int Algorithm = Protocol + sizeof(byte);
public const int PublicKey = Algorithm + sizeof(byte);
}
private const int ConstantPartLength = Offset.PublicKey;
public DnsResourceDataRKey(ushort flags, byte protocol, DnsAlgorithm algorithm, DataSegment publicKey)
{
Flags = flags;
Protocol = protocol;
Algorithm = algorithm;
PublicKey = publicKey;
}
/// <summary>
/// Reserved and must be zero.
/// </summary>
public ushort Flags { get; private set; }
/// <summary>
/// Must be set to 1.
/// </summary>
public byte Protocol { get; private set; }
/// <summary>
/// The key algorithm parallel to the same field for the SIG resource.
/// </summary>
public DnsAlgorithm Algorithm { get; private set; }
/// <summary>
/// The public key value.
/// </summary>
public DataSegment PublicKey { get; private set; }
public bool Equals(DnsResourceDataRKey other)
{
return other != null &&
Flags.Equals(other.Flags) &&
Protocol.Equals(other.Protocol) &&
Algorithm.Equals(other.Algorithm) &&
PublicKey.Equals(other.PublicKey);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataRKey);
}
internal DnsResourceDataRKey()
: this(0, 1, DnsAlgorithm.None, DataSegment.Empty)
{
}
internal override int GetLength()
{
return ConstantPartLength + PublicKey.Length;
}
internal override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset + Offset.Flags, Flags, Endianity.Big);
buffer.Write(offset + Offset.Protocol, Protocol);
buffer.Write(offset + Offset.Algorithm, (byte)Algorithm);
PublicKey.Write(buffer, offset + Offset.PublicKey);
}
internal override DnsResourceData CreateInstance(DataSegment data)
{
if (data.Length < ConstantPartLength)
return null;
ushort flags = data.ReadUShort(Offset.Flags, Endianity.Big);
byte protocol = data[Offset.Protocol];
DnsAlgorithm algorithm = (DnsAlgorithm)data[Offset.Algorithm];
DataSegment publicKey = data.SubSegment(Offset.PublicKey, data.Length - ConstantPartLength);
return new DnsResourceDataRKey(flags, protocol, algorithm, publicKey);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// <pre>
/// +------------+
/// | mbox-dname |
/// +------------+
/// | txt-dname |
/// +------------+
/// </pre>
/// </summary>
[DnsTypeRegistration(Type = DnsType.Rp)]
public sealed class DnsResourceDataResponsiblePerson : DnsResourceData2DomainNames
{
public DnsResourceDataResponsiblePerson(DnsDomainName mailBox, DnsDomainName textDomain)
: base(mailBox, textDomain)
{
}
/// <summary>
/// A domain name that specifies the mailbox for the responsible person.
/// Its format in master files uses the DNS convention for mailbox encoding, identical to that used for the RNAME mailbox field in the SOA RR.
/// The root domain name (just ".") may be specified for MailBox to indicate that no mailbox is available.
/// </summary>
public DnsDomainName MailBox { get { return First; } }
/// <summary>
/// A domain name for which TXT RR's exist.
/// A subsequent query can be performed to retrieve the associated TXT resource records at TextDomain.
/// This provides a level of indirection so that the entity can be referred to from multiple places in the DNS.
/// The root domain name (just ".") may be specified for TextDomain to indicate that the TXT_DNAME is absent, and no associated TXT RR exists.
/// </summary>
public DnsDomainName TextDomain { get { return Second; } }
internal DnsResourceDataResponsiblePerson()
: this(DnsDomainName.Root, DnsDomainName.Root)
{
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
DnsDomainName mailBox;
DnsDomainName textDomain;
if (!TryRead(out mailBox, out textDomain, dns, offsetInDns, length))
return null;
return new DnsResourceDataResponsiblePerson(mailBox, textDomain);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsResourceDataSimple : DnsResourceDataNoCompression
{
internal sealed override int WriteData(byte[] buffer, int offset)
{
WriteDataSimple(buffer, offset);
return GetLength();
}
internal abstract void WriteDataSimple(byte[] buffer, int offset);
internal sealed override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
return CreateInstance(dns.SubSegment(offsetInDns, length));
}
internal abstract DnsResourceData CreateInstance(DataSegment data);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment