Indented.Net.Dns.psm1
using namespace System.Management.Automation using namespace System.Collections.Generic using namespace System.Globalization using namespace System.IO using namespace System.Text using namespace Indented.IO using namespace Indented.Net.Dns using namespace System.Net.Sockets using namespace System.Collections using namespace System.Diagnostics using namespace System.Net using namespace System.Net.NetworkInformation #Region '.\enum\AFSDBSubType.ps1' 0 enum AFSDBSubType { AFSv3Loc = 1 # Andrews File Service v3.0 Location Service [RFC1183] DCENCARoot = 2 # DCE/NCA root cell directory node [RFC1183] } #EndRegion '.\enum\AFSDBSubType.ps1' 5 #Region '.\enum\AMTRelayType.ps1' 0 enum AMTRelayType { None IPv4 IPv6 DomainName } #EndRegion '.\enum\AMTRelayType.ps1' 7 #Region '.\enum\ATMAFormat.ps1' 0 enum ATMAFormat { AESA = 0 # ATM End System Address E164 = 1 # E.164 address format NSAP = 2 # Network Service Access Protocol (NSAP) address model } #EndRegion '.\enum\ATMAFormat.ps1' 6 #Region '.\enum\CAAFlag.ps1' 0 enum CAAFlag { None IssuerCritical = 128 } #EndRegion '.\enum\CAAFlag.ps1' 5 #Region '.\enum\CacheResourceType.ps1' 0 enum CacheResourceType { Hint = 1 Address } #EndRegion '.\enum\CacheResourceType.ps1' 5 #Region '.\enum\CertificateType.ps1' 0 enum CertificateType { PKIX = 1 # X.509 as per PKIX SPKI = 2 # SPKI certificate PGP = 3 # OpenPGP packet IPKIX = 4 # The URL of an X.509 data object ISPKI = 5 # The URL of an SPKI certificate IPGP = 6 # The fingerprint and URL of an OpenPGP packet ACPKIX = 7 # Attribute Certificate IACPKIX = 8 # The URL of an Attribute Certificate URI = 253 # URI private OID = 254 # OID private Experimental = 65534 Reserved = 65535 } #EndRegion '.\enum\CertificateType.ps1' 15 #Region '.\enum\CertificateUsage.ps1' 0 enum CertificateUsage { CAConstraint ServiceCertificateConstraint TrustAnchorAssertion DomainIssuedCertificate } #EndRegion '.\enum\CertificateUsage.ps1' 7 #Region '.\enum\CSYNCFlags.ps1' 0 enum CSYNCFlags { None Immediate Soaminimum } #EndRegion '.\enum\CSYNCFlags.ps1' 6 #Region '.\enum\DigestType.ps1' 0 enum DigestType { SHA1 = 1 # MANDATORY [RFC3658] SHA256 = 2 # MANDATORY [RFC4059] GOST = 3 # OPTIONAL [RFC5933] SHA384 = 4 # OPTIONAL [RFC6605] } #EndRegion '.\enum\DigestType.ps1' 7 #Region '.\enum\DistanceType.ps1' 0 enum DistanceType { Latitude = 1 Longitude } #EndRegion '.\enum\DistanceType.ps1' 5 #Region '.\enum\DOALocation.ps1' 0 enum DOALocation { Reserved Local Uri Hdl } #EndRegion '.\enum\DOALocation.ps1' 7 #Region '.\enum\DOAType.ps1' 0 enum DOAType { Reserved ContactEmail ContactWebsite ContactTelephone PublicKey = 100 } #EndRegion '.\enum\DOAType.ps1' 8 #Region '.\enum\EDnsDNSSECOK.ps1' 0 [Flags()] enum EDnsDNSSECOK { NONE = 0 DO = 32768 # DNSSEC answer OK [RFC4035][RFC3225] } #EndRegion '.\enum\EDnsDNSSECOK.ps1' 6 #Region '.\enum\EDnsOptionCode.ps1' 0 enum EDnsOptionCode { LLQ = 1 # On-hold [http://files.dns-sd.org/draft-sekar-dns-llq.txt] UL = 2 # On-hold [http://files.dns-sd.org/draft-sekar-dns-ul.txt] NSID = 3 # Standard [RFC5001] DAU = 5 # Standard [RFC6975] DHU = 6 # Standard [RFC6975] N3U = 7 # Standard [RFC6975] EDNSClientSubnet = 8 # Optional [draft-vandergaast-edns-client-subnet][Wilmer_van_der_Gaast] } #EndRegion '.\enum\EDnsOptionCode.ps1' 10 #Region '.\enum\EncryptionAlgorithm.ps1' 0 enum EncryptionAlgorithm { RSAMD5 = 1 # RSA/MD5 (deprecated see 5) [RFC3110][RFC4034] DH = 2 # Diffie-Hellman [RFC2539] DSA = 3 # DSA/SHA1 [RFC3755] RSASHA1 = 5 # RSA/SHA-1 [RFC3110][RFC4034] DSANSEC3SHA1 = 6 # DSA-NSEC3-SHA1 [RFC5155] RSASHA1NSEC3SHA1 = 7 # RSASHA1-NSEC3-SHA1 [RFC5155] RSASHA256 = 8 # RSA/SHA-256 [RFC5702] RSASHA512 = 10 # RSA/SHA-512 [RFC5702] ECCGOST = 12 # GOST R 34.10-2001 [RFC5933] ECDSAP256SHA256 = 13 # ECDSA Curve P-256 with SHA-256 [RFC6605] ECDSAP384SHA384 = 14 # ECDSA Curve P-384 with SHA-384 [RFC6605] INDIRECT = 252 # Reserved for indirect keys [RFC4034] PRIVATEDNS = 253 # Private algorithm [RFC4034] PRIVATEOID = 254 # Private algorithm OID [RFC4034] } #EndRegion '.\enum\EncryptionAlgorithm.ps1' 17 #Region '.\enum\HeaderFlags.ps1' 0 [Flags()] enum HeaderFlags { None = 0 AA = 1024 # Authoritative Answer [RFC1035] TC = 512 # Truncated Response [RFC1035] RD = 256 # Recursion Desired [RFC1035] RA = 128 # Recursion Allowed [RFC1035] AD = 32 # Authenticated Data [RFC4035] CD = 16 # Checking Disabled [RFC4035] } #EndRegion '.\enum\HeaderFlags.ps1' 11 #Region '.\enum\IanaAddressFamily.ps1' 0 enum IanaAddressFamily { IPv4 = 1 # IP version 4 IPv6 = 2 # IP version 6 NSAP = 3 # NSAP HDLC = 4 # HDLC (8-bit multidrop) BBN = 5 # BBN 1822 IEEE802 = 6 # 802 (includes all 802 media plus Ethernet "canonical format") E163 = 7 # E.163 E164 = 8 # E.164 (SMDS Frame Relay ATM) F69 = 9 # F.69 (Telex) X121 = 10 # X.121 (X.25 Frame Relay) IPX = 11 # IPX Appletalk = 12 # Appletalk DecNetIV = 13 # DecNet IV BanyanVines = 14 # Banyan Vines E164NSAP = 15 # E.164 with NSAP format subaddress [ATM Forum UNI 3.1. October 1995.][Andy_Malis] DNS = 16 # DNS (Domain Name System) DistinguishedName = 17 # Distinguished Name [Charles_Lynn] ASNumber = 18 # AS Number [Charles_Lynn] XTPOverIpv4 = 19 # XTP over IP version 4 [Mike_Saul] XTPOverIPv6 = 20 # XTP over IP version 6 [Mike_Saul] XTPNativeMode = 21 # XTP native mode XTP [Mike_Saul] FibreChannelWWPortName = 22 # Fibre Channel World-Wide Port Name [Mark_Bakke] FibreChannelWWNodeName = 23 # Fibre Channel World-Wide Node Name [Mark_Bakke] GWID = 24 # GWID [Subra_Hegde] AFIForL2VPN = 25 # AFI for L2VPN information [RFC4761][RFC6074] MPLSTPSectionID = 26 # MPLS-TP Section Endpoint Identifier [RFC-ietf-mpls-gach-adv-08] MPLSTPLSPID = 27 # MPLS-TP LSP Endpoint Identifier [RFC-ietf-mpls-gach-adv-08] MPLSTPPseudowireID = 28 # MPLS-TP Pseudowire Endpoint Identifier [RFC-ietf-mpls-gach-adv-08] EIGRPCommon = 16384 # EIGRP Common Service Family [Donnie_Savage] EIGRPIPv4 = 16385 # EIGRP IPv4 Service Family [Donnie_Savage] EIGRPIPv6 = 16386 # EIGRP IPv6 Service Family [Donnie_Savage] LCAF = 16387 # LISP Canonical Address Format (LCAF) [David_Meyer] BGPLS = 16388 # BGP-LS [draft-ietf-idr-ls-distribution] MAC48bit = 16389 # 48-bit MAC [RFC-eastlake-rfc5342bis-05] MAC64bit = 16390 # 64-bit MAC [RFC-eastlake-rfc5342bis-05] OUI = 16391 # OUI [draft-eastlake-trill-ia-appsubtlv] MAC24 = 16392 # MAC/24 [draft-eastlake-trill-ia-appsubtlv] MAC40 = 16393 # MAC/40 [draft-eastlake-trill-ia-appsubtlv] IPv664 = 16394 # IPv6/64 [draft-eastlake-trill-ia-appsubtlv] RBridgePortID = 16395 # RBridge Port ID [draft-eastlake-trill-ia-appsubtlv] } #EndRegion '.\enum\IanaAddressFamily.ps1' 43 #Region '.\enum\IPSECAlgorithm.ps1' 0 enum IPSECAlgorithm { DSA = 1 # [RFC4025] RSA = 2 # [RFC4025] } #EndRegion '.\enum\IPSECAlgorithm.ps1' 5 #Region '.\enum\IPSECGatewayType.ps1' 0 enum IPSECGatewayType { NoGateway = 0 # No gateway is present [RFC4025] IPv4 = 1 # A 4-byte IPv4 address is present [RFC4025] IPv6 = 2 # A 16-byte IPv6 address is present [RFC4025] DomainName = 3 # A wire-encoded domain name is present [RFC4025] } #EndRegion '.\enum\IPSECGatewayType.ps1' 7 #Region '.\enum\KEYAC.ps1' 0 enum KEYAC { AuthAndConfPermitted = 0 # Use of the key for authentication and/or confidentiality is permitted. AuthProhibited = 2 # Use of the key is prohibited for authentication. ConfProhibited = 1 # Use of the key is prohibited for confidentiality. NoKey = 3 # No key information } #EndRegion '.\enum\KEYAC.ps1' 7 #Region '.\enum\KEYNameType.ps1' 0 enum KEYNameType { UserKey = 0 # Indicates that this is a key associated with a "user" or "account" at an end entity usually a host. ZoneKey = 1 # Indicates that this is a zone key for the zone whose name is the KEY RR owner name. NonZone = 2 # Indicates that this is a key associated with the non-zone "entity" whose name is the RR owner name. Reserved = 3 # Reserved } #EndRegion '.\enum\KEYNameType.ps1' 7 #Region '.\enum\KEYProtocol.ps1' 0 enum KEYProtocol { Reserved = 0 TLS = 1 EMmail = 2 DNSSEC = 3 IPSEC = 4 All = 255 } #EndRegion '.\enum\KEYProtocol.ps1' 9 #Region '.\enum\LLQErrorCode.ps1' 0 enum LLQErrorCode { NoError = 0 ServFull = 1 Static = 2 FormatErr = 3 NoSuchLLQ = 4 BadVers = 5 UnknownErr = 6 } #EndRegion '.\enum\LLQErrorCode.ps1' 10 #Region '.\enum\LLQOpCode.ps1' 0 enum LLQOpCode { LLQSetup = 1 LLQRefresh = 2 LLQEvent = 3 } #EndRegion '.\enum\LLQOpCode.ps1' 6 #Region '.\enum\MatchingType.ps1' 0 enum MatchingType { NoHashUsed Sha256 Sha512 } #EndRegion '.\enum\MatchingType.ps1' 6 #Region '.\enum\MessageCompression.ps1' 0 enum MessageCompression { Enabled = 192 Disabled = 0 } #EndRegion '.\enum\MessageCompression.ps1' 5 #Region '.\enum\MSDNSOption.ps1' 0 enum MSDNSOption { Query = 0 # [RFC1035] IQuery = 1 # [RFC3425] Status = 2 # [RFC1035] Notify = 4 # [RFC1996] Update = 5 # [RFC2136] } #EndRegion '.\enum\MSDNSOption.ps1' 8 #Region '.\enum\NSEC3Flags.ps1' 0 enum NSEC3Flags { OptOut = 1 # [RFC5155] } #EndRegion '.\enum\NSEC3Flags.ps1' 4 #Region '.\enum\NSEC3HashAlgorithm.ps1' 0 enum NSEC3HashAlgorithm { SHA1 = 1 # [RFC5155] } #EndRegion '.\enum\NSEC3HashAlgorithm.ps1' 4 #Region '.\enum\OpCode.ps1' 0 enum OpCode { Query = 0 # [RFC1035] IQuery = 1 # [RFC3425] Status = 2 # [RFC1035] Notify = 4 # [RFC1996] Update = 5 # [RFC2136] } #EndRegion '.\enum\OpCode.ps1' 8 #Region '.\enum\QR.ps1' 0 enum QR { Query = 0 Response = 32768 } #EndRegion '.\enum\QR.ps1' 5 #Region '.\enum\RCode.ps1' 0 enum RCode { NoError = 0 # No Error [RFC1035] FormErr = 1 # Format Error [RFC1035] ServFail = 2 # Server Failure [RFC1035] NXDomain = 3 # Non-Existent Domain [RFC1035] NotImp = 4 # Not Implemented [RFC1035] Refused = 5 # Query Refused [RFC1035] YXDomain = 6 # Name Exists when it should not [RFC2136] YXRRSet = 7 # RR Set Exists when it should not [RFC2136] NXRRSet = 8 # RR Set that should exist does not [RFC2136] NotAuth = 9 # Server Not Authoritative for zone [RFC2136] NotZone = 10 # Name not contained in zone [RFC2136] BadVers = 16 # Bad OPT Version [RFC2671] BadSig = 16 # TSIG Signature Failure [RFC2845] BadKey = 17 # Key not recognized [RFC2845] BadTime = 18 # Signature out of time window [RFC2845] BadMode = 19 # Bad TKEY Mode [RFC2930] BadName = 20 # Duplicate key name [RFC2930] BadAlg = 21 # Algorithm not supported [RFC2930] BadTrunc = 22 # Bad Truncation [RFC4635] } #EndRegion '.\enum\RCode.ps1' 22 #Region '.\enum\RecordClass.ps1' 0 enum RecordClass { IN = 1 # [RFC1035] CH = 3 # [Moon1981] HS = 4 # [Dyer1987] NONE = 254 # [RFC2136] ANY = 255 # [RFC1035] } #EndRegion '.\enum\RecordClass.ps1' 8 #Region '.\enum\RecordType.ps1' 0 enum RecordType { EMPTY = 0 # an empty record [RFC1034] [MS DNS] A = 1 # a host address [RFC1035] NS = 2 # an authoritative name server [RFC1035] MD = 3 # a mail destination (Obsolete - use MX) [RFC1035] MF = 4 # a mail forwarder (Obsolete - use MX) [RFC1035] CNAME = 5 # the canonical name for an alias [RFC1035] SOA = 6 # marks the start of a zone of authority [RFC1035] MB = 7 # a mailbox domain name (EXPERIMENTAL) [RFC1035] MG = 8 # a mail group member (EXPERIMENTAL) [RFC1035] MR = 9 # a mail rename domain name (EXPERIMENTAL) [RFC1035] NULL = 10 # a null RR (EXPERIMENTAL) [RFC1035] WKS = 11 # a well known service description [RFC1035] PTR = 12 # a domain name pointer [RFC1035] HINFO = 13 # host information [RFC1035] MINFO = 14 # mailbox or mail list information [RFC1035] MX = 15 # mail exchange [RFC1035] TXT = 16 # text strings [RFC1035] RP = 17 # for Responsible Person [RFC1183] AFSDB = 18 # for AFS Data Base location [RFC1183] X25 = 19 # for X.25 PSDN address [RFC1183] ISDN = 20 # for ISDN address [RFC1183] RT = 21 # for Route Through [RFC1183] NSAP = 22 # for NSAP address NSAP style A record [RFC1706] NSAPPTR = 23 # for domain name pointer NSAP style [RFC1348] SIG = 24 # for security signature [RFC4034][RFC3755][RFC2535] KEY = 25 # for security key [RFC4034][RFC3755][RFC2535] PX = 26 # X.400 mail mapping information [RFC2163] GPOS = 27 # Geographical Position [RFC1712] AAAA = 28 # IP6 Address [RFC3596] LOC = 29 # Location Information [RFC1876] NXT = 30 # Next Domain - OBSOLETE [RFC3755][RFC2535] EID = 31 # Endpoint Identifier [Patton] NIMLOC = 32 # Nimrod Locator [Patton] SRV = 33 # Server Selection [RFC2782] ATMA = 34 # ATM Address [ATMDOC] NAPTR = 35 # Naming Authority Pointer [RFC2915][RFC2168] KX = 36 # Key Exchanger [RFC2230] CERT = 37 # CERT [RFC4398] A6 = 38 # A6 (Experimental) [RFC3226][RFC2874] DNAME = 39 # DNAME [RFC2672] SINK = 40 # SINK [Eastlake] OPT = 41 # OPT [RFC2671] APL = 42 # APL [RFC3123] DS = 43 # Delegation Signer [RFC4034][RFC3658] SSHFP = 44 # SSH Key Fingerprint [RFC4255] IPSECKEY = 45 # IPSECKEY [RFC4025] RRSIG = 46 # RRSIG [RFC4034][RFC3755] NSEC = 47 # NSEC [RFC4034][RFC3755] DNSKEY = 48 # DNSKEY [RFC4034][RFC3755] DHCID = 49 # DHCID [RFC4701] NSEC3 = 50 # NSEC3 [RFC5155] NSEC3PARAM = 51 # NSEC3PARAM [RFC5155] TLSA = 52 # Transport Layer Security [RFC6698] SMIMEA = 53 # S/MIME Certificate [RFC8162] HIP = 55 # Host Identity Protocol [RFC5205] NINFO = 56 # NINFO [Reid] RKEY = 57 # RKEY [Reid] TALINK = 58 # [Wouter_Wijngaards] CDS = 59 # Child DS [RFC7344] CDNSKEY = 60 # DNS key to reflect in DS [RFC7344] OPENPGPKEY = 61 # OpenPGP Key [RFC7929] CSYNC = 62 # Child-to-Parent Synchronization [RFC7477] ZONEMD = 63 # Synchronization message digest [draft-wessels-dns-zone-digest] SPF = 99 # [RFC4408] UINFO = 100 # [IANA-Reserved] UID = 101 # [IANA-Reserved] GID = 102 # [IANA-Reserved] UNSPEC = 103 # [IANA-Reserved] NID = 104 # [RFC6742] L32 = 105 # [RFC6742] L64 = 106 # [RFC6742] LP = 107 # [RFC6742] EUI48 = 108 # EUI-48 address [RFC7043] EUI64 = 109 # EUI-64 address [RFC7043] TKEY = 249 # Transaction Key [RFC2930] TSIG = 250 # Transaction Signature [RFC2845] IXFR = 251 # incremental transfer [RFC1995] AXFR = 252 # transfer of an entire zone [RFC1035] MAILB = 253 # mailbox-related RRs (MB MG or MR) [RFC1035] MAILA = 254 # mail agent RRs (Obsolete - see MX) [RFC1035] ANY = 255 # A request for all records (*) [RFC1035] URI = 256 # URI [RFC7553] CAA = 257 # Certification Authority Restriction [RFC6844] AVC = 258 # Visibility and Control [AVC/avc-completed-template] DOA = 259 # Digital Object Architecture [DOA/doa-completed-template] AMTRELAY = 260 # Multicast Tunnelling Relay [draft-ietf-mboned-driad-amt-discovery] TA = 32768 # DNSSEC Trust Authorities [Weiler] 2005-12-13 DLV = 32769 # DNSSEC Lookaside Validation [RFC4431] WINS = 65281 # WINS records (WINS Lookup record) [MS DNS] WINSR = 65282 # WINSR records (WINS Reverse Lookup record) [MS DNS] UNKNOWN = 65535 # Non-standard, implemented for this module. } #EndRegion '.\enum\RecordType.ps1' 94 #Region '.\enum\Selector.ps1' 0 enum Selector { FullCertificate SubjectPublicKeyInfo } #EndRegion '.\enum\Selector.ps1' 5 #Region '.\enum\SINKCoding.ps1' 0 enum SINKCoding { Reserved = 0 SNMPASN1 = 1 OSIASN11990 = 2 OSIASN11994 = 3 PrivateAbstract = 63 DNSRR = 64 MIME = 65 TextTagged = 66 PrivateFormat = 254 } #EndRegion '.\enum\SINKCoding.ps1' 12 #Region '.\enum\SINKMIMESubCoding.ps1' 0 enum SINKMIMESubCoding { SevenBit = 1 EightBit = 2 Binary = 3 QuotedPrintable = 4 Base64 = 5 Private = 254 } #EndRegion '.\enum\SINKMIMESubCoding.ps1' 9 #Region '.\enum\SINKPrivateAbstractSubCoding.ps1' 0 enum SINKSubCoding { Reserved = 0 BER = 1 DER = 2 PER = 3 PERUnaligned = 4 CER = 5 } #EndRegion '.\enum\SINKPrivateAbstractSubCoding.ps1' 9 #Region '.\enum\SINKTextSubCoding.ps1' 0 enum SINKTextSubCoding { ASCII = 1 UTF7 = 2 UTF8 = 3 ASCIIWithMIMEHeader = 4 Private = 254 } #EndRegion '.\enum\SINKTextSubCoding.ps1' 8 #Region '.\enum\SSHAlgorithm.ps1' 0 enum SSHAlgorithm { RSA = 1 # [RFC4255] DSS = 2 # [RFC4255] ECDSA = 3 # [RFC6594] ED25519 = 4 # [RFC7479] } #EndRegion '.\enum\SSHAlgorithm.ps1' 7 #Region '.\enum\SSHFPType.ps1' 0 enum SSHFPType { SHA1 = 1 # [RFC4255] SHA256 = 2 # [RFC6594] } #EndRegion '.\enum\SSHFPType.ps1' 5 #Region '.\enum\TKEYMode.ps1' 0 enum TKEYMode { ServerAssignment = 1 # Server assignment [RFC2930] DH = 2 # Diffie-Hellman Exchange [RFC2930] GSSAPI = 3 # GSS-API negotiation [RFC2930] ResolverAssignment = 4 # Resolver assignment [RFC2930] KeyDeletion = 5 # Key deletion [RFC2930] } #EndRegion '.\enum\TKEYMode.ps1' 8 #Region '.\enum\WINSMappingFlag.ps1' 0 enum WINSMappingFlag { Replicated = 0 LocalOnly = 65536 } #EndRegion '.\enum\WINSMappingFlag.ps1' 5 #Region '.\enum\ZONEMDDigestType.ps1' 0 enum ZONEMDDigestType { SHA384 = 1 } #EndRegion '.\enum\ZONEMDDigestType.ps1' 4 #Region '.\class\TransformDnsName.ps1' 0 #using namespace System.Management.Automation class TransformDnsName : ArgumentTransformationAttribute { [Object] Transform( [EngineIntrinsics] $engineIntrinsics, [Object] $inputData ) { $name = $inputData.ToString() if ($name -eq '.') { return $name } try { return [System.Globalization.IdnMapping]::new().GetAscii($name) } catch { return $name } } } #EndRegion '.\class\TransformDnsName.ps1' 21 #Region '.\class\ValidateDnsName.ps1' 0 #using namespace System.Management.Automation class ValidateDnsName : ValidateEnumeratedArgumentsAttribute { Hidden $nameRegex = '^([A-Z0-9]|_[A-Z])(([\w\-]{0,61})[^_\-])?(\.([A-Z0-9]|_[A-Z])(([\w\-]{0,61})[^_\-])?)*$|^\.$' ValidateDnsName() { } [void] ValidateElement( [Object]$element ) { if (-not ([IPAddress]::TryParse($element, [ref]$null)) -and $element -notmatch $this.nameRegex) { $errorRecord = [ErrorRecord]::new( [ArgumentException]::new('Invalid name format'), 'InvalidDnsName', [ErrorCategory]::InvalidArgument, $element ) throw $errorRecord } } } #EndRegion '.\class\ValidateDnsName.ps1' 22 #Region '.\class\0.Top\AngularDistance.ps1' 0 class AngularDistance { [Int64] $Degrees [Int64] $Minutes [Decimal] $Seconds [string] $Direction hidden static [Int64] $Equator = 2147483648 hidden static [Int64] $PrimeMeridian = 2147483648 AngularDistance([UInt32]$value, [DistanceType]$distanceType) { $this.Direction = switch ($distanceType) { 'Latitude' { ('S', 'N')[$value -gt [AngularDistance]::Equator] } 'Longitude' { ('W', 'E')[$value -gt [AngularDistance]::PrimeMeridian] } } $value = [Math]::Abs($value - 2147483648) $remainder = $value % (1000 * 60 * 60) $this.Degrees = ($value - $remainder) / (1000 * 60 * 60) $value = $remainder $remainder = $value % (1000 * 60) $this.Minutes = ($value - $remainder) / (1000 * 60) $value = $remainder $this.Seconds = $value / 1000 } [UInt32] ToUInt32() { $value = ( ($this.Seconds * 1000) + ($this.Minutes * 1000 * 60) + ($this.Degrees * 1000 * 60 * 60) ) if ($this.Direction -in 'N', 'E') { $value = 2147483648 + $value } else { $value = 2147483648 - $value } return $value } [string] ToString() { return '{0} {1} {2:N3} {3}' -f @( $this.Degrees $this.Minutes $this.Seconds $this.Direction ) } [string] ToLongString() { return '{0} degrees {1} minutes {2:N3} seconds {3}' -f @( $this.Degrees $this.Minutes $this.Seconds $this.Direction ) } } #EndRegion '.\class\0.Top\AngularDistance.ps1' 67 #Region '.\class\0.Top\DnsRecordType.ps1' 0 class DnsRecordType : IComparable, IEquatable[Object] { [string] $Name [UInt16] $TypeID DnsRecordType( [RecordType] $value ) { if ($value -eq 'NSAPPTR') { $this.Name = 'NSAP-PTR' } else { $this.Name = $value } $this.TypeId = $value } DnsRecordType( [string] $value ) { if ($value -eq 'NSAPPTR') { $this.Name = 'NSAP-PTR' } else { $this.Name = $value } $value = $value.ToUpper().Trim() if ($value -eq 'NSAP-PTR') { $this.TypeID = 23 } elseif ([RecordType].IsEnumDefined($value)) { $this.TypeID = [RecordType]$value } elseif ($value -match '^TYPE(\d+)$') { $this.TypeID = $matches[1] } else { throw 'Unable to parse record type to a type ID' } } DnsRecordType( [int] $value ) { $this.TypeID = $value if ([RecordType].IsEnumDefined($value)) { if ($value -eq 23) { $this.Name = 'NSAP-PTR' } else { $this.Name = [RecordType]$value } } else { $this.Name = 'TYPE{0}' -f $value } } hidden static [UInt16] op_Implicit([DnsRecordType] $dnsRecordType) { return [int]$dnsRecordType.TypeID } # Hack to support more than one cast hidden static [RecordType] op_Implicit([Object] $dnsRecordType) { return [RecordType]$dnsRecordType.TypeID } [int] CompareTo( [Object] $object ) { [UInt16]$uint16 = 0 if ($object -is [DnsRecordType]) { return $this.TypeID.CompareTo($object.TypeID) } elseif ($object -is [RecordType]) { return $this.TypeID.CompareTo([UInt16]$object) } elseif ([int]::TryParse($object, [ref]$uint16)) { return $this.TypeID.CompareTo($uint16) } elseif ($object -is [string]) { try { return $this.TypeID.CompareTo(([DnsRecordType]$object).TypeID) } catch { throw 'Invalid record type' } } else { throw 'Invalid comparison' } } [bool] Equals( [Object] $object ) { return $this.CompareTo($object) -eq 0 } [string] ToString() { return $this.Name } } #EndRegion '.\class\0.Top\DnsRecordType.ps1' 93 #Region '.\class\0.Top\EndianBinaryReader.ps1' 0 #using namespace System.Collections.Generic #using namespace System.Globalization #using namespace System.IO #using namespace System.Text class EndianBinaryReader : BinaryReader { [bool] $ConvertIdnToUnicode = $true hidden [IdnMapping] $idnMapping = [IdnMapping]::new() EndianBinaryReader([Stream]$BaseStream) : base($BaseStream) { } [UInt16] ReadUInt16( [bool] $isBigEndian ) { if ($isBigEndian) { return [UInt16](([UInt16]$this.ReadByte() -shl 8) -bor $this.ReadByte()) } else { return $this.ReadUInt16() } } [UInt32] ReadUInt32( [bool] $isBigEndian ) { if ($isBigEndian) { return [UInt32]( ([UInt32]$this.ReadByte() -shl 24) -bor ([UInt32]$this.ReadByte() -shl 16) -bor ([UInt32]$this.ReadByte() -shl 8) -bor $this.ReadByte()) } else { return $this.ReadUInt32() } } [UInt64] ReadUInt48() { return $this.ReadUInt48($false) } [UInt64] ReadUInt48( [bool] $isBigEndian ) { if ($isBigEndian) { return [UInt64]( ([UInt64]$this.ReadByte() -shl 40) -bor ([UInt64]$this.ReadByte() -shl 32) -bor ([UInt64]$this.ReadByte() -shl 24) -bor ([UInt64]$this.ReadByte() -shl 16) -bor ([UInt64]$this.ReadByte() -shl 8) -bor $this.ReadByte()) } else { return [UInt64]($this.ReadByte() -bor ([UInt64]$this.ReadByte() -shl 8) -bor ([UInt64]$this.ReadByte() -shl 16) -bor ([UInt64]$this.ReadByte() -shl 24) -bor ([UInt64]$this.ReadByte() -shl 32) -bor ([UInt64]$this.ReadByte() -shl 40)) } } [UInt64] ReadUInt64( [bool] $isBigEndian ) { if ($isBigEndian) { return [UInt64]( ([UInt64]$this.ReadByte() -shl 56) -bor ([UInt64]$this.ReadByte() -shl 48) -bor ([UInt64]$this.ReadByte() -shl 40) -bor ([UInt64]$this.ReadByte() -shl 32) -bor ([UInt64]$this.ReadByte() -shl 24) -bor ([UInt64]$this.ReadByte() -shl 16) -bor ([UInt64]$this.ReadByte() -shl 8) -bor $this.ReadByte()) } else { return $this.ReadUInt64() } } [byte] PeekByte() { $value = $this.ReadByte() $this.BaseStream.Seek(-1, 'Current') return $value } [IPAddress] ReadIPAddress() { return [IPAddress]::new($this.ReadBytes(4)) } [IPAddress] ReadIPv6Address() { return [IPAddress]::new($this.ReadBytes(16)) } # http://www.ietf.org/rfc/rfc1035.txt [string] ReadDnsCharacterString() { $length = 0 return $this.ReadDnsCharacterString([ref]$length) } [string] ReadDnsCharacterString( [ref] $Length ) { [Char[]]$escapeChars = @( 92 34 ) [Char[]]$replaceChars = @( 10 13 ) $stringLength = $this.ReadByte() $Length.Value = $stringLength + 1 $string = [string]::new($this.ReadChars($stringLength)) foreach ($escapeChar in $escapeChars) { $string = $string.Replace([string]$escapeChar, ('\{0}' -f $escapeChar)) } foreach ($replaceChar in $replaceChars) { $string = $string.Replace([string]$replaceChar, ('\{0:000}' -f [Int]$replaceChar)) } return $string } [UInt16[]] ReadBitMap( [int] $length ) { [UInt16[]]$bits = while ($length -gt 0) { $windowNumber = $this.ReadByte() $bitMapLength = $this.ReadByte() $bytes = $this.ReadBytes($bitMapLength) $binaryString = [StringBuilder]::new() foreach ($byte in $bytes) { $null = $binaryString.Append( [Convert]::ToString($byte, 2).PadLeft(8, '0') ) } for ($i = 0; $i -lt $binaryString.Length; $i++) { if ($binaryString[$i] -eq '1') { $i + (256 * $windowNumber) } } $length -= 2 + $bitMapLength } return $bits } # DNS messages implement compression to avoid bloat by repeated use of labels. # # If a label occurs elsewhere in the message a flag is set and an offset recorded as follows: # # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ # | 1 1| OFFSET | # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ # # http://www.ietf.org/rfc/rfc1035.txt # [string] ReadDnsDomainName() { $name = [StringBuilder]::new() [UInt64]$CompressionStart = 0 if ($this.BaseStream.Position -eq $this.BaseStream.Length) { return '' } while ($this.PeekByte() -ne 0) { $length = $this.ReadByte() if (($length -band [MessageCompression]::Enabled) -eq [MessageCompression]::Enabled) { if ($compressionStart -eq 0) { $compressionStart = $this.BaseStream.Position } # Remove the compression flag bits to calculate the offset value (relative to the start of the message) [UInt16]$offset = ([UInt16]($length -bxor [MessageCompression]::Enabled) -shl 8) -bor $this.ReadByte() $null = $this.BaseStream.Seek($offset, 'Begin') } else { $null = $name.Append($this.ReadChars($length)).Append('.') } } if ($compressionStart -gt 0) { $null = $this.BaseStream.Seek($compressionStart, 'Begin') } $null = $this.ReadByte() if ($name[-1] -ne '.') { $null = $name.Append('.') } $name = $name.ToString() if ($this.ConvertIdnToUnicode) { if ($name -eq '.') { return $name } if ($name -match 'xn--') { try { return $this.idnMapping.GetUnicode($name) } catch { return $name } } else { return $name } } else { return $name } } [string] ReadDnsDomainName( [ref] $Length ) { $start = $this.BaseStream.Position $value = $this.ReadDnsDomainName() $end = $this.BaseStream.Position $Length.Value = $end - $start return $value } # RFC 1034: # # "Internally, programs that manipulate domain names should represent them # as sequences of labels, where each label is a length octet followed by # an octet string. Because all domain names end at the root, which has a # null string for a label, these internal representations can use a length # byte of zero to terminate a domain name." # # RFC 1035: # # "<domain-name> is a domain name represented as a series of labels, and # terminated by a label with zero length. <character-string> is a single # length octet followed by that number of characters. <character-string> # is treated as binary information, and can be up to 256 characters in # length (including the length octet)." # # http://www.ietf.org/rfc/rfc1034.txt # http://www.ietf.org/rfc/rfc1035.txt # static [byte[]] GetDnsDomainNameBytes( [string] $Name ) { # Drop any trailing . characters from the name. They are no longer necessary all names must be absolute by this point. $Name = $Name.TrimEnd('.') $bytes = [List[byte]]::new() if ($Name) { foreach ($label in $Name.Split('.')) { $bytes.Add($label.Length) $bytes.AddRange([byte[]][Char[]]$label) } } # Add a zero length root label $bytes.Add(0) return $bytes.ToArray() } } #EndRegion '.\class\0.Top\EndianBinaryReader.ps1' 265 #Region '.\class\0.Top\EndianBitConverter.ps1' 0 #using namespace System.Text class EndianBitConverter { static [byte[]] GetBytes( [UInt16] $value, [bool] $isBigEndian ) { if ([BitConverter]::IsLittleEndian -eq $isBigEndian) { return [BitConverter]::GetBytes( [IPAddress]::HostToNetworkOrder([int]$value) )[2, 3] } else { return [BitConverter]::GetBytes($value) } } static [byte[]] GetBytes( [UInt32] $value, [bool] $isBigEndian ) { if ([BitConverter]::IsLittleEndian -eq $isBigEndian) { return [BitConverter]::GetBytes( [IPAddress]::HostToNetworkOrder([Int64]$value) )[4..7] } else { return [BitConverter]::GetBytes($value) } } static [string] ToBinary( [byte[]] $bytes ) { $string = [StringBuilder]::new() foreach ($byte in $bytes) { $string.Append( [Convert]::ToString($byte, 2).PadLeft(8, '0') ) } return $string.ToString() } static [string] ToHexadecimal( [byte[]] $bytes ) { $string = [StringBuilder]::new() foreach ($byte in $bytes) { $string.AppendFormat('{0:X2}' -f $byte) } return $string.ToString() } static [string] ToBase32String( [byte[]] $bytes ) { $base32Characters = '0123456789ABCDEFGHIJKLMNOPQRSTUV' if ($bytes.Count -eq 0) { return '' } $binaryString = '' foreach ($byte in $bytes) { $binaryString += [Convert]::ToString($byte, 2).PadLeft(8, '0') } $chars = foreach ($value in $binaryString -split '(?<=\G.{5})') { if ($value) { $byte = [Convert]::ToByte($value.PadRight('0', 5), 2) $base32Characters[$byte] } } return [string]::new($chars) } } #EndRegion '.\class\0.Top\EndianBitConverter.ps1' 76 #Region '.\class\1.MessageParts\DnsHeader.ps1' 0 class DnsHeader { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [UInt16] $ID [QR] $QR [OpCode] $OpCode [HeaderFlags] $Flags [RCode] $RCode [UInt16] $QuestionCount [UInt16] $AnswerCount [UInt16] $AuthorityCount [UInt16] $AdditionalCount DnsHeader() { } DnsHeader( [EndianBinaryReader] $binaryReader ) { $this.ID = $binaryReader.ReadUInt16($true) $value = $binaryReader.ReadUInt16($true) $this.QR = $value -band 0x8000 $this.OpCode = ($value -band 0x7800) -shr 11 $this.Flags = $value -band 0x07B0 $this.RCode = $value -band 0x000F $this.QuestionCount = $binaryReader.ReadUInt16($true) $this.AnswerCount = $binaryReader.ReadUInt16($true) $this.AuthorityCount = $binaryReader.ReadUInt16($true) $this.AdditionalCount = $binaryReader.ReadUInt16($true) } DnsHeader( [bool] $recursionDesired, [UInt16] $questionCount ) { $this.ID = Get-Random -Minimum 0 -Maximum ([UInt16]::MaxValue + 1) if ($recursionDesired) { $this.Flags = [HeaderFlags]::RD } $this.QuestionCount = $questionCount } [byte[]] ToByteArray() { $bytes = [byte[]]::new(12) $bytes[0], $bytes[1] = [EndianBitConverter]::GetBytes($this.ID, $true) # QR, Flags, OpCode and RCode [UInt16]$value = ( $this.QR -bor ([UInt16]$this.OpCode -shl 11) -bor $this.Flags -bor $this.RCode ) $bytes[2], $bytes[3] = [EndianBitConverter]::GetBytes($value, $true) $bytes[4], $bytes[5] = [EndianBitConverter]::GetBytes($this.QuestionCount, $true) $bytes[6], $bytes[7] = [EndianBitConverter]::GetBytes($this.AnswerCount, $true) $bytes[8], $bytes[9] = [EndianBitConverter]::GetBytes($this.AuthorityCount, $true) $bytes[10], $bytes[11] = [EndianBitConverter]::GetBytes($this.AdditionalCount, $true) return $bytes } [string] ToString() { return 'ID: {0} OpCode: {1} RCode: {2} Flags: {3} Query: {4} Answer: {5} Authority: {6} Additional: {7}' -f @( $this.ID $this.OpCode.ToString().ToUpper() $this.RCode.ToString().ToUpper() $this.Flags.ToString().ToUpper() $this.QuestionCount $this.AnswerCount $this.AuthorityCount $this.AdditionalCount ) } } #EndRegion '.\class\1.MessageParts\DnsHeader.ps1' 96 #Region '.\class\1.MessageParts\DnsQuestion.ps1' 0 #using namespace System.Collections.Generic class DnsQuestion { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / QNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QCLASS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string] $Name [DnsRecordType] $RecordType [Object] $RecordClass DnsQuestion() { } DnsQuestion( [string] $recordName, [RecordType] $type, [RecordClass] $class ) { $this.Name = $recordName $this.RecordType = $type $this.RecordClass = $class } DnsQuestion( [EndianBinaryReader] $binaryReader ) { $this.Name = $binaryReader.ReadDnsDomainName() $this.RecordType = [DnsRecordType]$binaryReader.ReadUInt16($true) if ($this.RecordType -eq 'OPT') { $this.RecordClass = $binaryReader.ReadUInt16($true) } else { $this.RecordClass = [RecordClass]$binaryReader.ReadUInt16($true) } } hidden [byte[]] ToByteArray() { $bytes = [List[byte]]::new() $bytes.AddRange([EndianBinaryReader]::GetDnsDomainNameBytes($this.Name)) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.RecordType, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.RecordClass, $true)) return $bytes.ToArray() } [string] ToString() { return '{0,-29} {1,-5} {2,-5}' -f @( $this.Name $this.RecordClass $this.RecordType ) } } #EndRegion '.\class\1.MessageParts\DnsQuestion.ps1' 64 #Region '.\class\1.MessageParts\DnsResourceRecord.ps1' 0 #using namespace System.Collections.Generic #using namespace System.IO class DnsResourceRecord : IEquatable[Object] { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / NAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CLASS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TTL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | RDLENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| / RDATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string] $Name [UInt32] $TTL [RecordClass] $RecordClass = [RecordClass]::IN [DnsRecordType] $RecordType = 'EMPTY' [string] $RecordData [UInt16] $RecordDataLength hidden [bool] $IsTruncated DnsResourceRecord() { $thisTypeName = $this.GetType().Name if ($thisTypeName -ne 'DnsResourceRecord') { $this.RecordType = $thisTypeName -replace '^Dns|Record$' } } DnsResourceRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) { $this.Name = $dnsResourceRecord.Name $this.RecordType = $dnsResourceRecord.RecordType $this.RecordClass = $binaryReader.ReadUInt16($true) $this.TTL = $binaryReader.ReadUInt32($true) $this.RecordDataLength = $binaryReader.ReadUInt16($true) if ($binaryReader.BaseStream.Capacity -ge ($binaryReader.BaseStream.Position + $this.RecordDataLength)) { $this.ReadRecordData($binaryReader) } $this.RecordData = $this.RecordDataToString() } static [DnsResourceRecord] Parse( [byte[]] $bytes ) { $binaryReader = [EndianBinaryReader][MemoryStream]$bytes return [DnsResourceRecord]::Parse($binaryReader) } static [DnsResourceRecord] Parse( [EndianBinaryReader] $binaryReader ) { $resourceRecord = [DnsResourceRecord]::new() $resourceRecord.Name = $binaryReader.ReadDnsDomainName() if ($binaryReader.BaseStream.Capacity -ge ($binaryReader.BaseStream.Position + 10)) { $resourceRecord.RecordType = [int]$binaryReader.ReadUInt16($true) $typeName = 'Dns{0}Record' -f $resourceRecord.RecordType if ($typeName -as [Type]) { return ($typeName -as [Type])::new( $resourceRecord, $binaryReader ) } else { # Avoids a race condition when loading classes. return ('DnsUNKNOWNRecord' -as [Type])::new( $resourceRecord, $binaryReader ) } } else { $resourceRecord.IsTruncated = $true } return $resourceRecord } # Child classes must override this method hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $binaryReader.ReadBytes($this.RecordDataLength) } # Child classes must override this method hidden [string] RecordDataToString() { return '' } # Child classes should override this method if appropriate hidden [byte[]] RecordDataToByteArray( [bool] $useCompressedNames ) { return [byte[]]::new($this.RecordDataLength) } [byte[]] ToByteArray() { return $this.ToByteArray($true) } [byte[]] ToByteArray( [bool] $useCompressedNames ) { $bytes = [List[byte]]::new() if ($useCompressedNames) { $bytes.AddRange([byte[]](0xC0, 0x0C)) } else { $bytes.AddRange([EndianBinaryReader]::GetDnsDomainNameBytes($this.Name)) } $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.RecordType, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.RecordClass, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt32]$this.TTL, $true)) $recordDataBytes = $this.RecordDataToByteArray($useCompressedNames) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$recordDataBytes.Count, $true)) $bytes.AddRange($recordDataBytes) return $bytes.ToArray() } [bool] Equals( [Object] $object ) { return $this.ToString() -eq $object.ToString() } [string] ToString() { return '{0,-29} {1,-10} {2,-5} {3,-10} {4}' -f @( $this.Name $this.TTL $this.RecordClass $this.RecordType $this.RecordData ) } } #EndRegion '.\class\1.MessageParts\DnsResourceRecord.ps1' 158 #Region '.\class\2.RecordTypes\DnsA6Record.ps1' 0 class DnsA6Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFIX LEN | | +--+--+--+--+--+--+--+--+ | / ADDRESS SUFFIX / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PREFIX NAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [byte] $PrefixLength [IPAddress] $AddressSuffix [string] $PrefixName DnsA6Record() : base() { } DnsA6Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.PrefixLength = $binaryReader.ReadByte() $addressSuffixBytes = [byte[]]::new(16) $length = [Math]::Ceiling((128 - $this.PrefixLength) / 8) [Array]::Copy( $binaryReader.ReadBytes($length), 0, $addressSuffixBytes, 16 - $length, $length ) $this.AddressSuffix = [IPAddress]::new($addressSuffixBytes) if ($this.RecordDataLength - $length - 1 -gt 0) { $this.PrefixName = $binaryReader.ReadDnsDomainName() } } hidden [string] RecordDataToString() { $ipAddress = '{0}' -f $this.AddressSuffix.IPAddressToString if ($ipAddress -eq '::') { $ipAddress = '' } return ( '{0} {1} {2}' -f @( $this.PrefixLength $ipAddress $this.PrefixName ) ).Trim() } } #EndRegion '.\class\2.RecordTypes\DnsA6Record.ps1' 68 #Region '.\class\2.RecordTypes\DnsAAAARecord.ps1' 0 class DnsAAAARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESS | | | | | | | | | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [IPAddress] $IPAddress DnsAAAARecord() : base() { } DnsAAAARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.IPAddress = $binaryReader.ReadIPv6Address() } hidden [string] RecordDataToString() { return $this.IPAddress.IPAddressToString } } #EndRegion '.\class\2.RecordTypes\DnsAAAARecord.ps1' 38 #Region '.\class\2.RecordTypes\DnsAFSDBRecord.ps1' 0 class DnsAFSDBRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SUBTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / HOSTNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1183.txt #> [AFSDBSubType] $SubType [UInt16] $SubTypeValue [string] $Hostname DnsAFSDBRecord() : base() { } DnsAFSDBRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.SubTypeValue = $binaryReader.ReadUInt16($true) if ([Enum]::IsDefined([AFSDBSubType], [int]$this.SubTypeValue)) { $this.SubType = [int]$this.SubTypeValue } $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.SubTypeValue $this.Hostname ) } } #EndRegion '.\class\2.RecordTypes\DnsAFSDBRecord.ps1' 45 #Region '.\class\2.RecordTypes\DnsAMTRelayRecord.ps1' 0 class DnsAMTRELAYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PRECEDENCE | D| TYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / RELAY / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://tools.ietf.org/html/draft-ietf-mboned-driad-amt-discovery-06 #> [byte] $Precedence [bool] $DiscoveryOptional [AMTRelayType] $Type [string] $Relay DnsAMTRELAYRecord() : base() { } DnsAMTRELAYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Precedence = $binaryReader.ReadByte() $discoveryAndType = $binaryReader.ReadByte() $this.DiscoveryOptional = $discoveryAndType -band 0x80 $this.Type = $discoveryAndType -band 0x7F if ($this.Type -ne 'None') { $this.Relay = switch ($this.Type) { IPv4 { $binaryReader.ReadIPAddress() break } IPv6 { $binaryReader.ReadIPv6Address() break } DomainName { $binaryReader.ReadDnsDomainName() break } } } } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.Precedence [byte]$this.DiscoveryOptional $this.Type $this.Relay ) } } #EndRegion '.\class\2.RecordTypes\DnsAMTRelayRecord.ps1' 66 #Region '.\class\2.RecordTypes\DnsAPLRecord.ps1' 0 class DnsAPLRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESSFAMILY | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFIX | N| AFDLENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / AFDPART / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/html/rfc3123 #> [PSObject[]] $List DnsAPLRecord() : base() { } DnsAPLRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { if ($this.RecordDataLength -gt 0) { $listLength = $this.RecordDataLength $this.List = while ($listLength -gt 0) { $addressFamily = [IanaAddressFamily]$binaryReader.ReadUInt16($true) $prefix = $binaryReader.ReadByte() $negationAndLength = $binaryReader.ReadByte() $item = [PSCustomObject]@{ AddressFamily = $addressFamily Prefix = $prefix Negation = [bool]($negationAndLength -band 0x80) AddressLength = $negationAndLength -band 0x7F Address = $null } $addressBytes = switch ($item.AddressFamily) { 'IPv4' { [byte[]]::new(4) } 'IPv6' { [byte[]]::new(16) } } [Array]::Copy( $binaryReader.ReadBytes($item.AddressLength), 0, $addressBytes, 0, $item.AddressLength ) $item.Address = [IPAddress]::new($addressBytes) $item $listLength -= 4 + $item.AddressLength } } } hidden [string] RecordDataToString() { $values = foreach ($item in $this.List) { '{0}{1:D}:{2}/{3}' -f @( ('', '!')[$item.Negation] $item.AddressFamily $item.Address $item.Prefix ) } return $values -join ' ' } } #EndRegion '.\class\2.RecordTypes\DnsAPLRecord.ps1' 79 #Region '.\class\2.RecordTypes\DnsARecord.ps1' 0 class DnsARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [IPAddress] $IPAddress DnsARecord() : base() { } DnsARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.IPAddress = $binaryReader.ReadIPAddress() } hidden [string] RecordDataToString() { return $this.IPAddress.IPAddressToString } } #EndRegion '.\class\2.RecordTypes\DnsARecord.ps1' 31 #Region '.\class\2.RecordTypes\DnsATMARecord.ps1' 0 #using namespace System.Text class DnsATMARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FORMAT | | +--+--+--+--+--+--+--+--+ | / ATMADDRESS / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [ATMAFormat] $Format [string] $ATMAAddress DnsATMARecord() : base() { } DnsATMARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Format = [ATMAFormat]$binaryReader.ReadByte() $length = $this.RecordDataLength - 1 $this.ATMAAddress = switch ($this.Format) { 'E164' { '+{0}' -f [string]::new($binaryReader.ReadChars($length)) break } default { [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($length)).ToLower() break } } } hidden [string] RecordDataToString() { return $this.ATMAAddress } } #EndRegion '.\class\2.RecordTypes\DnsATMARecord.ps1' 51 #Region '.\class\2.RecordTypes\DnsAVCRecord.ps1' 0 class DnsAVCRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / AVC-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string[]] $Data DnsAVCRecord() : base() { } DnsAVCRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = $this.RecordDataLength if ($length -gt 0) { $this.Data = do { $entryLength = 0 $binaryReader.ReadDnsCharacterString([ref]$entryLength) $length -= $entryLength } until ($length -le 0) } } hidden [string] RecordDataToString() { return '"{0}"' -f ($this.Data -join '" "') } } #EndRegion '.\class\2.RecordTypes\DnsAVCRecord.ps1' 40 #Region '.\class\2.RecordTypes\DnsCAARecord.ps1' 0 class DnsCAARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | / +--+--+--+--+--+--+--+--+ / / TAG / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / VALUE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/html/rfc6844 #> [CAAFlag] $CAAFlag [string] $Tag [string] $Value DnsCAARecord() : base() { } DnsCAARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.CAAFlag = $binaryReader.ReadByte() $length = 0 $this.Tag = $binaryReader.ReadDnsCharacterString([ref]$length) $this.Value = [string]::new( $binaryReader.ReadChars( $this.RecordDataLength - $length - 1 ) ) } hidden [string] RecordDataToString() { return '{0:D} {1} "{2}"' -f @( $this.CAAFlag $this.Tag $this.Value ) } } #EndRegion '.\class\2.RecordTypes\DnsCAARecord.ps1' 54 #Region '.\class\2.RecordTypes\DnsCDNSKEYRecord.ps1' 0 class DnsCDNSKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PROTOCOL | ALGORITHM | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLIC KEY / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ The flags field takes the following format, discussed in RFC 4034 2.1.1: 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | Z| | S| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ Where Z represents the ZoneKey bit, and S the SecureEntryPoint bit. http://www.ietf.org/rfc/rfc7344.txt #> [UInt16] $Flags [bool] $ZoneKey [bool] $SecureEntryPoint [KEYProtocol] $Protocol [EncryptionAlgorithm] $Algorithm [string] $PublicKey DnsCDNSKEYRecord() : base() { } DnsCDNSKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Flags = $binaryReader.ReadUInt16($true) $this.ZoneKey = $this.Flags -band 0x0100 $this.SecureEntryPoint = $this.Flags -band 0x0001 $this.Protocol = $binaryReader.ReadByte() $this.Algorithm = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 4) $this.PublicKey = [Convert]::ToBase64String($bytes) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.Flags $this.Protocol $this.Algorithm $this.PublicKey -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsCDNSKEYRecord.ps1' 67 #Region '.\class\2.RecordTypes\DnsCDSRecord.ps1' 0 class DnsCDSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEYTAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | DIGESTTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DIGEST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc7344.txt #> [UInt16] $KeyTag [EncryptionAlgorithm] $Algorithm [DigestType] $DigestType [string] $Digest DnsCDSRecord() : base() { } DnsCDSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.KeyTag = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.DigestType = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 4) $this.Digest = [EndianBitConverter]::ToHexadecimal($bytes) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.KeyTag $this.Algorithm $this.DigestType $this.Digest -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsCDSRecord.ps1' 51 #Region '.\class\2.RecordTypes\DnsCERTRecord.ps1' 0 class DnsCERTRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEY TAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | | +--+--+--+--+--+--+--+--+ | / CERTIFICATE or CRL / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc4398.txt #> [CertificateType] $CertificateType [UInt16] $KeyTag [EncryptionAlgorithm] $Algorithm [string] $Certificate DnsCERTRecord() : base() { } DnsCERTRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.CertificateType = $binaryReader.ReadUInt16($true) $this.KeyTag = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 5) $this.Certificate = [Convert]::ToBase64String($bytes) } hidden [string] RecordDataToString() { return '{0:D} {1:D} {2} {3}' -f @( $this.CertificateType $this.KeyTag $this.Algorithm $this.Certificate -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsCERTRecord.ps1' 53 #Region '.\class\2.RecordTypes\DnsCNAMERecord.ps1' 0 class DnsCNAMERecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / CNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string] $Hostname DnsCNAMERecord() : base() { } DnsCNAMERecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsCNAMERecord.ps1' 32 #Region '.\class\2.RecordTypes\DnsCSYNCRecord.ps1' 0 class DnsCSYNCRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERIAL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TYPE BIT MAP / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc7477.txt #> [UInt32] $Serial [CSYNCFlags] $Flags [DnsRecordType[]] $TypesToProcess DnsCSYNCRecord() : base() { } DnsCSYNCRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Serial = $binaryReader.ReadUInt32($true) $this.Flags = $binaryReader.ReadUInt16($true) $this.TypesToProcess = $binaryReader.ReadBitMap($this.RecordDataLength - 6) } hidden [string] RecordDataToString() { if ($this.TypesToProcess.Count -gt 0) { return '{0} {1:D} {2}' -f @( $this.Serial $this.Flags $this.TypesToProcess -join ' ' ) } else { return '{0} {1:D}' -f @( $this.Serial $this.Flags ) } } } #EndRegion '.\class\2.RecordTypes\DnsCSYNCRecord.ps1' 56 #Region '.\class\2.RecordTypes\DnsDHCIDRecord.ps1' 0 class DnsDHCIDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / <anything> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc4701.txt #> [byte[]] $BinaryData DnsDHCIDRecord() : base() { } DnsDHCIDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.BinaryData = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return [Convert]::ToBase64String($this.BinaryData) } } #EndRegion '.\class\2.RecordTypes\DnsDHCIDRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsDLVRecord.ps1' 0 class DnsDLVRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEYTAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | DIGESTTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DIGEST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc4431.txt #> [UInt16] $KeyTag [EncryptionAlgorithm] $Algorithm [DigestType] $DigestType [string] $Digest DnsDLVRecord() : base() { } DnsDLVRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.KeyTag = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.DigestType = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 4) $this.Digest = [EndianBitConverter]::ToHexadecimal($bytes) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.KeyTag $this.Algorithm $this.DigestType $this.Digest ) } } #EndRegion '.\class\2.RecordTypes\DnsDLVRecord.ps1' 51 #Region '.\class\2.RecordTypes\DnsDNAMERecord.ps1' 0 class DnsDNAMERecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TARGET / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2672.txt #> [string] $Target DnsDNAMERecord() : base() { } DnsDNAMERecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Target = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Target } } #EndRegion '.\class\2.RecordTypes\DnsDNAMERecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsDNSKEYRecord.ps1' 0 class DnsDNSKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PROTOCOL | ALGORITHM | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLIC KEY / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ The flags field takes the following format, discussed in RFC 4034 2.1.1: 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | Z| | S| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ Where Z represents the ZoneKey bit, and S the SecureEntryPoint bit. http://www.ietf.org/rfc/rfc3755.txt http://www.ietf.org/rfc/rfc4034.txt #> [UInt16] $Flags [bool] $ZoneKey [bool] $SecureEntryPoint [KEYProtocol] $Protocol [EncryptionAlgorithm] $Algorithm [string] $PublicKey DnsDNSKEYRecord() : base() { } DnsDNSKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Flags = $binaryReader.ReadUInt16($true) $this.ZoneKey = $this.Flags -band 0x0100 $this.SecureEntryPoint = $this.Flags -band 0x0001 $this.Protocol = $binaryReader.ReadByte() $this.Algorithm = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 4) $this.PublicKey = [Convert]::ToBase64String($bytes) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.Flags $this.Protocol $this.Algorithm $this.PublicKey -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsDNSKEYRecord.ps1' 68 #Region '.\class\2.RecordTypes\DnsDOARecord.ps1' 0 class DnsDOARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | DOA-ENTERPRISE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | DOA-TYPE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | DOA-LOCATION | / +--+--+--+--+--+--+--+--+ / / DOA-MEDIA-TYPE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DOA-DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://tools.ietf.org/html/draft-durand-doa-over-dns-03 DOA Enterprise values are defined by: https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers #> [UInt32] $Enterprise [UInt32] $Type [DOALocation] $Location [string] $MediaType [string] $Data DnsDOARecord() : base() { } DnsDOARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Enterprise = $binaryReader.ReadUInt32($true) $this.Type = $binaryReader.ReadUInt32($true) $this.Location = $binaryReader.ReadByte() $length = 0 $this.MediaType = $binaryReader.ReadDnsCharacterString([ref]$length) $length = $this.RecordDataLength - 9 - $length $this.Data = [Convert]::ToBase64String($binaryReader.ReadBytes($length)) } hidden [string] RecordDataToString() { return '{0} {1} {2:D} "{3}" {4}' -f @( $this.Enterprise $this.Type $this.Location $this.MediaType $this.Data ) } } #EndRegion '.\class\2.RecordTypes\DnsDOARecord.ps1' 67 #Region '.\class\2.RecordTypes\DnsDSRecord.ps1' 0 class DnsDSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEYTAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | DIGESTTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DIGEST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc3658.txt http://www.ietf.org/rfc/rfc4034.txt #> [UInt16] $KeyTag [EncryptionAlgorithm] $Algorithm [DigestType] $DigestType [string] $Digest DnsDSRecord() : base() { } DnsDSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.KeyTag = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.DigestType = $binaryReader.ReadByte() $bytes = $binaryReader.ReadBytes($this.RecordDataLength - 4) $this.Digest = [EndianBitConverter]::ToHexadecimal($bytes) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.KeyTag $this.Algorithm $this.DigestType $this.Digest -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsDSRecord.ps1' 52 #Region '.\class\2.RecordTypes\DnsEIDRecord.ps1' 0 class DnsEIDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / EID / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://cpansearch.perl.org/src/MIKER/Net-DNS-Codes-0.11/extra_docs/draft-ietf-nimrod-dns-02.txt #> [string] $EID DnsEIDRecord() : base() { } DnsEIDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.EID = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength)) } hidden [string] RecordDataToString() { return $this.EID } } #EndRegion '.\class\2.RecordTypes\DnsEIDRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsEUI48Record.ps1' 0 class DnsEUI48Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESS | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://cpansearch.perl.org/src/MIKER/Net-DNS-Codes-0.11/extra_docs/draft-ietf-nimrod-dns-02.txt #> [string] $Address DnsEUI48Record() : base() { } DnsEUI48Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Address = [BitConverter]::ToString($binaryReader.ReadBytes(6)).ToLower() } hidden [string] RecordDataToString() { return $this.Address } } #EndRegion '.\class\2.RecordTypes\DnsEUI48Record.ps1' 36 #Region '.\class\2.RecordTypes\DnsEUI64Record.ps1' 0 class DnsEUI64Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESS | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://cpansearch.perl.org/src/MIKER/Net-DNS-Codes-0.11/extra_docs/draft-ietf-nimrod-dns-02.txt #> [string] $Address DnsEUI64Record() : base() { } DnsEUI64Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Address = [BitConverter]::ToString($binaryReader.ReadBytes(8)).ToLower() } hidden [string] RecordDataToString() { return $this.Address } } #EndRegion '.\class\2.RecordTypes\DnsEUI64Record.ps1' 37 #Region '.\class\2.RecordTypes\DnsGIDRecord.ps1' 0 class DnsGIDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / GID / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ IANA-Reserved #> [byte[]] $Data DnsGIDRecord() : base() { } DnsGIDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Data = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return '\# {0} {1}' -f @( $this.Data.Length [EndianBitConverter]::ToHexadecimal($this.Data) ) } } #EndRegion '.\class\2.RecordTypes\DnsGIDRecord.ps1' 36 #Region '.\class\2.RecordTypes\DnsGPOSRecord.ps1' 0 class DnsGPOSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / LONGITUDE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / LATITUDE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ALTITUDE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1712.txt #> [string] $Longitude [string] $Latitude [string] $Altitude DnsGPOSRecord() : base() { } DnsGPOSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Longitude = $binaryReader.ReadDnsCharacterString() $this.Latitude = $binaryReader.ReadDnsCharacterString() $this.Altitude = $binaryReader.ReadDnsCharacterString() } hidden [string] RecordDataToString() { return '"{0}" "{1}" "{2}"' -f @( $this.Longitude $this.Latitude $this.Altitude ) } } #EndRegion '.\class\2.RecordTypes\DnsGPOSRecord.ps1' 48 #Region '.\class\2.RecordTypes\DnsHINFORecord.ps1' 0 class DnsHINFORecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / CPU / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / OS / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $CPU [string] $OS DnsHINFORecord() : base() { } DnsHINFORecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.CPU = $binaryReader.ReadDnsCharacterString() $this.OS = $binaryReader.ReadDnsCharacterString() } hidden [string] RecordDataToString() { return '"{0}" "{1}"' -f @( $this.CPU $this.OS ) } } #EndRegion '.\class\2.RecordTypes\DnsHINFORecord.ps1' 40 #Region '.\class\2.RecordTypes\DnsHIPRecord.ps1' 0 class DnsHIPRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | HIT LENGTH | PK ALGORITHM | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PUBLIC KEY LENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / HIT / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLIC KEY / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / RENDEZVOUS SERVERS / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc5205.txt #> [IPSECAlgorithm] $PublicKeyAlgorithm [string] $HIT [string] $PublicKey [string[]] $RendezvousServers DnsHIPRecord() : base() { } DnsHIPRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $hitLength = $binaryReader.ReadByte() $this.PublicKeyAlgorithm = $binaryReader.ReadByte() $publicKeyLength = $binaryReader.ReadUInt16($true) $this.HIT = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($hitLength)) $this.PublicKey = [Convert]::ToBase64String($binaryReader.ReadBytes($publicKeyLength)) $length = $this.RecordDataLength - 4 - $hitLength - $publicKeyLength if ($length -gt 0) { $this.RendezvousServers = do { $entryLength = 0 $binaryReader.ReadDnsDomainName([ref]$entryLength) $length -= $entryLength } until ($length -le 0) } } hidden [string] RecordDataToString() { return '{0:D} {1} {2} {3}' -f @( $this.PublicKeyAlgorithm $this.HIT $this.PublicKey $this.RendezvousServers -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsHIPRecord.ps1' 71 #Region '.\class\2.RecordTypes\DnsIPSECKEYRecord.ps1' 0 class DnsIPSECKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PRECEDENCE | GATEWAYTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | / +--+--+--+--+--+--+--+--+ / / GATEWAY / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLICKEY / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc4025.txt #> [byte] $Precedence [IPSECGatewayType] $GatewayType [IPSECAlgorithm] $Algorithm [string] $Gateway [string] $PublicKey DnsIPSECKEYRecord() : base() { } DnsIPSECKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Precedence = $binaryReader.ReadByte() $this.GatewayType = $binaryReader.ReadByte() $this.Algorithm = $binaryReader.ReadByte() $length = 0 $this.Gateway = switch ($this.GatewayType) { IPv4 { $binaryReader.ReadIPAddress() $length = 4 break } IPv6 { $binaryReader.ReadIPv6Address() $length = 16 break } DomainName { $binaryReader.ReadDnsDomainName([ref]$length) break } } if ($this.Gateway.Length -eq 0) { $this.Gateway = '.' } $publicKeyLength = $this.RecordDataLength - $length - 3 $this.PublicKey = [Convert]::ToBase64String($binaryReader.ReadBytes($publicKeyLength)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3} {4}' -f @( $this.Precedence $this.GatewayType $this.Algorithm $this.Gateway $this.PublicKey ) } } #EndRegion '.\class\2.RecordTypes\DnsIPSECKEYRecord.ps1' 77 #Region '.\class\2.RecordTypes\DnsISDNRecord.ps1' 0 class DnsISDNRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ISDNADDRESS / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SUBADDRESS / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1183.txt #> [string] $ISDNAddress [string] $SubAddress DnsISDNRecord() : base() { } DnsISDNRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = 0 $this.ISDNAddress = $binaryReader.ReadDnsCharacterString([ref]$length) if ($this.RecordDataLength - $length -gt 0) { $this.SubAddress = $binaryReader.ReadDnsCharacterString() } } hidden [string] RecordDataToString() { if ($this.SubAddress) { return '"{0}" "{1}"' -f @( $this.ISDNAddress $this.SubAddress ) } else { return '"{0}"' -f @( $this.ISDNAddress ) } } } #EndRegion '.\class\2.RecordTypes\DnsISDNRecord.ps1' 50 #Region '.\class\2.RecordTypes\DnsKEYRecord.ps1' 0 class DnsKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PROTOCOL | ALGORITHM | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLIC KEY / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ The flags field takes the following format, discussed in RFC 2535 3.1.2: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ #> [UInt16] $Flags [KEYAC] $AuthenticationConfidentiality [UInt16] $FlagsExtension [KEYNameType] $NameType [bool] $SignatoryField [KEYProtocol] $Protocol [EncryptionAlgorithm] $Algorithm [string] $PublicKey DnsKEYRecord() : base() { } DnsKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Flags = $binaryReader.ReadUInt16($true) $this.AuthenticationConfidentiality = [byte]($this.Flags -shr 14) if (($this.Flags -band 0x1000) -eq 0x1000) { $this.FlagsExtension = $binaryReader.ReadUInt16($true) } $this.NameType = ($this.Flags -band 0x0300) -shr 9 $this.SignatoryField = $this.Flags -band 0x000F $this.Protocol = $binaryReader.ReadByte() $this.Algorithm = $binaryReader.ReadByte() $length = $this.RecordDataLength - 4 if ($this.AuthenticationConfidentiality -ne 'NoKey' -and $length -gt 0) { $this.PublicKey = [Convert]::ToBase64String($binaryReader.ReadBytes($length)) } } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.Flags $this.Protocol $this.Algorithm $this.PublicKey -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsKEYRecord.ps1' 71 #Region '.\class\2.RecordTypes\DnsKXRecord.ps1' 0 class DnsKXRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / EXCHANGER / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2230.txt #> [UInt16] $Preference [string] $Exchanger DnsKXRecord() : base() { } DnsKXRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.Exchanger = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.Exchanger ) } } #EndRegion '.\class\2.RecordTypes\DnsKXRecord.ps1' 41 #Region '.\class\2.RecordTypes\DnsL32Record.ps1' 0 class DnsL32Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOCATOR | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://www.ietf.org/rfc/rfc6742.txt #> [UInt16] $Preference [string] $Locator DnsL32Record() : base() { } DnsL32Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.Locator = $binaryReader.ReadIPAddress() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.Locator ) } } #EndRegion '.\class\2.RecordTypes\DnsL32Record.ps1' 41 #Region '.\class\2.RecordTypes\DnsL64Record.ps1' 0 class DnsL64Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOCATOR | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://www.ietf.org/rfc/rfc6742.txt #> [UInt16] $Preference [string] $Locator DnsL64Record() : base() { } DnsL64Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $bytes = $binaryReader.ReadBytes(8) $address = for ($i = 0; $i -lt $bytes.Count; $i += 2) { ('{0:x2}{1:x2}' -f $bytes[$i], $bytes[$i + 1]).TrimStart('0') } $this.Locator = $address -join ':' } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.Locator ) } } #EndRegion '.\class\2.RecordTypes\DnsL64Record.ps1' 48 #Region '.\class\2.RecordTypes\DnsLOCRecord.ps1' 0 class DnsLOCRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | VERSION | SIZE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | HORIZ PRE | VERT PRE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LATITUDE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LONGITUDE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALTITUDE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1876.txt #> [byte] $Version [Decimal] $Size [Decimal] $HorizontalPrecision [Decimal] $VerticalPrecision [AngularDistance] $Latitude [AngularDistance] $Longitude [Decimal] $Altitude DnsLOCRecord() : base() { } DnsLOCRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [Double] ConvertFromIntegerPair($byte) { return 0 + ( '{0}e{1}' -f @( ($byte -band 0xF0) -shr 4 $byte -band 0x0F ) ) / 100 } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Version = $binaryReader.ReadByte() $this.Size = $this.ConvertFromIntegerPair($binaryReader.ReadByte()) $this.HorizontalPrecision = $this.ConvertFromIntegerPair($binaryReader.ReadByte()) $this.VerticalPrecision = $this.ConvertFromIntegerPair($binaryReader.ReadByte()) $this.Latitude = [AngularDistance]::new($binaryReader.ReadUInt32($true), 'Latitude') $this.Longitude = [AngularDistance]::new($binaryReader.ReadUInt32($true), 'Longitude') $this.Altitude = (-10000000 + $binaryReader.ReadUInt32($true)) / 100 } hidden [string] RecordDataToString() { return '{0} {1} {2:N2}m {3}m {4}m {5}m' -f @( $this.Latitude $this.Longitude $this.Altitude $this.Size $this.HorizontalPrecision $this.VerticalPrecision ) } } #EndRegion '.\class\2.RecordTypes\DnsLOCRecord.ps1' 74 #Region '.\class\2.RecordTypes\DnsLPRecord.ps1' 0 class DnsLPRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / FQDN / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2230.txt #> [UInt16] $Preference [string] $FQDN DnsLPRecord() : base() { } DnsLPRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.FQDN = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.FQDN ) } } #EndRegion '.\class\2.RecordTypes\DnsLPRecord.ps1' 41 #Region '.\class\2.RecordTypes\DnsMBRecord.ps1' 0 class DnsMBRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MADNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $Hostname DnsMBRecord() : base() { } DnsMBRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsMBRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsMDRecord.ps1' 0 class DnsMDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MADNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $Hostname DnsMDRecord() : base() { } DnsMDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsMDRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsMFRecord.ps1' 0 class DnsMFRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MADNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $Hostname DnsMFRecord() : base() { } DnsMFRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsMFRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsMGRecord.ps1' 0 class DnsMGRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MGMNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $MailboxName DnsMGRecord() : base() { } DnsMGRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.MailboxName = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.MailboxName } } #EndRegion '.\class\2.RecordTypes\DnsMGRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsMINFORecord.ps1' 0 #using namespace Indented.IO class DnsMINFORecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / RMAILBX / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / EMAILBX / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $ResponsibleMailbox [string] $ErrorMailbox DnsMINFORecord() : base() { } DnsMINFORecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.ResponsibleMailbox = $binaryReader.ReadDnsDomainName() $this.ErrorMailbox = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.ResponsibleMailbox $this.ErrorMailbox ) } } #EndRegion '.\class\2.RecordTypes\DnsMINFORecord.ps1' 43 #Region '.\class\2.RecordTypes\DnsMRRecord.ps1' 0 class DnsMRRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / NEWNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $MailboxName DnsMRRecord() : base() { } DnsMRRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.MailboxName = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.MailboxName } } #EndRegion '.\class\2.RecordTypes\DnsMRRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsMXRecord.ps1' 0 class DnsMXRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / EXCHANGE / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [UInt16] $Preference [string] $Exchange DnsMXRecord() : base() { } DnsMXRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.Exchange = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.Exchange ) } } #EndRegion '.\class\2.RecordTypes\DnsMXRecord.ps1' 41 #Region '.\class\2.RecordTypes\DnsNAPTRRecord.ps1' 0 class DnsNAPTRRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ORDER | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / FLAGS / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SERVICES / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / REGEXP / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / REPLACEMENT / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2915.txt #> [UInt16] $Order [UInt16] $Preference [string] $Flags [string] $Service [string] $RegularExpression [string] $Replacement DnsNAPTRRecord() : base() { } DnsNAPTRRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Order = $binaryReader.ReadUInt16($true) $this.Preference = $binaryReader.ReadUInt16($true) $this.Flags = $binaryReader.ReadDnsCharacterString() $this.Service = $binaryReader.ReadDnsCharacterString() $this.RegularExpression = $binaryReader.ReadDnsCharacterString() $this.Replacement = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1} "{2}" "{3}" "{4}" {5}' -f @( $this.Order $this.Preference $this.Flags $this.Service $this.RegularExpression $this.Replacement ) } } #EndRegion '.\class\2.RecordTypes\DnsNAPTRRecord.ps1' 61 #Region '.\class\2.RecordTypes\DnsNIDRecord.ps1' 0 class DnsNIDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NODEID | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://www.ietf.org/rfc/rfc6742.txt #> [UInt16] $Preference [string] $NodeID DnsNIDRecord() : base() { } DnsNIDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $bytes = $binaryReader.ReadBytes(8) $address = for ($i = 0; $i -lt $bytes.Count; $i += 2) { ('{0:x2}{1:x2}' -f $bytes[$i], $bytes[$i + 1]).TrimStart('0') } $this.NodeID = $address -join ':' } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference $this.NodeID ) } } #EndRegion '.\class\2.RecordTypes\DnsNIDRecord.ps1' 48 #Region '.\class\2.RecordTypes\DnsNIMLOCRecord.ps1' 0 class DnsNIMLOCRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / BinaryData / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt #> [byte[]] $BinaryData DnsNIMLOCRecord() : base() { } DnsNIMLOCRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.BinaryData = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return [EndianBitConverter]::ToHexadecimal($this.BinaryData) } } #EndRegion '.\class\2.RecordTypes\DnsNIMLOCRecord.ps1' 33 #Region '.\class\2.RecordTypes\DnsNINFORecord.ps1' 0 #using namespace System.Collections.Generic #using namespace System.Text class DnsNINFORecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ZS-DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/html/draft-lewis-dns-undocumented-types-01 http://tools.ietf.org/html/draft-reid-dnsext-zs-01 #> [string[]] $ZSData DnsNINFORecord() : base() { } DnsNINFORecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = $this.RecordDataLength if ($length -gt 0) { $this.ZSData = do { $entryLength = 0 $binaryReader.ReadDnsCharacterString([ref]$entryLength) $length -= $entryLength } until ($length -le 0) } } hidden [string] RecordDataToString() { return '"{0}"' -f ($this.ZSData -join '" "') } } #EndRegion '.\class\2.RecordTypes\DnsNINFORecord.ps1' 47 #Region '.\class\2.RecordTypes\DnsNSAPPTRRecord.ps1' 0 class DnsNSAPPTRRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / OWNER / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1348.txt #> [string] $Owner DnsNSAPPTRRecord() : base() { } DnsNSAPPTRRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Owner = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Owner } [string] ToString() { return '{0,-29} {1,-10} {2,-5} {3,-10} {4}' -f @( $this.Name $this.TTL $this.RecordClass 'NSAP-PTR' $this.RecordData ) } } #EndRegion '.\class\2.RecordTypes\DnsNSAPPTRRecord.ps1' 44 #Region '.\class\2.RecordTypes\DnsNSAPRecord.ps1' 0 class DnsNSAPRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / NSAP / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1706.txt #> [string] $Text [string] $Data DnsNSAPRecord() : base() { } DnsNSAPRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Data = '0x{0}' -f @( [EndianBitConverter]::ToHexadecimal( $binaryReader.ReadBytes($this.RecordDataLength) ) ) } hidden [string] RecordDataToString() { return $this.Data } } #EndRegion '.\class\2.RecordTypes\DnsNSAPRecord.ps1' 38 #Region '.\class\2.RecordTypes\DnsNSEC3PARAMRecord.ps1' 0 class DnsNSEC3PARAMRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | HASH ALG | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ITERATIONS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SALT LEN | / +--+--+--+--+--+--+--+--+ / / SALT / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc5155.txt #> [NSEC3HashAlgorithm] $HashAlgorithm [byte] $Flags [UInt16] $Iterations [string] $Salt = '-' DnsNSEC3PARAMRecord() : base() { } DnsNSEC3PARAMRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.HashAlgorithm = $binaryReader.ReadByte() $this.Flags = $binaryReader.ReadByte() $this.Iterations = $binaryReader.ReadUInt16($true) $saltLength = $binaryReader.ReadByte() if ($saltLength -gt 0) { $this.Salt = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($saltLength)) } } hidden [string] RecordDataToString() { return '{0:D} {1} {2} {3}' -f @( $this.HashAlgorithm $this.Flags $this.Iterations $this.Salt ) } } #EndRegion '.\class\2.RecordTypes\DnsNSEC3PARAMRecord.ps1' 54 #Region '.\class\2.RecordTypes\DnsNSEC3Record.ps1' 0 class DnsNSEC3Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | HASH ALG | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ITERATIONS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SALT LEN | / +--+--+--+--+--+--+--+--+ / / SALT / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | HASH LEN | / +--+--+--+--+--+--+--+--+ / / HASH / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / <BIT MAP> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ The flags field takes the following format, discussed in RFC 5155 3.2: 0 1 2 3 4 5 6 7 +--+--+--+--+--+--+--+--+ | |O | +--+--+--+--+--+--+--+--+ Where O, bit 7, represents the Opt-Out Flag. http://www.ietf.org/rfc/rfc5155.txt #> [NSEC3HashAlgorithm] $HashAlgorithm [byte] $Flags [bool] $OptOut [UInt16] $Iterations [string] $Salt [string] $Hash [DnsRecordType[]] $RRType DnsNSEC3Record() : base() { } DnsNSEC3Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.HashAlgorithm = $binaryReader.ReadByte() $this.Flags = $binaryReader.ReadByte() $this.OptOut = $this.Flags -band [NSEC3Flags]::OptOut $this.Iterations = $binaryReader.ReadUInt16($true) $saltLength = $binaryReader.ReadByte() if ($saltLength -gt 0) { $this.Salt = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($saltLength)) } $hashLength = $binaryReader.ReadByte() $this.Hash = [EndianBitConverter]::ToBase32String($binaryReader.ReadBytes($hashLength)) $this.RRType = $binaryReader.ReadBitMap( $this.RecordDataLength - 6 - $saltLength - $hashLength ) } hidden [string] RecordDataToString() { return '{0:D} {1} {2} {3} {4} {5}' -f @( $this.HashAlgorithm $this.Flags $this.Iterations $this.Salt $this.Hash $this.RRType -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsNSEC3Record.ps1' 84 #Region '.\class\2.RecordTypes\DnsNSECRecord.ps1' 0 class DnsNSECRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DOMAINNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / <BIT MAP> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string] $DomainName [DnsRecordType[]] $RRType DnsNSECRecord() : base() { } DnsNSECRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = 0 $this.DomainName = $binaryReader.ReadDnsDomainName([ref]$length) $this.RRType = $binaryReader.ReadBitMap( $this.RecordDataLength - $length ) } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.DomainName $this.RRType -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsNSECRecord.ps1' 44 #Region '.\class\2.RecordTypes\DnsNSRecord.ps1' 0 class DnsNSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / NSDNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [string] $Hostname DnsNSRecord() : base() { } DnsNSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsNSRecord.ps1' 32 #Region '.\class\2.RecordTypes\DnsNULLRecord.ps1' 0 class DnsNULLRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / <anything> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [byte[]] $BinaryData DnsNULLRecord() : base() { } DnsNULLRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.BinaryData = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return [Convert]::ToBase64String($this.BinaryData) } } #EndRegion '.\class\2.RecordTypes\DnsNULLRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsNXTRecord.ps1' 0 #using namespace System.Text class DnsNXTRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DOMAINNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / <BIT MAP> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2535.txt http://www.ietf.org/rfc/rfc3755.txt #> [string] $DomainName [DnsRecordType[]] $RRType DnsNXTRecord() : base() { } DnsNXTRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = 0 $this.DomainName = $binaryReader.ReadDnsDomainName([ref]$length) $bitMapLength = $this.RecordDataLength - $length $bitMap = $binaryReader.ReadBytes($bitMapLength) $this.RRType = for ($i = 0; $i -lt $bitMapLength; $i++) { for ($j = 7; $j -ge 0; $j--) { if ($bitMap[$i] -band 1 -shl $j) { 8 * $i + 7 - $j } } } } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.DomainName $this.RRType -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsNXTRecord.ps1' 56 #Region '.\class\2.RecordTypes\DnsOPENPGPKEYRecord.ps1' 0 class DnsOPENPGPKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXT-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $Key DnsOPENPGPKEYRecord() : base() { } DnsOPENPGPKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Key = [Convert]::ToBase64String($binaryReader.ReadBytes($this.RecordDataLength)) } hidden [string] RecordDataToString() { return $this.Key -split '(?<=\G.{56})' -join ' ' } } #EndRegion '.\class\2.RecordTypes\DnsOPENPGPKEYRecord.ps1' 33 #Region '.\class\2.RecordTypes\DnsOPTRecord.ps1' 0 #using namespace System.Collections.Generic #using namespace System.Text class DnsOPTRecord : DnsResourceRecord { <# OPT records make the following changes to standard resource record fields: Field Name Field Type Description ---------- ---------- ----------- NAME domain name empty (root domain) TYPE u_int16_t OPT CLASS u_int16_t sender's UDP payload size TTL u_int32_t extended RCODE and flags RDLEN u_int16_t describes RDATA RDATA octet stream {attribute,value} pairs The Extended RCODE (stored in the TTL) is formatted as follows: 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | EXTENDED-RCODE | VERSION | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | Z | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ RR data structure: 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-CODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-LENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / OPTION-DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ Processing for each option assigned by IANA has been added as described below. LLQ --- 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-CODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-LENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | VERSION | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LLQ-OPCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ERROR-CODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LLQ-ID | | | | | | | | | | | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LEASE-LIFE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ NSID ---- Option data is returned as a byte array (NSIDBytes) and an ASCII string (NSIDString). DUA, DHU and N3U ---------------- 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-CODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LIST-LENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALG-CODE | ... / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ EDNS-client-subnet ------------------ 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-CODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OPTION-LENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESSFAMILY | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SOURCE NETMASK | SCOPE NETMASK | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ADDRESS / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2671.txt http://files.dns-sd.org/draft-sekar-dns-llq.txt http://files.dns-sd.org/draft-sekar-dns-ul.txt http://www.ietf.org/rfc/rfc5001.txt http://www.ietf.org/rfc/rfc6975.txt https://tools.ietf.org/html/rfc7871 #> [UInt16] $MaximumPayloadSize [UInt16] $ExtendedRCode [UInt32] $Version [EDnsDNSSECOK] $Z [PSObject[]] $OptionData DnsOPTRecord() : base() { $this.RecordType = 'OPT' } DnsOPTRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) { $this.Name = $dnsResourceRecord.Name $this.RecordType = $dnsResourceRecord.RecordType $this.MaximumPayloadSize = $binaryReader.ReadUInt16($true) $this.ExtendedRCode = $binaryReader.ReadByte() $this.Version = $binaryReader.ReadByte() $this.Z = $binaryReader.ReadUInt16($true) $this.RecordDataLength = $binaryReader.ReadUInt16($true) if ($binaryReader.BaseStream.Capacity -ge ($binaryReader.BaseStream.Position + $this.RecordDataLength)) { $this.ReadRecordData($binaryReader) } } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $optionsLength = $this.RecordDataLength $this.OptionData = while ($optionsLength -gt 0) { $optionCode = [EDnsOptionCode]$binaryReader.ReadUInt16($true) $optionLength = $binaryReader.ReadUInt16($true) $optionsLength -= $optionLength switch ($optionCode) { 'LLQ' { [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength Version = $binaryReader.ReadUInt16($true) OpCode = [LLQOpCode]$binaryReader.ReadUInt16($true) ErrorCode = [LLQErrorCode]$binaryReader.ReadUInt16($true) ID = $binaryReader.ReadUInt64($true) LeaseLife = $binaryReader.ReadUInt32($true) } break } 'UL' { [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength Lease = $binaryReader.ReadInt32($true) } break } 'NSID' { $bytes = $binaryReader.ReadBytes($this.OptionLength) [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength Bytes = $bytes String = [Encoding]::UTF8.GetString($bytes) } break } 'EDNSClientSubnet' { $option = [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength AddressFamily = [IanaAddressFamily]$binaryReader.ReadUInt16($true) SourceNetMask = $binaryReader.ReadByte() ScopeNetMask = $binaryReader.ReadByte() Address = $null } $addressLength = [Math]::Ceiling($option.SourceNetMask / 8) $addressBytes = $binaryReader.ReadBytes($addressLength) $length = switch ($option.AddressFamily) { 'IPv4' { 4 } 'IPv6' { 16 } } if ($length) { while ($addressBytes.Length -lt $length) { $addressBytes = @([byte]0) + $addressBytes } $option.Address = [IPAddress]::new($addressBytes) } else { $option.Address = $addressBytes } $option break } { $_ -in 'DAU', 'DHU', 'N3U' } { [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength Algorithm = [EncryptionAlgorithm]$binaryReader.ReadByte() HashBytes = [Convert]::ToBase64String($binaryReader.ReadBytes($optionLength - 1)) } break } default { [PSCustomObject]@{ OptionCode = $optionCode OptionLength = $optionLength OptionData = $binaryReader.ReadBytes($optionLength) } } } } } hidden [IEnumerable[byte]] RecordDataToByteArray() { return [byte[]]::new(0) } [byte[]] ToByteArray( [bool] $useCompressedNames ) { $bytes = [List[byte]]::new() $bytes.Add(0) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.RecordType, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes($this.MaximumPayloadSize, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes($this.ExtendedRCode, $true)) $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$this.Z, $true)) $recordDataBytes = $this.RecordDataToByteArray() $bytes.AddRange([EndianBitConverter]::GetBytes([UInt16]$recordDataBytes.Count, $true)) $bytes.AddRange($recordDataBytes) return $bytes.ToArray() } } #EndRegion '.\class\2.RecordTypes\DnsOPTRecord.ps1' 255 #Region '.\class\2.RecordTypes\DnsPTRRecord.ps1' 0 class DnsPTRRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PTRDNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $Hostname DnsPTRRecord() : base() { } DnsPTRRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return $this.Hostname } } #EndRegion '.\class\2.RecordTypes\DnsPTRRecord.ps1' 34 #Region '.\class\2.RecordTypes\DnsPXRecord.ps1' 0 class DnsPXRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MAP822 / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MAPX400 / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2163.txt #> [UInt16] $Preference [string] $MAP822 [string] $MAPX400 DnsPXRecord() : base() { } DnsPXRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.MAP822 = $binaryReader.ReadDnsDomainName() $this.MAPX400 = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0,-5} {1} {2}' -f @( $this.Preference $this.MAP822 $this.MAPX400 ) } } #EndRegion '.\class\2.RecordTypes\DnsPXRecord.ps1' 47 #Region '.\class\2.RecordTypes\DnsRKEYRecord.ps1' 0 #using namespace System.Collections.Generic class DnsRKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FLAGS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PROTOCOL | ALGORITHM | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PUBLIC KEY / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/html/draft-reid-dnsext-rkey-00 #> [UInt16] $Flags [KEYProtocol] $Protocol [EncryptionAlgorithm] $Algorithm [string] $PublicKey DnsRKEYRecord() : base() { } DnsRKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Flags = $binaryReader.ReadUInt16($true) $this.Protocol = $binaryReader.ReadByte() $this.Algorithm = $binaryReader.ReadByte() $keyLength = $this.RecordDataLength - 4 $this.PublicKey = [Convert]::ToBase64String($binaryReader.ReadBytes($keyLength)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.Flags $this.Protocol $this.Algorithm $this.PublicKey -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsRKEYRecord.ps1' 54 #Region '.\class\2.RecordTypes\DnsRPRecord.ps1' 0 class DnsRPRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / RMAILBX / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXTDNAME / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1183.txt #> [string] $ResponsibleMailbox [string] $DomainName DnsRPRecord() : base() { } DnsRPRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.ResponsibleMailbox = $binaryReader.ReadDnsDomainName() $this.DomainName = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.ResponsibleMailbox $this.DomainName ) } } #EndRegion '.\class\2.RecordTypes\DnsRPRecord.ps1' 40 #Region '.\class\2.RecordTypes\DnsRRSIGRecord.ps1' 0 class DnsRRSIGRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TYPE COVERED | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | LABELS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ORIGINAL TTL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SIGNATURE EXPIRATION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SIGNATURE INCEPTION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEY TAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SIGNER'S NAME / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SIGNATURE / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc3755.txt http://www.ietf.org/rfc/rfc4034.txt #> [DnsRecordType] $TypeCovered [EncryptionAlgorithm] $Algorithm [byte] $Labels [UInt32] $OriginalTTL [DateTime] $SignatureExpiration [DateTime] $SignatureInception [UInt16] $KeyTag [string] $SignersName [string] $Signature DnsRRSIGRecord() : base() { } DnsRRSIGRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.TypeCovered = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.Labels = $binaryReader.ReadByte() $this.OriginalTTL = $binaryReader.ReadUInt32($true) $this.SignatureExpiration = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.SignatureInception = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.KeyTag = $binaryReader.ReadUInt16($true) $length = 0 $this.SignersName = $binaryReader.ReadDnsDomainName([ref]$length) $this.Signature = [Convert]::ToBase64String($binaryReader.ReadBytes($this.RecordDataLength - 18 - $length)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2} {3} {4:yyyyMMddHHmmss} {5:yyyyMMddHHmmss} {6} {7} {8}' -f @( $this.TypeCovered $this.Algorithm $this.Labels $this.OriginalTTL $this.SignatureExpiration $this.SignatureInception $this.KeyTag $this.SignersName $this.Signature -split '(?<=\G.{56})' -join ' ' ) } [string] ToLongString() { return ( @( '{0} {1:D} {2} ( ; type-cov={0}, alg={1}, labels={2}' ' {3,-16} ; OriginalTTL' ' {4,-16:yyyyMMddHHmmss} ; Signature expiration ({4:u})' ' {5,-16:yyyyMMddHHmmss} ; Signature inception ({5:u})' ' {6,-16} ; Key identifier' ' {7,-16} ; Signer' ' {8,-16} ; Signature' ')' ) -join "`n" ) -f @( $this.TypeCovered $this.Algorithm $this.Labels $this.OriginalTTL $this.SignatureExpiration $this.SignatureInception $this.KeyTag $this.SignersName $this.Signature -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsRRSIGRecord.ps1' 108 #Region '.\class\2.RecordTypes\DnsRTRecord.ps1' 0 class DnsRTRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PREFERENCE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / INTERMEDIATEHOST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1183.txt #> [UInt16] $Preference [string] $IntermediateHost DnsRTRecord() : base() { } DnsRTRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Preference = $binaryReader.ReadUInt16($true) $this.IntermediateHost = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Preference, $this.IntermediateHost ) } } #EndRegion '.\class\2.RecordTypes\DnsRTRecord.ps1' 42 #Region '.\class\2.RecordTypes\DnsSIGRecord.ps1' 0 #using namespace Indented.IO #using namespace Indented.Net.Dns class DnsSIGRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TYPE COVERED | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | LABELS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ORIGINAL TTL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SIGNATURE EXPIRATION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SIGNATURE INCEPTION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEY TAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SIGNER'S NAME / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SIGNATURE / / / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2535.txt http://www.ietf.org/rfc/rfc2931.txt #> [DnsRecordType] $TypeCovered [EncryptionAlgorithm] $Algorithm [byte] $Labels [UInt32] $OriginalTTL [DateTime] $SignatureExpiration [DateTime] $SignatureInception [UInt16] $KeyTag [string] $SignersName [string] $Signature DnsSIGRecord() : base() { } DnsSIGRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.TypeCovered = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.Labels = $binaryReader.ReadByte() $this.OriginalTTL = $binaryReader.ReadUInt32($true) $this.SignatureExpiration = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.SignatureInception = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.KeyTag = $binaryReader.ReadUInt16($true) $length = 0 $this.SignersName = $binaryReader.ReadDnsDomainName([ref]$length) $this.Signature = [Convert]::ToBase64String($binaryReader.ReadBytes($this.RecordDataLength - 18 - $length)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2} {3} {4:yyyyMMddHHmmss} {5:yyyyMMddHHmmss} {6} {7} {8}' -f @( $this.TypeCovered $this.Algorithm $this.Labels $this.OriginalTTL $this.SignatureExpiration $this.SignatureInception $this.KeyTag $this.SignersName $this.Signature -split '(?<=\G.{56})' -join ' ' ) } [string] ToLongString() { return ( @( '{0} {1:D} {2} ( ; type-cov={0}, alg={1}, labels={2}' ' {3,-16} ; OriginalTTL' ' {4,-16:yyyyMMddHHmmss} ; Signature expiration ({4:u})' ' {5,-16:yyyyMMddHHmmss} ; Signature inception ({5:u})' ' {6,-16} ; Key identifier' ' {7,-16} ; Signer' ' {8,-16} ; Signature' ')' ) -join "`n" ) -f @( $this.TypeCovered $this.Algorithm $this.Labels $this.OriginalTTL $this.SignatureExpiration $this.SignatureInception $this.KeyTag $this.SignersName $this.Signature -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsSIGRecord.ps1' 111 #Region '.\class\2.RecordTypes\DnsSINKRecord.ps1' 0 class DnsSINKRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CODING | SUBCODING | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/id/draft-eastlake-kitchen-sink-02.txt The structure above is modified to match dig. Adding a meaning byte. #> [byte] $Meaning [byte] $Coding [byte] $Subcoding [string] $Data DnsSINKRecord() : base() { } DnsSINKRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Meaning = $binaryReader.ReadByte() $this.Coding = $binaryReader.ReadByte() $this.Subcoding = $binaryReader.ReadByte() $dataLength = $this.RecordDataLength - 3 if ($dataLength -gt 0) { $this.Data = [Convert]::ToBase64String($binaryReader.ReadBytes($dataLength)) } } hidden [string] RecordDataToString() { if ($this.Data) { return '{0:D} {1:D} {2:D} {3}' -f @( $this.Meaning $this.Coding $this.Subcoding $this.Data ) } else { return '{0:D} {1:D} {2:D}' -f @( $this.Meaning $this.Coding $this.Subcoding ) } } } #EndRegion '.\class\2.RecordTypes\DnsSINKRecord.ps1' 61 #Region '.\class\2.RecordTypes\DnsSMIMEARecord.ps1' 0 class DnsSMIMEARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CERT USAGE | SELECTOR | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | MATCHING TYPE | / +--+--+--+--+--+--+--+--+ / / CERT ASSOCIATION DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://tools.ietf.org/html/rfc8162 #> [CertificateUsage] $CertificateUsage [Selector] $Selector [MatchingType] $MatchingType [string] $CertificateAssociation DnsSMIMEARecord() : base() { } DnsSMIMEARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.CertificateUsage = $binaryReader.ReadByte() $this.Selector = $binaryReader.ReadByte() $this.MatchingType = $binaryReader.ReadByte() $this.CertificateAssociation = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength - 3)) } hidden [string] RecordDataToString() { return '{0:D} {1:D} {2:D} {3}' -f @( $this.CertificateUsage $this.Selector $this.MatchingType $this.CertificateAssociation -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsSMIMEARecord.ps1' 49 #Region '.\class\2.RecordTypes\DnsSOARecord.ps1' 0 #using namespace System.Collections.Generic class DnsSOARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / RNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERIAL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | REFRESH | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | RETRY | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | EXPIRE | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | MINIMUM | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $NameServer [string] $ResponsiblePerson [UInt32] $Serial [UInt32] $Refresh [UInt32] $Retry [UInt32] $Expire [UInt32] $MinimumTTL DnsSOARecord() : base() { } DnsSOARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.NameServer = $binaryReader.ReadDnsDomainName() $this.ResponsiblePerson = $binaryReader.ReadDnsDomainName() $this.Serial = $binaryReader.ReadUInt32($true) $this.Refresh = $binaryReader.ReadUInt32($true) $this.Retry = $binaryReader.ReadUInt32($true) $this.Expire = $binaryReader.ReadUInt32($true) $this.MinimumTTL = $binaryReader.ReadUInt32($true) } hidden [string] RecordDataToString() { return '{0} {1} {2} {3} {4} {5} {6}' -f @( $this.NameServer $this.ResponsiblePerson $this.Serial $this.Refresh $this.Retry $this.Expire $this.MinimumTTL ) } hidden [byte[]] RecordDataToByteArray( [bool] $useCompressedNames ) { $bytes = [List[byte]]::new() if ($useCompressedNames) { # MNAME $bytes.AddRange([byte[]](0xC0, 0x0C)) # RNAME $bytes.AddRange([byte[]](0xC0, 0x0C)) } else { $bytes.AddRange([EndianBinaryReader]::GetDnsDomainNameBytes($this.NameServer)) # RNAME $bytes.AddRange([EndianBinaryReader]::GetDnsDomainNameBytes($this.ResponsiblePerson)) } # SerialNumber $bytes.AddRange([EndianBitConverter]::GetBytes($this.Serial, $true)) $bytes.AddRange([byte[]]::new(16)) return $bytes.ToArray() } [string] ToLongString() { return ( @( '{0} {1} (' ' {2,-10} ; serial' ' {3,-10} ; refresh ({4})' ' {5,-10} ; retry ({6})' ' {7,-10} ; expire ({8})' ' {9,-10} ; minimum ttl ({10})' ')' ) -join "`n" ) -f @( $this.NameServer $this.ResponsiblePerson $this.Serial $this.Refresh (ConvertToTimeSpanString -Seconds $this.Refresh) $this.Retry (ConvertToTimeSpanString -Seconds $this.Retry) $this.Expire (ConvertToTimeSpanString -Seconds $this.Expire) $this.MinimumTTL (ConvertToTimeSpanString -Seconds $this.MinimumTTL) ) } } #EndRegion '.\class\2.RecordTypes\DnsSOARecord.ps1' 123 #Region '.\class\2.RecordTypes\DnsSPFRecord.ps1' 0 class DnsSPFRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXT-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string[]] $SPF DnsSPFRecord() : base() { } DnsSPFRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = $this.RecordDataLength if ($length -gt 0) { $this.SPF = do { $entryLength = 0 $binaryReader.ReadDnsCharacterString([ref]$entryLength) $length -= $entryLength } until ($length -le 0) } } hidden [string] RecordDataToString() { return '"{0}"' -f ($this.SPF -join '" "') } } #EndRegion '.\class\2.RecordTypes\DnsSPFRecord.ps1' 42 #Region '.\class\2.RecordTypes\DnsSRVRecord.ps1' 0 class DnsSRVRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PRIORITY | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | WEIGHT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PORT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TARGET / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2782.txt #> [UInt16] $Priority [UInt16] $Weight [UInt16] $Port [string] $Hostname DnsSRVRecord() : base() { } DnsSRVRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Priority = $binaryReader.ReadUInt16($true) $this.Weight = $binaryReader.ReadUInt16($true) $this.Port = $binaryReader.ReadUInt16($true) $this.Hostname = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1} {2} {3}' -f @( $this.Priority $this.Weight $this.Port $this.Hostname ) } } #EndRegion '.\class\2.RecordTypes\DnsSRVRecord.ps1' 52 #Region '.\class\2.RecordTypes\DnsSSHFPRecord.ps1' 0 class DnsSSHFPRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | FPTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / FINGERPRINT / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc4255.txt #> [SSHAlgorithm] $Algorithm [SSHFPType] $FPType [string] $Fingerprint DnsSSHFPRecord() : base() { } DnsSSHFPRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Algorithm = $binaryReader.ReadByte() $this.FPType = $binaryReader.ReadByte() $this.FingerPrint = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength - 2)) } hidden [string] RecordDataToString() { return '{0:D} {1:D} {2}' -f @( $this.Algorithm $this.FPType $this.Fingerprint -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsSSHFPRecord.ps1' 44 #Region '.\class\2.RecordTypes\DnsTALINKRecord.ps1' 0 class DnsTALINKRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / PREV / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / NEXT / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template #> [string] $Previous [string] $Next DnsTALINKRecord() : base() { } DnsTALINKRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Previous = $binaryReader.ReadDnsDomainName() $this.Next = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { return '{0} {1}' -f @( $this.Previous $this.Next ) } } #EndRegion '.\class\2.RecordTypes\DnsTALINKRecord.ps1' 42 #Region '.\class\2.RecordTypes\DnsTARecord.ps1' 0 class DnsTARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEYTAG | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ALGORITHM | DIGESTTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DIGEST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://tools.ietf.org/html/draft-lewis-dns-undocumented-types-01 #> [UInt16] $KeyTag [EncryptionAlgorithm] $Algorithm [DigestType] $DigestType [string] $Digest DnsTARecord() : base() { } DnsTARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.KeyTag = $binaryReader.ReadUInt16($true) $this.Algorithm = $binaryReader.ReadByte() $this.DigestType = $binaryReader.ReadByte() $this.Digest = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength - 4)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2:D} {3}' -f @( $this.KeyTag $this.Algorithm $this.DigestType $this.Digest ) } } #EndRegion '.\class\2.RecordTypes\DnsTARecord.ps1' 49 #Region '.\class\2.RecordTypes\DnsTKEYRecord.ps1' 0 class DnsTKEYRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ALGORITHM / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | INCEPTION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | EXPIRATION | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | MODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ERROR | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | KEYSIZE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / KEYDATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OTHERSIZE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / OTHERDATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2930.txt #> [string] $Algorithm [DateTime] $Inception [DateTime] $Expiration [TKEYMode] $Mode [RCode] $TKEYError [string] $KeyData [string] $OtherData DnsTKEYRecord() : base() { } DnsTKEYRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Algorithm = $binaryReader.ReadDnsDomainName() $this.Inception = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.Expiration = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt32($true)) $this.Mode = $binaryReader.ReadUInt16($true) $this.TKEYError = $binaryReader.ReadUInt16($true) $keySize = $binaryReader.ReadUInt16($true) $this.KeyData = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($keySize)) $otherSize = $binaryReader.ReadUInt16($true) if ($otherSize -gt 0) { $this.OtherData = [EndianBitConverter]::ToHexadecimal($BinaryReader.ReadBytes($otherSize)) } } hidden [string] RecordDataToString() { return '{0} {1:yyyyMMddHHmmss} {2:yyyyMMddHHmmss} {3:D} {4} {5}' -f @( $this.Algorithm $this.Inception $this.Expiration $this.Mode $this.KeyData $this.OtherData ) } } #EndRegion '.\class\2.RecordTypes\DnsTKEYRecord.ps1' 79 #Region '.\class\2.RecordTypes\DnsTLSARecord.ps1' 0 class DnsTLSARecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CERT USAGE | SELECTOR | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | MATCHING TYPE | / +--+--+--+--+--+--+--+--+ / / CERT ASSOCIATION DATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc6698.txt #> [CertificateUsage] $CertificateUsage [Selector] $Selector [MatchingType] $MatchingType [string] $CertificateAssociation DnsTLSARecord() : base() { } DnsTLSARecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.CertificateUsage = $binaryReader.ReadByte() $this.Selector = $binaryReader.ReadByte() $this.MatchingType = $binaryReader.ReadByte() $this.CertificateAssociation = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength - 3)) } hidden [string] RecordDataToString() { return '{0:D} {1:D} {2:D} {3}' -f @( $this.CertificateUsage $this.Selector $this.MatchingType $this.CertificateAssociation -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsTLSARecord.ps1' 49 #Region '.\class\2.RecordTypes\DnsTSIGRecord.ps1' 0 class DnsTSIGRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / ALGORITHM / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TIMESIGNED | | | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | FUDGE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | MACSIZE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / MAC / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ORIGINALID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ERROR | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | OTHERSIZE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / OTHERDATA / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc2845.txt #> [string] $Algorithm [DateTime] $TimeSigned [UInt16] $Fudge [string] $MAC [UInt16] $OriginalID [RCode] $TSIGError [string] $OtherData DnsTSIGRecord() : base() { } DnsTSIGRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Algorithm = $binaryReader.ReadDnsDomainName() $this.TimeSigned = (Get-Date '01/01/1970').AddSeconds($binaryReader.ReadUInt48($true)) $this.Fudge = $binaryReader.ReadUInt16($true) $macSize = $binaryReader.ReadUInt16($true) $this.MAC = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($macSize)) $this.OriginalID = $binaryReader.ReadUInt16($true) $this.TSIGError = $binaryReader.ReadUInt16($true) $otherSize = $binaryReader.ReadUInt16($true) if ($otherSize -gt 0) { $this.OtherData = [EndianBitConverter]::ToHexadecimal($BinaryReader.ReadBytes($otherSize)) } } hidden [string] RecordDataToString() { return '{0} {1:yyyyMMddHHmmss} {2} {3} {4} {5:D} {6}' -f @( $this.Algorithm $this.TimeSigned $this.Fudge $this.MAC $this.OriginalID $this.TSIGError $this.OtherData ) } } #EndRegion '.\class\2.RecordTypes\DnsTSIGRecord.ps1' 82 #Region '.\class\2.RecordTypes\DnsTXTRecord.ps1' 0 class DnsTXTRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXT-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string[]] $Text DnsTXTRecord() : base() { } DnsTXTRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $length = $this.RecordDataLength if ($length -gt 0) { $this.Text = do { $entryLength = 0 $binaryReader.ReadDnsCharacterString([ref]$entryLength) $length -= $entryLength } until ($length -le 0) } } hidden [string] RecordDataToString() { return '"{0}"' -f ($this.Text -join '" "') } } #EndRegion '.\class\2.RecordTypes\DnsTXTRecord.ps1' 42 #Region '.\class\2.RecordTypes\DnsUIDRecord.ps1' 0 class DnsUIDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / UID / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ IANA-Reserved #> [byte[]] $Data DnsUIDRecord() : base() { } DnsUIDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Data = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return '\# {0} {1}' -f @( $this.Data.Length [EndianBitConverter]::ToHexadecimal($this.Data) ) } } #EndRegion '.\class\2.RecordTypes\DnsUIDRecord.ps1' 36 #Region '.\class\2.RecordTypes\DnsUINFORecord.ps1' 0 class DnsUINFORecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / UINFO / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ IANA-Reserved #> [byte[]] $Data DnsUINFORecord() : base() { } DnsUINFORecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Data = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return '\# {0} {1}' -f @( $this.Data.Length [EndianBitConverter]::ToHexadecimal($this.Data) ) } } #EndRegion '.\class\2.RecordTypes\DnsUINFORecord.ps1' 36 #Region '.\class\2.RecordTypes\DnsUNKNOWNRecord.ps1' 0 class DnsUNKNOWNRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / <anything> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [byte[]] $BinaryData DnsUNKNOWNRecord() : base() { } DnsUNKNOWNRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.BinaryData = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return [Convert]::ToBase64String($this.BinaryData) } } #EndRegion '.\class\2.RecordTypes\DnsUNKNOWNRecord.ps1' 32 #Region '.\class\2.RecordTypes\DnsUNSPECRecord.ps1' 0 class DnsUNSPECRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / UNSPEC / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ IANA-Reserved #> [byte[]] $Data DnsUNSPECRecord() : base() { } DnsUNSPECRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Data = $binaryReader.ReadBytes($this.RecordDataLength) } hidden [string] RecordDataToString() { return '\# {0} {1}' -f @( $this.Data.Length [EndianBitConverter]::ToHexadecimal($this.Data) ) } } #EndRegion '.\class\2.RecordTypes\DnsUNSPECRecord.ps1' 36 #Region '.\class\2.RecordTypes\DnsUriRecord.ps1' 0 class DnsURIRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PRIORITY | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | WEIGHT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TARGET / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://tools.ietf.org/html/rfc7553 #> [UInt16] $Priority [UInt16] $Weight [string] $Target DnsURIRecord() : base() { } DnsURIRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Priority = $binaryReader.ReadUInt16($true) $this.Weight = $binaryReader.ReadUInt16($true) $this.Target = [string]::new( $binaryReader.ReadChars( $this.RecordDataLength - 4 ) ) } hidden [string] RecordDataToString() { return '{0} {1} "{2}"' -f @( $this.Priority $this.Weight $this.Target ) } } #EndRegion '.\class\2.RecordTypes\DnsUriRecord.ps1' 51 #Region '.\class\2.RecordTypes\DnsWINSRecord.ps1' 0 class DnsWINSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOCAL FLAG | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOOKUP TIMEOUT | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CACHE TIMEOUT | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NUMBER OF SERVERS | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / SERVER IP LIST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://msdn.microsoft.com/en-us/library/ms682748%28VS.85%29.aspx #> [WINSMappingFlag] $MappingFlag [UInt32] $LookupTimeout [UInt32] $CacheTimeout [IPAddress[]] $ServerList DnsWINSRecord() : base() { } DnsWINSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.MappingFlag = $binaryReader.ReadUInt32($true) $this.LookupTimeout = $binaryReader.ReadUInt32($true) $this.CacheTimeout = $binaryReader.ReadUInt32($true) $numberOfServers = $binaryReader.ReadUInt32($true) $this.ServerList = for ($i = 0; $i -lt $numberOfServers; $i++) { $binaryReader.ReadIPAddress() } } hidden [string] RecordDataToString() { $value = 'L{0} C{1} ( {2} )' -f @( $this.LookupTimeout $this.CacheTimeout $this.ServerList -join ' ' ) if ($this.MappingFlag -eq 0x10000) { return 'LOCAL {0}' -f $value } return $value } } #EndRegion '.\class\2.RecordTypes\DnsWINSRecord.ps1' 65 #Region '.\class\2.RecordTypes\DnsWINSRRecord.ps1' 0 class DnsWINSRRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOCAL FLAG | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | LOOKUP TIMEOUT | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CACHE TIMEOUT | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NUMBER OF DOMAINS | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DOMAIN NAME LIST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://msdn.microsoft.com/en-us/library/ms682748%28VS.85%29.aspx #> [WINSMappingFlag] $MappingFlag [UInt32] $LookupTimeout [UInt32] $CacheTimeout [string] $DomainToAppend DnsWINSRRecord() : base() { } DnsWINSRRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.MappingFlag = $binaryReader.ReadUInt32($true) $this.LookupTimeout = $binaryReader.ReadUInt32($true) $this.CacheTimeout = $binaryReader.ReadUInt32($true) $this.DomainToAppend = $binaryReader.ReadDnsDomainName() } hidden [string] RecordDataToString() { $value = 'L{0} C{1} ( {2} )' -f @( $this.LookupTimeout $this.CacheTimeout $this.DomainToAppend ) if ($this.MappingFlag -eq 0x10000) { return 'LOCAL {0}' -f $value } return $value } } #EndRegion '.\class\2.RecordTypes\DnsWINSRRecord.ps1' 61 #Region '.\class\2.RecordTypes\DnsWKSRecord.ps1' 0 #using namespace System.Net.Sockets #using namespace System.Text class DnsWKSRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ADDRESS | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | PROTOCOL | / +--+--+--+--+--+--+--+--+ / / / / <BIT MAP> / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt http://www.ietf.org/rfc/rfc1010.txt #> [IPAddress] $IPAddress [byte] $IPProtocolNumber [ProtocolType] $IPProtocolType [string] $BitMap [UInt16[]] $Ports DnsWKSRecord() : base() { } DnsWKSRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.IPAddress = $binaryReader.ReadIPAddress() $this.IPProtocolNumber = $binaryReader.ReadByte() $this.IPProtocolType = $this.IPProtocolNumber $bitmapBytes = $binaryReader.ReadBytes($this.RecordDataLength - 5) foreach ($byte in $bitmapBytes) { $this.BitMap += [Convert]::ToString($byte, 2).PadLeft(8, '0') } $this.Ports = for ($i = 0; $i -lt $this.BitMap.Length; $i++) { if ($this.BitMap[$i] -eq '1') { $i } } } hidden [string] RecordDataToString() { return '{0} {1} {2}' -f @( $this.IPAddress $this.IPProtocolNumber $this.Ports -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsWKSRecord.ps1' 65 #Region '.\class\2.RecordTypes\DnsX25Record.ps1' 0 class DnsX25Record : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXT-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ http://www.ietf.org/rfc/rfc1035.txt #> [string] $PSDNAddress DnsX25Record() : base() { } DnsX25Record( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.PSDNAddress = $binaryReader.ReadDnsCharacterString() } hidden [string] RecordDataToString() { return '"{0}"' -f $this.PSDNAddress } } #EndRegion '.\class\2.RecordTypes\DnsX25Record.ps1' 33 #Region '.\class\2.RecordTypes\DnsZONEMDRecord.ps1' 0 class DnsZONEMDRecord : DnsResourceRecord { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | SERIAL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | DIGEST-TYPE | RESERVED | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / DIGEST / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ https://tools.ietf.org/html/draft-wessels-dns-zone-digest-06 #> [UInt32] $Serial [ZONEMDDigestType] $DigestType [byte] $Reserved [string] $Digest DnsZONEMDRecord() : base() { } DnsZONEMDRecord( [DnsResourceRecord] $dnsResourceRecord, [EndianBinaryReader] $binaryReader ) : base( $dnsResourceRecord, $binaryReader ) { } hidden [void] ReadRecordData( [EndianBinaryReader] $binaryReader ) { $this.Serial = $binaryReader.ReadUInt32($true) $this.DigestType = $binaryReader.ReadByte() $this.Reserved = $binaryReader.ReadByte() $this.Digest = [EndianBitConverter]::ToHexadecimal($binaryReader.ReadBytes($this.RecordDataLength - 6)) } hidden [string] RecordDataToString() { return '{0} {1:D} {2} {3}' -f @( $this.Serial $this.DigestType $this.Reserved $this.Digest -split '(?<=\G.{56})' -join ' ' ) } } #EndRegion '.\class\2.RecordTypes\DnsZONEMDRecord.ps1' 50 #Region '.\class\3.Message\DnsMessage.ps1' 0 #using namespace System.Collections #using namespace System.Collections.Generic #using namespace System.Text #using namespace System.IO class DnsMessage { <# 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / HEADER / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / QUESTION / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / ANSWER / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / AUTHORITY / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / / / ADDITIONAL / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ #> [DnsHeader] $Header [DnsQuestion[]] $Question [DnsResourceRecord[]] $Answer [DnsResourceRecord[]] $Authority [DnsResourceRecord[]] $Additional [Int] $Size [Int64] $TimeTaken [string] $ComputerName DnsMessage() { } DnsMessage( [string] $name, [RecordType] $recordType ) { $this.Header = [DnsHeader]::new($true, 1) $this.Question = [DnsQuestion]::new($name, $recordType, 'IN') } DnsMessage( [string] $name, [RecordType] $recordType, [RecordClass] $recordClass ) { $this.Header = [DnsHeader]::new($true, 1) $this.Question = [DnsQuestion]::new($name, $recordType, $recordClass) } DnsMessage( [string] $name, [RecordType] $recordType, [RecordClass] $recordClass, [UInt32] $Serial ) { $this.Header = [DnsHeader]::new($true, 1) $this.Question = [DnsQuestion]::new($name, $recordType, $recordClass) $this.Header.AuthorityCount = 1 $this.Authority = [DnsSOARecord]@{ Serial = $Serial } } DnsMessage( [byte[]] $message ) { $this.ReadDnsMessage($message, $true) } DnsMessage( [byte[]] $message, [bool] $convertIdnToUnicode ) { $this.ReadDnsMessage($message, $convertIdnToUnicode) } hidden [void] ReadDnsMessage( [byte[]] $message, [bool] $convertIdnToUnicode ) { $binaryReader = [EndianBinaryReader][MemoryStream]$message $binaryReader.ConvertIdnToUnicode = $convertIdnToUnicode $this.Size = $message.Length $this.Header = [DnsHeader]$binaryReader $this.Question = for ($i = 0; $i -lt $this.Header.QuestionCount; $i++) { [DnsQuestion]$binaryReader } $this.Answer = for ($i = 0; $i -lt $this.Header.AnswerCount; $i++) { [DnsResourceRecord]::Parse($binaryReader) } $this.Authority = for ($i = 0; $i -lt $this.Header.AuthorityCount; $i++) { [DnsResourceRecord]::Parse($binaryReader) } $this.Additional = for ($i = 0; $i -lt $this.Header.AdditionalCount; $i++) { [DnsResourceRecord]::Parse($binaryReader) } } hidden [string] RecordSetToString( [DnsResourceRecord[]] $resourceRecords ) { if ($resourceRecords.Count -gt 0) { $string = [StringBuilder]::new() foreach ($resourceRecord in $resourceRecords) { if ($resourceRecord.RecordType -ne [RecordType]::OPT) { $string.AppendLine($resourceRecord.ToString()) } } return $string.ToString().TrimEnd() } return '' } [string] QuestionToString() { $string = [StringBuilder]::new() foreach ($question in $this.Question) { $string.AppendLine($question.ToString()) } return $string.ToString().TrimEnd() } [string] AnswerToString() { return $this.RecordSetToString($this.Answer) } [string] AuthorityToString() { return $this.RecordSetToString($this.Authority) } [string] AdditionalToString() { return $this.RecordSetToString($this.Additional) } [void] SetEDnsBufferSize() { $this.SetEDnsBufferSize(4096) } [void] SetEDnsBufferSize([UInt16]$EDnsBufferSize) { $this.Header.AdditionalCount = 1 $this.Additional = [DnsOPTRecord]@{ MaximumPayloadSize = $EDnsBufferSize Z = [EDnsDNSSECOK]::DO } } [void] SetAcceptDnsSec() { $this.Header.Flags = $this.Header.Flags -bor [HeaderFlags]::AD } [void] DisableRecursion() { $this.Header.Flags = [UInt16]$this.Header.Flags -bxor [UInt16][HeaderFlags]::RD } [byte[]] ToByteArray() { return $this.ToByteArray($false, $true) } [byte[]] ToByteArray( [bool] $useCompressedNames ) { return $this.ToByteArray($false, $useCompressedNames) } [byte[]] ToByteArray( [bool] $tcp, [bool] $useCompressedNames ) { $bytes = [List[byte]]::new() $bytes.AddRange($this.Header.ToByteArray()) $bytes.AddRange([byte[]]$this.Question.ToByteArray()) if ($this.Header.AuthorityCount -gt 0) { foreach ($resourceRecord in $this.Authority) { $bytes.AddRange($resourceRecord.ToByteArray($useCompressedNames)) } } if ($this.Header.AdditionalCount -gt 0) { foreach ($resourceRecord in $this.Additional) { $bytes.AddRange($resourceRecord.ToByteArray()) } } if ($tcp) { $length = [BitConverter]::GetBytes([UInt16]$bytes.Count) [Array]::Reverse($length) $bytes.InsertRange(0, $length) } return $bytes.ToArray() } } #EndRegion '.\class\3.Message\DnsMessage.ps1' 206 #Region '.\class\4.Client\DnsClient.ps1' 0 #using namespace System.Collections.Generic #using namespace System.Diagnostics #using namespace System.Net #using namespace System.Net.Sockets class DnsClient { [int] $BufferSize = 4096 [EndPoint] $RemoteEndPoint [Timespan] $TimeTaken hidden [Socket] $socket DnsClient() { $this.Initialize($false, $false, 5, 5) } DnsClient( [bool] $useTcp, [bool] $useIPv6 ) { $this.Initialize($useTcp, $useIPv6, 5, 5) } DnsClient( [bool] $useTcp, [bool] $useIPv6, [int] $receiveTimeout, [int] $sendTimeout ) { $this.Initialize($useTcp, $useIPv6, $receiveTimeout, $sendTimeout) } hidden [void] Initialize( [bool] $useTcp, [bool] $useIPv6, [int] $receiveTimeout, [int] $sendTimeout ) { $addressFamily = 'InterNetwork' if ($useIPv6) { $addressFamily = 'InterNetworkV6' } if ($useTcp) { $this.Socket = [Socket]::new($addressFamily, 'Stream', 'Tcp') } else { $this.Socket = [Socket]::new($addressFamily, 'Dgram', 'Udp') } $this.Socket.ReceiveTimeout = $receiveTimeout * 1000 $this.Socket.SendTimeout = $sendTimeout * 1000 } [void] SendQuestion( [DnsMessage] $message, [IPAddress] $ipAddress ) { $this.SendQuestion( $message, $ipAddress, 53 ) } [void] SendQuestion( [DnsMessage] $message, [IPAddress] $ipAddress, [UInt16] $port ) { try { $stopWatch = [StopWatch]::StartNew() $this.RemoteEndPoint = [EndPoint][IPEndPoint]::new($ipAddress, $port) if ($this.socket.ProtocolType -eq 'Tcp') { try { $this.socket.Connect($this.RemoteEndPoint) $this.socket.Send($message.ToByteArray($true, $true)) } catch { throw } } else { $null = $this.socket.SendTo( $message.ToByteArray($false, $true), $this.RemoteEndPoint ) } } catch { throw } finally { $stopWatch.Stop() $this.TimeTaken = $stopWatch.Elapsed } } [DnsMessage] ReceiveAnswer() { return $this.ReceiveAnswer($true) } [DnsMessage] ReceiveAnswer( [bool] $convertIdnToUnicode ) { try { $stopWatch = [StopWatch]::StartNew() $messageBytes = $this.ReceiveBytes() return [DnsMessage]::new($messageBytes, $convertIdnToUnicode) } catch { throw } finally { $stopWatch.Stop() $this.TimeTaken += $stopWatch.Elapsed } } [byte[]] ReceiveBytes() { try { $buffer = [byte[]]::new($this.bufferSize) if ($this.socket.ProtocolType -eq 'Tcp') { $bytesReceived = $this.socket.Receive($buffer) $length = [BitConverter]::ToUInt16(($buffer[1, 0]), 0) $messageBytes = [byte[]]::new($length) [Array]::Copy( $buffer, 2, $messageBytes, 0, $bytesReceived - 2 ) $totalBytesReceived = $bytesReceived while ($totalBytesReceived -lt $length) { $bytesReceived = $this.socket.Receive($buffer) [Array]::Copy( $buffer, 0, $messageBytes, $totalBytesReceived - 2, $bytesReceived ) $totalBytesReceived += $bytesReceived } $this.RemoteEndPoint = $this.socket.RemoteEndPoint } else { if ($this.socket.AddressFamily -eq 'InterNetwork') { $endPoint = [IPEndPoint]::new([IPAddress]::Any, 0) } else { $endPoint = [IPEndPoint]::new([IPAddress]::IPv6Any, 0) } $bytesReceived = $this.socket.ReceiveFrom($buffer, [ref]$endPoint) $this.RemoteEndPoint = $endPoint $messageBytes = [byte[]]::new($bytesReceived) [Array]::Copy( $buffer, $messageBytes, $bytesReceived ) } return $messageBytes } catch { throw } } [void] Close() { if ($this.socket.ProtocolType -eq 'Tcp') { $this.socket.Shutdown([SocketShutdown]::Both) $this.socket.Disconnect($true) } $this.socket.Close() } } #EndRegion '.\class\4.Client\DnsClient.ps1' 180 #Region '.\class\5.Cache\DnsCacheRecord.ps1' 0 class DnsCacheRecord { [string] $Name [UInt32] $TTL [DnsRecordType] $RecordType [IPAddress] $IPAddress [CacheResourceType] $ResourceType = 'Address' [DateTime] $TimeAdded = (Get-Date) [bool] $IsPermanent DnsCacheRecord() { } DnsCacheRecord( [DnsARecord] $dnsRecord ) { $this.Initialize($dnsRecord) } DnsCacheRecord( [DnsAAAARecord] $dnsRecord ) { $this.Initialize($dnsRecord) } hidden Initialize( $dnsRecord ) { $this.Name = $dnsRecord.Name $this.TTL = $dnsRecord.TTL $this.RecordType = $dnsRecord.RecordType $this.IPAddress = $dnsRecord.IPAddress } static [DnsCacheRecord] Parse( [string] $recordData ) { if ($recordData -match '(?<Name>\S+)\s+(?<TTL>\d+)\s+(IN)?\s*(?<RecordType>A|AAAA)\s+(?<IPAddress>\S+)') { $matches.Remove(0) return [DnsCacheRecord]$matches } else { throw 'Invalid record data format' } } [bool] HasExpired() { if ($this.IsPermanent) { return $false } return $this.TimeAdded.AddSeconds($this.TTL) -lt (Get-Date) } } #EndRegion '.\class\5.Cache\DnsCacheRecord.ps1' 52 #Region '.\private\ConvertToTimeSpanString.ps1' 0 function ConvertToTimeSpanString { <# .SYNOPSIS Converts a number of seconds to a string. .DESCRIPTION ConvertToTimeSpanString accepts values in seconds then uses integer division to represent that time as a string. ConvertToTimeSpanString accepts UInt32 values, overcoming the Int32 type limitation built into New-TimeSpan. The format below is used, omitting any values of 0: # weeks # days # hours # minutes # seconds .INPUTS System.UInt32 .EXAMPLE ConvertToTimeSpanString 28800 .EXAMPLE [UInt32]::MaxValue | ConvertToTimeSpanString .EXAMPLE 86400, 700210 | ConvertToTimeSpanString #> [CmdletBinding()] [OutputType([string])] param ( # A number of seconds as an unsigned 32-bit integer. [Parameter(Mandatory, ValueFromPipeline)] [UInt32]$Seconds ) begin { # Time periods described in seconds $formats = [Ordered]@{ week = 604800 day = 86400 hour = 3600 minute = 60 second = 1 } } process { $values = foreach ($key in $formats.Keys) { $remainder = $Seconds % $formats[$key] $value = ($Seconds - $Remainder) / $formats[$key] $Seconds = $remainder if ($value) { '{0} {1}{2}' -f @( $value $Key ('', 's')[$value -gt 1] ) } } return $values -join ' ' } } #EndRegion '.\private\ConvertToTimeSpanString.ps1' 59 #Region '.\private\GetDnsSuffixSearchList.ps1' 0 function GetDnsSuffixSearchList { <# .SYNOPSIS Attempt to discover a DNS suffix search list. .DESCRIPTION Attempt to discover a DNS suffix search list. #> [CmdletBinding()] param ( [string]$Name ) if (-not $Name.EndsWith('.')) { if (-not $psversiontable.Platform -or $psversiontable.Platform -eq 'Win32NT') { $params = @{ ClassName = 'Win32_NetworkAdapterConfiguration' Property = 'DNSDomainSuffixSearchOrder' } (Get-CimInstance @params).DNSDomainSuffixSearchOrder } elseif (Test-Path '/etc/resolv.conf') { Get-Content '/etc/resolv.conf' | Where-Object { $_ -match '^search (.+)' } | ForEach-Object { $matches[1] -split '\s+' } } } } #EndRegion '.\private\GetDnsSuffixSearchList.ps1' 28 #Region '.\private\ResolveDnsServer.ps1' 0 #using namespace System.Management.Automation function ResolveDnsServer { [CmdletBinding()] [OutputType([IPAddress])] param ( # The name or IP address of a DNS server to use. [string]$ComputerName, # Whether or not IPv6 will be used. [switch]$IPv6 ) $ipAddress = [IPAddress]::Any if ([IPAddress]::TryParse($ComputerName, [ref]$ipAddress)) { return $ipAddress } else { if ($IPv6) { $serverRecordType = [RecordType]::AAAA } else { $serverRecordType = [RecordType]::A } if ($cachedServer = Get-InternalDnsCacheRecord -Name $ComputerName -RecordType $ServerRecordType) { Write-Debug ('Resolve-DnsServer: Cache: Using Server ({0}) from cache.' -f $ComputerName) return $cachedServer | Select-Object -First 1 | Select-Object -ExpandProperty IPAddress } else { $dnsResponse = Get-Dns -Name $ComputerName -RecordType $ServerRecordType if ($dnsResponse.Answer) { $ipAddress = $dnsResponse.Answer | Select-Object -First 1 | Select-Object -ExpandProperty IPAddress Write-Debug ('Resolve-DnsServer: Cache: Adding Server ({0}) to cache.' -f $ComputerName) $dnsResponse.Answer | Add-InternalDnsCacheRecord return $ipAddress } } } $errorRecord = [ErrorRecord]::new( [ArgumentException]::new('Unable to find an IP address for the specified name server ({0})' -f $ComputerName), 'ArgumentException', [ErrorCategory]::InvalidArgument, $ComputerName ) $PSCmdlet.ThrowTerminatingError($errorRecord) } #EndRegion '.\private\ResolveDnsServer.ps1' 50 #Region '.\public\Add-InternalDnsCacheRecord.ps1' 0 function Add-InternalDnsCacheRecord { <# .SYNOPSIS Add a new CacheRecord to the DNS cache object. .DESCRIPTION The DNS cache is used to reduce the effort required to resolve DNS server names used with the ComputerName parameter. .INPUTS DnsCacheRecord DnsResourceRecord .EXAMPLE $CacheRecord | Add-InternalDnsCacheRecord #> [CmdletBinding(DefaultParameterSetName = 'CacheRecord')] [OutputType('DnsCacheRecord')] param ( # A record to add to the cache. [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'CacheRecord')] [DnsCacheRecord]$CacheRecord, # A resource record to add to the cache. [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ResourceRecord')] [DnsResourceRecord]$ResourceRecord, # The cache object type. [CacheResourceType]$ResourceType = 'Address', # A time property is used to age entries out of the cache. If permanent is set the time is not, the value will not be purged based on the TTL. [switch]$Permanent ) process { if ($ResourceRecord) { $CacheRecord = $ResourceRecord } $CacheRecord.ResourceType = $ResourceType if ($Permanent) { $CacheRecord.IsPermanent = $true } if ($Script:dnsCache.Contains($CacheRecord.Name)) { if ($Script:dnsCache.Contains($CacheRecord.Name)) { $Script:dnsCache[$CacheRecord.Name] += $CacheRecord } } else { $Script:dnsCache.Add($CacheRecord.Name, @($CacheRecord)) } } } #EndRegion '.\public\Add-InternalDnsCacheRecord.ps1' 54 #Region '.\public\Clear-InternalDnsCache.ps1' 0 function Clear-InternalDnsCache { <# .SYNOPSIS Clears expired entries from the internal DNS cache. .DESCRIPTION Clear expired entries from the internal DNS cache. .EXAMPLE Clear-InternalDnsCacheRecord #> [CmdletBinding(SupportsShouldProcess)] param ( [switch]$ExpiredOnly ) if ($ExpiredOnly) { (Get-InternalDnsCacheRecord | Where-Object { $_.HasExpired() }) | Remove-InternalDnsCacheRecord } else { if ($PSCmdlet.ShouldProcess('Clearing DNS cache')) { $Script:dnsCache.Clear() } } } #EndRegion '.\public\Clear-InternalDnsCache.ps1' 27 #Region '.\public\Format-DnsResponse.ps1' 0 function Format-DnsResponse { <# .SYNOPSIS Format a DNS message section for display. .DESCRIPTION Format a DNS message section for display. #> [CmdletBinding()] param ( # The DnsMessage to format. [Parameter(Mandatory)] [DnsMessage]$DnsMessage, # The section to format and return as a string. [Parameter(Mandatory)] [string]$Section ) $maximumLength = $host.UI.RawUI.BufferSize.Width - 15 $recordStrings = if ($DnsMessage.$Section.Count -gt 0) { foreach ($resourceRecord in $DnsMessage.$Section) { $string = $resourceRecord.ToString() if ($string.Length -gt $maximumLength) { '{0}...' -f $string.Substring(0, $maximumLength - 4) } else { $string } } } $recordStrings -join "`n" } #EndRegion '.\public\Format-DnsResponse.ps1' 36 #Region '.\public\Get-Dns.ps1' 0 #using namespace System.Management.Automation #using namespace System.Net.Sockets function Get-Dns { <# .SYNOPSIS Get a DNS resource record from a DNS server. .DESCRIPTION Get-Dns is a debugging resolver tool similar to dig and nslookup. .EXAMPLE Get-Dns hostname Attempt to resolve hostname using the system-configured search list. .EXAMPLE Get-Dns www.domain.example The system-configured search list will be appended to this query before it is executed. .EXAMPLE Get-Dns www.domain.example. The name is fully-qualified (or root terminated), no additional suffixes will be appended. .EXAMPLE Get-Dns example. -DnsSec Request ANY record for the co.uk domain, advertising DNSSEC support. #> [CmdletBinding()] [OutputType('DnsMessage')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] param ( # A resource name to query, by default Get-Dns will use '.' as the name. IP addresses (IPv4 and IPv6) are automatically converted into an appropriate format to aid PTR queries. [Parameter(Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [TransformDnsName()] [ValidateDnsName()] [string]$Name = '.', # Any resource record type, by default a query for ANY will be sent. [Parameter(Position = 2, ValueFromPipelineByPropertyName)] [Alias('Type')] [RecordType[]]$RecordType = @('A', 'AAAA'), # By default the class is IN. CH (Chaos) may be used to query for name server information. HS (Hesoid) may be used if the name server supports it. [RecordClass]$RecordClass = [RecordClass]::IN, # Remove the Recursion Desired (RD) flag from a query. Recursion is requested by default. [Alias('NoRecurse')] [switch]$NoRecursion, # Advertise support for DNSSEC when executing a query. [switch]$DnsSec, # Enable EDNS support, suppresses OPT RR advertising client support in DNS question. Automatically enabled if DNSSEC is requested. [switch]$EDns, # By default the EDns buffer size is set to 4096 bytes. [UInt16]$EDnsBufferSize = 4096, # Disables conversion of international domain names to unicode in responses. [switch]$DisableIdnConversion, # Disable the use of TCP if a truncated response (TC flag) is seen when using UDP. [Alias('Ignore')] [switch]$NoTcpFallback, # If a name is not root terminated (does not end with '.') a SearchList will be used for recursive queries. If this parameter is not defined Get-Dns will attempt to retrieve a SearchList from the hosts network configuration. # # An empty search list by be specified by providing an empty array for this parameter. [AllowEmptyCollection()] [string[]]$SearchList = (GetDnsSuffixSearchList), # Recursive, or version, queries can be forced to use TCP by setting the TCP switch parameter. [Alias('vc')] [switch]$Tcp, # By default, DNS uses TCP or UDP port 53. The port used to send queries may be changed if a server is listening on a different port. [UInt16]$Port = 53, # By default, queries will timeout after 5 seconds. The value may be set between 1 and 30 seconds. [ValidateRange(1, 30)] [byte]$Timeout = 5, # Force the use of IPv6 for queries, if this parameter is set and the ComputerName is set to a name (e.g. ns1.domain.example), Get-Dns will attempt to locate an AAAA record for the server. [switch]$IPv6, # A server name or IP address to execute a query against. If an IPv6 address is used Get-Dns will attempt the query using IPv6 (enables the IPv6 parameter). # # If a name is used another lookup will be required to resolve the name to an IP. Get-Dns caches responses for queries performed involving the Server parameter. The cache may be viewed and maintained using the *-InternalDnsCache CmdLets. # # If no server name is defined, the Get-DnsServerList command is used to discover locally configured DNS servers. [Alias('Server')] [string]$ComputerName = (Get-DnsServerList -IPv6:$IPv6 | Select-Object -First 1), # Forces Get-Dns to output intermediate requests which would normally be hidden, such as NXDomain replies when using a SearchList. [switch]$DnsDebug ) begin { Clear-InternalDnsCache -ExpiredOnly } process { try { $serverIPAddress = ResolveDnsServer -ComputerName $ComputerName -IPv6:$IPv6 if ($serverIPAdddress.AddressFamily -eq [AddressFamily]::InterNetworkv6) { Write-Verbose 'Resolve-DnsServer: IPv6 server value used. Using IPv6 transport.' $IPv6 = $true } $ComputerName = $serverIPAddress } catch { $PSCmdlet.ThrowTerminatingError($_) } $querySearchList = $SearchList if ($Name.EndsWith('.')) { $querySearchList = '' } elseif ($Name.IndexOf('.') -ne $Name.LastIndexOf('.')) { $querySearchList += '' } $querySearchListPosition = 0 :searchList foreach ($suffix in $querySearchList) { $querySearchListPosition++ foreach ($rrType in $RecordType) { if ($suffix) { $fullName = '{0}.{1}' -f $Name, $suffix } else { $fullName = $Name } $dnsMessage = [DnsMessage]::new( $fullName, $rrType, $RecordClass ) if ($EDns -or $DnsSec) { $dnsMessage.SetEDnsBufferSize($EDnsBufferSize) } if ($DnsSec) { $dnsMessage.SetAcceptDnsSec() } if ($NoRecursion) { $dnsMessage.DisableRecursion() } try { $dnsClient = [DnsClient]::new( $Tcp.IsPresent, ([IPAddress]$ComputerName).AddressFamily -eq 'InterNetworkV6', $Timeout, $Timeout ) $dnsClient.SendQuestion( $dnsMessage, $ComputerName, $Port ) $dnsResponse = $dnsClient.ReceiveAnswer(-not $DisableIdnConversion) $dnsResponse.ComputerName = $dnsClient.RemoteEndPoint $dnsResponse.TimeTaken = $dnsClient.TimeTaken.TotalMilliseconds $dnsClient.Close() if ($dnsResponse.Header.RCode -ne 'NXDOMAIN' -or $querySearchListPosition -eq $querySearchList.Count -or $dnsDebug) { if ($dnsResponse.Header.Flags -band 'TC' -and -not $NoTcpFallback) { Write-Debug 'Response is truncated. Resending using TCP' Get-Dns @PSBoundParameters -Tcp break searchList } else { $dnsResponse } if (-not $dnsDebug) { break searchList } } } catch [SocketException] { $errorRecord = [ErrorRecord]::new( $_.Exception, 'Timeout', [ErrorCategory]::ConnectionError, $Socket ) $PSCmdlet.ThrowTerminatingError($errorRecord) } catch { $PSCmdlet.ThrowTerminatingError($_) } } } } } #EndRegion '.\public\Get-Dns.ps1' 205 #Region '.\public\Get-DnsServerList.ps1' 0 #using namespace System.Management.Automation #using namespace System.Net.NetworkInformation #using namespace System.Net.Sockets function Get-DnsServerList { <# .SYNOPSIS Gets a list of network interfaces and attempts to return a list of DNS server IP addresses. .DESCRIPTION Get-DnsServerList uses System.Net.NetworkInformation to return a list of operational ethernet or wireless interfaces. IP properties are returned, and an attempt to return a list of DNS server addresses is made. If successful, the DNS server list is returned. .EXAMPLE Get-DnsServerList Get a list of DNS servers. .EXAMPLE Get-DnsServerList -IPv6 Get a list of IPv6 DNS servers. #> [CmdletBinding()] [OutputType([IPAddress])] param ( # Find DNS servers which support IPv6. [switch]$IPv6 ) if ($IPv6) { $AddressFamily = [AddressFamily]::InterNetworkv6 } else { $AddressFamily = [AddressFamily]::InterNetwork } if ([NetworkInterface]::GetIsNetworkAvailable()) { [NetworkInterface]::GetAllNetworkInterfaces() | Where-Object { $_.OperationalStatus -eq 'Up' -and $_.NetworkInterfaceType -match 'Ethernet|Wireless' } | ForEach-Object { $_.GetIPProperties().DnsAddresses } | Where-Object AddressFamily -eq $AddressFamily } else { $errorRecord = [ErrorRecord]::new( [InvalidOperationException]::new('Failed to locate an available network'), 'NoDnsServersAvailable', 'InvalidOperation', $null ) $PSCmdlet.ThrowTerminatingError($errorRecord) } } #EndRegion '.\public\Get-DnsServerList.ps1' 51 #Region '.\public\Get-DnsVersion.ps1' 0 function Get-DnsVersion { <# .SYNOPSIS Get the DNS server version. .DESCRIPTION Attempt to get the DNS server version by sending a request for version.bind. using the CH class. DNS servers often refuse queries for the version number. .EXAMPLE Get-DnsVersion Get the version of the default DNS server. .EXAMPLE Get-DnsVersion -ComputerName 127.0.0.1 Get the version of the DNS server running on 127.0.0.1. #> [CmdletBinding()] param ( # Recursive, or version, queries can be forced to use TCP by setting the TCP switch parameter. [Alias('vc')] [switch]$Tcp, # By default, DNS uses TCP or UDP port 53. The port used to send queries may be changed if a server is listening on a different port. [UInt16]$Port = 53, # By default, queries will timeout after 5 seconds. The value may be set between 1 and 30 seconds. [ValidateRange(1, 30)] [byte]$Timeout = 5, # Force the use of IPv6 for queries, if this parameter is set and the ComputerName is set to a name (e.g. ns1.domain.example), Get-Dns will attempt to locate an AAAA record for the server. [switch]$IPv6, # A server name or IP address to execute a query against. If an IPv6 address is used Get-Dns will attempt the query using IPv6 (enables the IPv6 parameter). # # If a name is used another lookup will be required to resolve the name to an IP. Get-Dns caches responses for queries performed involving the Server parameter. The cache may be viewed and maintained using the *-InternalDnsCache CmdLets. # # If no server name is defined, the Get-DnsServerList command is used to discover locally configured DNS servers. [Alias('Server')] [string]$ComputerName ) $params = @{ Name = 'version.bind.' RecordType = 'TXT' RecordClass = 'CH' } Get-Dns @params @psboundparameters } #EndRegion '.\public\Get-DnsVersion.ps1' 55 #Region '.\public\Get-DnsZoneTransfer.ps1' 0 function Get-DnsZoneTransfer { <# .SYNOPSIS Get the content of a DNS zone using zone transfer. .DESCRIPTION Get the content of a DNS zone using zone transfer. #> [CmdletBinding()] param ( # The name of the zone to transfer. [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [TransformDnsName()] [ValidateDnsName()] [string]$ZoneName, # If the serial number is set, an incremental zone transfer is performed. [UInt32]$SerialNumber, # By default, DNS uses TCP or UDP port 53. The port used to send queries may be changed if a server is listening on a different port. [UInt16]$Port = 53, # By default, queries will timeout after 5 seconds. The value may be set between 1 and 30 seconds. [ValidateRange(1, 30)] [byte]$Timeout = 5, # Force the use of IPv6 for queries, if this parameter is set and the ComputerName is set to a name (e.g. ns1.domain.example), Get-Dns will attempt to locate an AAAA record for the server. [switch]$IPv6, # A server name or IP address to execute a query against. If an IPv6 address is used Get-Dns will attempt the query using IPv6 (enables the IPv6 parameter). # # If a name is used another lookup will be required to resolve the name to an IP. Get-Dns caches responses for queries performed involving the Server parameter. The cache may be viewed and maintained using the *-InternalDnsCache CmdLets. # # If no server name is defined, the Get-DnsServerList command is used to discover locally configured DNS servers. [Alias('Server')] [string]$ComputerName ) begin { try { $serverIPAddress = ResolveDnsServer -ComputerName $ComputerName -IPv6:$IPv6 if ($serverIPAdddress.AddressFamily -eq [AddressFamily]::InterNetworkv6) { Write-Verbose 'IPv6 server value used. Using IPv6 transport.' $IPv6 = $true } $ComputerName = $serverIPAddress } catch { $PSCmdlet.ThrowTerminatingError($_) } } process { if ($SerialNumber) { $dnsMessage = [DnsMessage]::new( $ZoneName, 'IXFR', 'IN', $SerialNumber ) } else { $dnsMessage = [DnsMessage]::new( $ZoneName, 'AXFR', 'IN' ) } $dnsClient = [DnsClient]::new( $true, ([IPAddress]$ComputerName).AddressFamily -eq 'InterNetworkV6', $Timeout, $Timeout ) $dnsClient.SendQuestion( $dnsMessage, $ComputerName, $Port ) $dnsResponse = $dnsClient.ReceiveAnswer() $dnsResponse.ComputerName = $dnsClient.RemoteEndPoint $dnsResponse.TimeTaken = $dnsClient.TimeTaken.TotalMilliseconds $dnsClient.Close() $dnsResponse } } #EndRegion '.\public\Get-DnsZoneTransfer.ps1' 90 #Region '.\public\Get-InternalDnsCacheRecord.ps1' 0 function Get-InternalDnsCacheRecord { <# .SYNOPSIS Get the content of the internal DNS cache used by Get-Dns. .DESCRIPTION Get-InternalDnsCacheRecord displays records held in the cache. .INPUTS Indented.Net.Dns.CacheRecord .EXAMPLE Get-InternalDnsCacheRecord .EXAMPLE Get-InternalDnsCacheRecord a.root-servers.net A #> [CmdletBinding()] [OutputType('DnsCacheRecord')] param ( # The name of the record to retrieve. [Parameter(Position = 1, ValueFromPipelineByPropertyName)] [string]$Name, # The record type to retrieve. [Parameter(Position = 2, ValueFromPipelineByPropertyName)] [string]$RecordType, # The resource type to retrieve. [ValidateSet('Address', 'Hint')] [string]$ResourceType ) process { if ($Name) { if (-not $Name.EndsWith('.')) { $Name += '.' } if ($Script:dnsCache.Contains($Name)) { $Script:dnsCache[$Name] | Where-Object { -not $RecordType -or $_.RecordType -eq $RecordType } } } else { $Script:dnsCache.Values | ForEach-Object { $_ } | Where-Object { (-not $RecordType -or $_.RecordType -eq $RecordType) -and (-not $ResourceType -or $_.ResourceType -eq $ResourceType) } } } } #EndRegion '.\public\Get-InternalDnsCacheRecord.ps1' 53 #Region '.\public\Initialize-InternalDnsCache.ps1' 0 function Initialize-InternalDnsCache { <# .SYNOPSIS Initializes a basic DNS cache for use by Get-Dns. .DESCRIPTION Get-Dns maintains a limited DNS cache, capturing A and AAAA records, to assist name server resolution (for values passed using the Server parameter). The cache may be manipulated using *-InternalDnsCacheRecord Cmdlets. .EXAMPLE Initialize-InternalDnsCache Initialize the cache. #> [CmdletBinding()] param( ) $Script:dnsCache = @{} $path = Join-Path $MyInvocation.MyCommand.Module.ModuleBase 'var\named.root' if (Test-Path $path) { Get-Content $path | Where-Object { -not $_.StartsWith(';') -and $_ -cmatch '\d+\s+A' } | ForEach-Object { [DnsCacheRecord]::Parse($_) } | Add-InternalDnsCacheRecord -ResourceType Hint -Permanent } } #EndRegion '.\public\Initialize-InternalDnsCache.ps1' 30 #Region '.\public\Remove-InternalDnsCacheRecord.ps1' 0 function Remove-InternalDnsCacheRecord { <# .SYNOPSIS Remove a single entry from the internal DNS cache. .DESCRIPTION Remove a single entry from the internal DNS cache. .EXAMPLE Remove-InternalDnsCacheRecord someName -RecordType A Remove someName from the cache. #> [CmdletBinding(SupportsShouldProcess)] param ( # The name of the record to retrieve. [Parameter(Position = 1, ValueFromPipelineByPropertyName)] [string]$Name, # The record type to retrieve. [Parameter(Position = 2, ValueFromPipelineByPropertyName)] [ValidateSet('A', 'AAAA')] [RecordType]$RecordType ) process { if (-not $Name.EndsWith('.')) { $Name += '.' } if ($Script:dnsCache.Contains($Name)) { if ($PSCmdlet.ShouldProcess('Removing {0} from cache' -f $Name)) { if ($RecordType) { $Script:dnsCache[$Name] = $Script:dnsCache[$Name] | Where-Object { $_.RecordType -ne $RecordType } if ($Script:dnsCache[$Name].Count -eq 0) { $Script:dnsCache.Remove($Name) } } else { $Script:dnsCache.Remove($Name) } } } } } #EndRegion '.\public\Remove-InternalDnsCacheRecord.ps1' 49 #Region '.\public\Search-Dns.ps1' 0 function Search-Dns { <# .SYNOPSIS Search all name servers for a specific record. .DESCRIPTION Search-Dns may be used to retrieve a resource record from all name servers for a given domain. #> [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')] [CmdletBinding()] param ( # The name of the record to search for. The name can either be fully-qualified or relative to the zone name. [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [AllowEmptyString()] [TransformDnsName()] [string]$Name, # The zone name is used to ensure the correct zone is searched for records. This avoids the need for tricks to discover the authority for record types such as CNAME. [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)] [TransformDnsName()] [ValidateDnsName()] [string]$ZoneName, # The record type to search for. [Parameter(Position = 3, ValueFromPipelineByPropertyName)] [RecordType]$RecordType = 'ANY', # Advertise support for DNSSEC when executing a query. [switch]$DnsSec, # Recursive, or version, queries can be forced to use TCP by setting the TCP switch parameter. [Alias('vc')] [switch]$Tcp, # By default, DNS uses TCP or UDP port 53. The port used to send queries may be changed if a server is listening on a different port. [UInt16]$Port = 53, # By default, queries will timeout after 5 seconds. The value may be set between 1 and 30 seconds. [ValidateRange(1, 30)] [byte]$Timeout = 5, # Force the use of IPv6 for queries, if this parameter is set and the ComputerName is set to a name (e.g. ns1.domain.example), Get-Dns will attempt to locate an AAAA record for the server. [switch]$IPv6, # A server name or IP address to execute a query against. If an IPv6 address is used Get-Dns will attempt the query using IPv6 (enables the IPv6 parameter). # # If a name is used another lookup will be required to resolve the name to an IP. Get-Dns caches responses for queries performed involving the Server parameter. The cache may be viewed and maintained using the *-InternalDnsCache CmdLets. # # If no server name is defined, the Get-DnsServerList command is used to discover locally configured DNS servers. [Alias('Server')] [string]$ComputerName ) process { $null = $PSBoundParameters.Remove('Name') $null = $PSBoundParameters.Remove('ZoneName') $null = $PSBoundParameters.Remove('RecordType') $params = @{ Name = $ZoneName = '{0}.' -f $ZoneName.TrimEnd('.') RecordType = 'NS' } $dnsResponse = Get-Dns @params @psboundparameters $Name = '{0}.' -f $Name.TrimEnd('.') if (-not $Name.EndsWith($ZoneName, 'InvariantCultureIgnoreCase')) { $Name = '{0}{1}' -f $Name, $ZoneName } $Name = $Name.TrimStart('.') foreach ($answer in $dnsResponse.Answer) { $nameServer = $answer.HostName $params = @{ Name = $Name RecordType = $RecordType ComputerName = $nameServer } Get-Dns @params @psboundparameters } } } #EndRegion '.\public\Search-Dns.ps1' 84 #Region '.\public\Trace-Dns.ps1' 0 function Trace-Dns { <# .SYNOPSIS Iteratively trace resolution of a name from a root or specified name server. .DESCRIPTION Trace-Dns attempts to resolve a name from a root or specified name server by following authority records. .EXAMPLE Trace-Dns www.google.com. Trace resolution of www.googl.com from the root servers down. #> [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '')] [CmdletBinding()] param ( # The name of the record to search for. The name can either be fully-qualified or relative to the zone name. [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)] [TransformDnsName()] [ValidateDnsName()] [string]$Name, # The record type to search for. [Parameter(Position = 3, ValueFromPipelineByPropertyName)] [RecordType]$RecordType = 'ANY', # Advertise support for DNSSEC when executing a query. [switch]$DnsSec, # Recursive, or version, queries can be forced to use TCP by setting the TCP switch parameter. [Alias('vc')] [switch]$Tcp, # By default, DNS uses TCP or UDP port 53. The port used to send queries may be changed if a server is listening on a different port. [UInt16]$Port = 53, # By default, queries will timeout after 5 seconds. The value may be set between 1 and 30 seconds. [ValidateRange(1, 30)] [byte]$Timeout = 5, # Force the use of IPv6 for queries, if this parameter is set and the ComputerName is set to a name (e.g. ns1.domain.example), Get-Dns will attempt to locate an AAAA record for the server. [switch]$IPv6, # A server name or IP address to execute a query against. If an IPv6 address is used Get-Dns will attempt the query using IPv6 (enables the IPv6 parameter). # # If a name is used another lookup will be required to resolve the name to an IP. Get-Dns caches responses for queries performed involving the Server parameter. The cache may be viewed and maintained using the *-InternalDnsCache CmdLets. # # If no server name is defined, the Get-DnsServerList command is used to discover locally configured DNS servers. [Alias('Server')] [string]$ComputerName ) begin { if (-not $ComputerName) { $nameServerRecordType = 'A' if ($IPv6) { $nameServerRecordType = 'AAAA' } $rootHints = Get-InternalDnsCacheRecord -RecordType $nameServerRecordType -ResourceType Hint $ComputerName = $rootHints.Name | Sort-Object { Get-Random } | Select-Object -First 1 } } process { do { $null = $PSBoundParameters.Remove('ComputerName') $dnsResponse = Get-Dns @PSBoundParameters -NoRecursion -ComputerName $ComputerName if ($dnsResponse.Header.AuthorityCount -gt 0) { $ComputerName = $dnsResponse.Authority[0].Hostname } $dnsResponse } until ($dnsResponse.Header.AnswerCount -gt 0 -or $dnsResponse.Header.RCode -ne 'NOERROR') } } #EndRegion '.\public\Trace-Dns.ps1' 79 #Region '.\public\Update-InternalRootHint.ps1' 0 function Update-InternalRootHint { <# .SYNOPSIS Updates the root hints file from InterNIC then re-initializes the internal cache. .DESCRIPTION The root hints file is used as the basis of an internal DNS cache. The content of the root hints file is used during iterative name resolution. .PARAMETER Source Update-InternalRootHints attempts to download a named.root file from InterNIC by default. An alternative root hints source may be specified here. .EXAMPLE Update-InternalRootHints #> [CmdletBinding(SupportsShouldProcess)] param ( [Uri]$Source = 'http://www.internic.net/domain/named.root' ) $path = Join-Path $MyInvocation.MyCommand.Module.ModuleBase 'var\named.root' if ($PSCmdlet.ShouldProcess('Updating {0}' -f $path)) { Invoke-WebRequest -Uri $Source -OutFile $path Initialize-InternalDnsCache } } #EndRegion '.\public\Update-InternalRootHint.ps1' 27 #Region '.\InitializeModule.ps1' 0 # Resolver (Message): Initialize the DNS cache for Get-Dns Initialize-InternalDnsCache # Resolver (Message): Set a variable to store TC state. New-Variable DnsTCEndFound -Scope Script -Value $false #EndRegion '.\InitializeModule.ps1' 6 |