示例#1
0
        internal static DnsGateway CreateInstance(DnsGatewayType gatewayType, DnsDatagram dns, int offsetInDns, int length)
        {
            switch (gatewayType)
            {
            case DnsGatewayType.None:
                return(None);

            case DnsGatewayType.IpV4:
                if (length < IpV4Address.SizeOf)
                {
                    return(null);
                }
                return(new DnsGatewayIpV4(dns.ReadIpV4Address(offsetInDns, Endianity.Big)));

            case DnsGatewayType.IpV6:
                if (length < IpV6Address.SizeOf)
                {
                    return(null);
                }
                return(new DnsGatewayIpV6(dns.ReadIpV6Address(offsetInDns, Endianity.Big)));

            case DnsGatewayType.DomainName:
                DnsDomainName domainName;
                int           numBytesRead;
                if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out numBytesRead))
                {
                    return(null);
                }
                return(new DnsGatewayDomainName(domainName));

            default:
                return(null);
            }
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            DnsDomainName nextDomainName;
            int           nextDomainNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out nextDomainName, out nextDomainNameLength))
            {
                return(null);
            }
            offsetInDns += nextDomainNameLength;
            length      -= nextDomainNameLength;

            if (length > MaxTypeBitmapLength)
            {
                return(null);
            }

            DataSegment typeBitmap = dns.Subsegment(offsetInDns, length);

            if (length != 0 && typeBitmap.Last == 0)
            {
                return(null);
            }

            return(new DnsResourceDataNextDomain(nextDomainName, typeBitmap));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < MinimumLength)
            {
                return(null);
            }

            DnsDomainName previous;
            int           previousLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length - DnsDomainName.RootLength, out previous, out previousLength))
            {
                return(null);
            }
            offsetInDns += previousLength;
            length      -= previousLength;

            DnsDomainName next;
            int           nextLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out next, out nextLength))
            {
                return(null);
            }

            if (length != nextLength)
            {
                return(null);
            }

            return(new DnsResourceDataTrustAnchorLink(previous, next));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength)
            {
                return(null);
            }

            DnsType      typeCovered         = (DnsType)dns.ReadUShort(offsetInDns + Offset.TypeCovered, Endianity.Big);
            DnsAlgorithm algorithm           = (DnsAlgorithm)dns[offsetInDns + Offset.Algorithm];
            byte         labels              = dns[offsetInDns + Offset.Labels];
            uint         originalTtl         = dns.ReadUInt(offsetInDns + Offset.OriginalTtl, Endianity.Big);
            uint         signatureExpiration = dns.ReadUInt(offsetInDns + Offset.SignatureExpiration, Endianity.Big);
            uint         signatureInception  = dns.ReadUInt(offsetInDns + Offset.SignatureInception, Endianity.Big);
            ushort       keyTag              = dns.ReadUShort(offsetInDns + Offset.KeyTag, Endianity.Big);

            offsetInDns += ConstantPartLength;
            length      -= ConstantPartLength;

            DnsDomainName signersName;
            int           signersNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out signersName, out signersNameLength))
            {
                return(null);
            }
            offsetInDns += signersNameLength;
            length      -= signersNameLength;

            DataSegment signature = dns.Subsegment(offsetInDns, length);

            return(new DnsResourceDataSignature(typeCovered, algorithm, labels, originalTtl, signatureExpiration, signatureInception, keyTag, signersName, signature));
        }
        /// <summary>
        /// Constructs an instance out of the algorithm, inception, expiration, mode, error, key and other fields.
        /// </summary>
        /// <param name="algorithm">
        /// Name of the algorithm in domain name syntax.
        /// The algorithm determines how the secret keying material agreed to using the TKEY RR is actually used to derive the algorithm specific key.
        /// </param>
        /// <param name="inception">
        /// Number of seconds since the beginning of 1 January 1970 GMT ignoring leap seconds treated as modulo 2**32 using ring arithmetic.
        /// In messages between a DNS resolver and a DNS server where this field is meaningful,
        /// it is either the requested validity interval start for the keying material asked for or
        /// specify the validity interval start of keying material provided.
        ///
        /// To avoid different interpretations of the inception time in TKEY RRs,
        /// resolvers and servers exchanging them must have the same idea of what time it is.
        /// One way of doing this is with the NTP protocol [RFC 2030] but that or any other time synchronization used for this purpose must be done securely.
        /// </param>
        /// <param name="expiration">
        /// Number of seconds since the beginning of 1 January 1970 GMT ignoring leap seconds treated as modulo 2**32 using ring arithmetic.
        /// In messages between a DNS resolver and a DNS server where this field is meaningful,
        /// it is either the requested validity interval end for the keying material asked for or
        /// specify the validity interval end of keying material provided.
        ///
        /// To avoid different interpretations of the expiration time in TKEY RRs,
        /// resolvers and servers exchanging them must have the same idea of what time it is.
        /// One way of doing this is with the NTP protocol [RFC 2030] but that or any other time synchronization used for this purpose must be done securely.
        /// </param>
        /// <param name="mode">
        /// Specifies the general scheme for key agreement or the purpose of the TKEY DNS message.
        /// Servers and resolvers supporting this specification must implement the Diffie-Hellman key agreement mode and the key deletion mode for queries.
        /// All other modes are optional.
        /// A server supporting TKEY that receives a TKEY request with a mode it does not support returns the BADMODE error.
        /// </param>
        /// <param name="error">
        /// When the TKEY Error Field is non-zero in a response to a TKEY query, the DNS header RCODE field indicates no error.
        /// However, it is possible if a TKEY is spontaneously included in a response the TKEY RR and DNS header error field
        /// could have unrelated non-zero error codes.
        /// </param>
        /// <param name="key">The key exchange data. The meaning of this data depends on the mode.</param>
        /// <param name="other">May be used in future extensions.</param>
        public DnsResourceDataTransactionKey(DnsDomainName algorithm, SerialNumber32 inception, SerialNumber32 expiration, DnsTransactionKeyMode mode,
                                             DnsResponseCode error, DataSegment key, DataSegment other)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }

            if (key.Length > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("key", key.Length,
                                                      string.Format(CultureInfo.InvariantCulture, "Cannot be longer than {0}", ushort.MaxValue));
            }
            if (other.Length > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("other", other.Length,
                                                      string.Format(CultureInfo.InvariantCulture, "Cannot be longer than {0}", ushort.MaxValue));
            }

            Algorithm  = algorithm;
            Inception  = inception;
            Expiration = expiration;
            Mode       = mode;
            Error      = error;
            Key        = key;
            Other      = other;
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength)
            {
                return(null);
            }

            ushort priortiy = dns.ReadUShort(offsetInDns + Offset.Priority, Endianity.Big);
            ushort weight   = dns.ReadUShort(offsetInDns + Offset.Weight, Endianity.Big);
            ushort port     = dns.ReadUShort(offsetInDns + Offset.Port, Endianity.Big);

            DnsDomainName target;
            int           targetLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns + Offset.Target, length - ConstantPartLength, out target, out targetLength))
            {
                return(null);
            }

            if (ConstantPartLength + targetLength != length)
            {
                return(null);
            }

            return(new DnsResourceDataServerSelection(priortiy, weight, port, target));
        }
        internal static bool TryRead(out ushort value, out DnsDomainName domainName,
                                     DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength)
            {
                value      = 0;
                domainName = null;
                return(false);
            }
            value   = dns.ReadUShort(offsetInDns + Offset.Value, Endianity.Big);
            length -= ConstantPartLength;

            int domainNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns + Offset.DomainName, length, out domainName, out domainNameLength))
            {
                return(false);
            }
            length -= domainNameLength;

            if (length != 0)
            {
                return(false);
            }

            return(true);
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            DnsDomainName mainNameServer;
            int           domainNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out mainNameServer, out domainNameLength))
            {
                return(null);
            }
            offsetInDns += domainNameLength;
            length      -= domainNameLength;

            DnsDomainName responsibleMailbox;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out responsibleMailbox, out domainNameLength))
            {
                return(null);
            }
            offsetInDns += domainNameLength;
            length      -= domainNameLength;

            if (length != ConstantPartLength)
            {
                return(null);
            }

            uint serial     = dns.ReadUInt(offsetInDns + Offset.Serial, Endianity.Big);;
            uint refresh    = dns.ReadUInt(offsetInDns + Offset.Refresh, Endianity.Big);;
            uint retry      = dns.ReadUInt(offsetInDns + Offset.Retry, Endianity.Big);;
            uint expire     = dns.ReadUInt(offsetInDns + Offset.Expire, Endianity.Big);;
            uint minimumTtl = dns.ReadUInt(offsetInDns + Offset.MinimumTtl, Endianity.Big);;

            return(new DnsResourceDataStartOfAuthority(mainNameServer, responsibleMailbox, serial, refresh, retry, expire, minimumTtl));
        }
        /// <summary>
        /// Constructs an instance out of the algorithm time signed, fudge, message authentication code, original ID, error and other fields.
        /// </summary>
        /// <param name="algorithm">Name of the algorithm in domain name syntax.</param>
        /// <param name="timeSigned">Seconds since 1-Jan-70 UTC.</param>
        /// <param name="fudge">Seconds of error permitted in Time Signed.</param>
        /// <param name="messageAuthenticationCode">Defined by Algorithm Name.</param>
        /// <param name="originalId">Original message ID.</param>
        /// <param name="error">RCODE covering TSIG processing.</param>
        /// <param name="other">Empty unless Error == BADTIME.</param>
        public DnsResourceDataTransactionSignature(DnsDomainName algorithm, UInt48 timeSigned, ushort fudge, DataSegment messageAuthenticationCode,
                                                   ushort originalId, DnsResponseCode error, DataSegment other)
        {
            if (messageAuthenticationCode == null)
            {
                throw new ArgumentNullException("messageAuthenticationCode");
            }
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }

            if (messageAuthenticationCode.Length > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("messageAuthenticationCode", messageAuthenticationCode.Length,
                                                      string.Format(CultureInfo.InvariantCulture, "Cannot be longer than {0}", ushort.MaxValue));
            }
            if (other.Length > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException("other", other.Length,
                                                      string.Format(CultureInfo.InvariantCulture, "Cannot be longer than {0}", ushort.MaxValue));
            }

            Algorithm  = algorithm;
            TimeSigned = timeSigned;
            Fudge      = fudge;
            MessageAuthenticationCode = messageAuthenticationCode;
            OriginalId = originalId;
            Error      = error;
            Other      = other;
        }
 /// <summary>
 /// Constructs an instance out of the priority, weight, port and target fields.
 /// </summary>
 /// <param name="priority">
 /// The priority of this target host.
 /// A client must attempt to contact the target host with the lowest-numbered priority it can reach;
 /// target hosts with the same priority should be tried in an order defined by the weight field.
 /// </param>
 /// <param name="weight">
 /// A server selection mechanism.
 /// The weight field specifies a relative weight for entries with the same priority.
 /// Larger weights should be given a proportionately higher probability of being selected.
 /// Domain administrators should use Weight 0 when there isn't any server selection to do, to make the RR easier to read for humans (less noisy).
 /// In the presence of records containing weights greater than 0, records with weight 0 should have a very small chance of being selected.
 ///
 /// In the absence of a protocol whose specification calls for the use of other weighting information, a client arranges the SRV RRs of the same Priority in the order in which target hosts,
 /// specified by the SRV RRs, will be contacted.
 /// The following algorithm SHOULD be used to order the SRV RRs of the same priority:
 /// To select a target to be contacted next, arrange all SRV RRs (that have not been ordered yet) in any order, except that all those with weight 0 are placed at the beginning of the list.
 /// Compute the sum of the weights of those RRs, and with each RR associate the running sum in the selected order.
 /// Then choose a uniform random number between 0 and the sum computed (inclusive), and select the RR whose running sum value is the first in the selected order which is greater than or equal to the random number selected.
 /// The target host specified in the selected SRV RR is the next one to be contacted by the client.
 /// Remove this SRV RR from the set of the unordered SRV RRs and apply the described algorithm to the unordered SRV RRs to select the next target host.
 /// Continue the ordering process until there are no unordered SRV RRs.
 /// This process is repeated for each Priority.
 /// </param>
 /// <param name="port">The port on this target host of this service. This is often as specified in Assigned Numbers but need not be.</param>
 /// <param name="target">
 /// The domain name of the target host.
 /// There must be one or more address records for this name, the name must not be an alias (in the sense of RFC 1034 or RFC 2181).
 /// Implementors are urged, but not required, to return the address record(s) in the Additional Data section.
 /// Unless and until permitted by future standards action, name compression is not to be used for this field.
 ///
 /// A Target of "." means that the service is decidedly not available at this domain.
 /// </param>
 public DnsResourceDataServerSelection(ushort priority, ushort weight, ushort port, DnsDomainName target)
 {
     Priority = priority;
     Weight   = weight;
     Port     = port;
     Target   = target;
 }
示例#11
0
        public DnsResourceDataNamingAuthorityPointer(ushort order, ushort preference, DataSegment flags, DataSegment services, DataSegment regularExpression,
                                                     DnsDomainName replacement)
        {
            if (flags == null)
            {
                throw new ArgumentNullException("flags");
            }

            if (!IsLegalFlags(flags))
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.InvariantCulture, "Flags ({0}) contain a non [a-zA-Z0-9] character.",
                                        Encoding.ASCII.GetString(flags.Buffer, flags.StartOffset, flags.Length)),
                          "flags");
            }

            Order      = order;
            Preference = preference;
            Flags      = flags.All(flag => flag <'a' || flag> 'z') && flags.IsStrictOrdered()
                        ? flags
                        : new DataSegment(flags.Select(flag => flag >= 'a' && flag <= 'z' ? (byte)(flag + 'A' - 'a') : flag)
                                          .Distinct().OrderBy(flag => flag).ToArray());
            Services          = services;
            RegularExpression = regularExpression;
            Replacement       = replacement;
        }
 /// <summary>
 /// Constructs an instance out of the main name server, responsible mailbox, serial, refresh, retry, expire and minimum TTL fields.
 /// </summary>
 /// <param name="mainNameServer">The domain-name of the name server that was the original or primary source of data for this zone.</param>
 /// <param name="responsibleMailbox">A domain-name which specifies the mailbox of the person responsible for this zone.</param>
 /// <param name="serial">
 /// The unsigned 32 bit version number of the original copy of the zone.
 /// Zone transfers preserve this value.
 /// This value wraps and should be compared using sequence space arithmetic.
 /// </param>
 /// <param name="refresh">A 32 bit time interval before the zone should be refreshed.</param>
 /// <param name="retry">A 32 bit time interval that should elapse before a failed refresh should be retried.</param>
 /// <param name="expire">
 /// A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative.
 /// </param>
 /// <param name="minimumTtl">The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone.</param>
 public DnsResourceDataStartOfAuthority(DnsDomainName mainNameServer, DnsDomainName responsibleMailbox,
                                        SerialNumber32 serial, uint refresh, uint retry, uint expire, uint minimumTtl)
 {
     MainNameServer     = mainNameServer;
     ResponsibleMailbox = responsibleMailbox;
     Serial             = serial;
     Refresh            = refresh;
     Retry      = retry;
     Expire     = expire;
     MinimumTtl = minimumTtl;
 }
示例#13
0
 /// <summary>
 /// Constructs an instance out of the type covered, algorithm, labels, original TTL, signature expiration, signature inception, key tag,
 /// signer's name and signature fields.
 /// </summary>
 /// <param name="typeCovered">The type of the other RRs covered by this SIG.</param>
 /// <param name="algorithm">The key algorithm.</param>
 /// <param name="labels">
 /// An unsigned count of how many labels there are in the original SIG RR owner name not counting the null label for root and not counting any initial "*" for a wildcard.
 /// If a secured retrieval is the result of wild card substitution, it is necessary for the resolver to use the original form of the name in verifying the digital signature.
 /// This field makes it easy to determine the original form.
 ///
 /// If, on retrieval, the RR appears to have a longer name than indicated by "labels", the resolver can tell it is the result of wildcard substitution.
 /// If the RR owner name appears to be shorter than the labels count, the SIG RR must be considered corrupt and ignored.
 /// The maximum number of labels allowed in the current DNS is 127 but the entire octet is reserved and would be required should DNS names ever be expanded to 255 labels.
 /// </param>
 /// <param name="originalTtl">
 /// The "original TTL" field is included in the RDATA portion to avoid
 /// (1) authentication problems that caching servers would otherwise cause by decrementing the real TTL field and
 /// (2) security problems that unscrupulous servers could otherwise cause by manipulating the real TTL field.
 /// This original TTL is protected by the signature while the current TTL field is not.
 ///
 /// NOTE:  The "original TTL" must be restored into the covered RRs when the signature is verified.
 /// This generaly implies that all RRs for a particular type, name, and class, that is, all the RRs in any particular RRset, must have the same TTL to start with.
 /// </param>
 /// <param name="signatureExpiration">
 /// The last time the signature is valid.
 /// Numbers of seconds since the start of 1 January 1970, GMT, ignoring leap seconds.
 /// Ring arithmetic is used.
 /// This time can never be more than about 68 years after the inception.
 /// </param>
 /// <param name="signatureInception">
 /// The first time the signature is valid.
 /// Numbers of seconds since the start of 1 January 1970, GMT, ignoring leap seconds.
 /// Ring arithmetic is used.
 /// This time can never be more than about 68 years before the expiration.
 /// </param>
 /// <param name="keyTag">
 /// Used to efficiently select between multiple keys which may be applicable and thus check that a public key about to be used
 /// for the computationally expensive effort to check the signature is possibly valid.
 /// For algorithm 1 (MD5/RSA) as defined in RFC 2537,
 /// it is the next to the bottom two octets of the public key modulus needed to decode the signature field.
 /// That is to say, the most significant 16 of the least significant 24 bits of the modulus in network (big endian) order.
 /// For all other algorithms, including private algorithms, it is calculated as a simple checksum of the KEY RR.
 /// </param>
 /// <param name="signersName">
 /// The domain name of the signer generating the SIG RR.
 /// This is the owner name of the public KEY RR that can be used to verify the signature.
 /// It is frequently the zone which contained the RRset being authenticated.
 /// Which signers should be authorized to sign what is a significant resolver policy question.
 /// The signer's name may be compressed with standard DNS name compression when being transmitted over the network.
 /// </param>
 /// <param name="signature">
 /// The actual signature portion of the SIG RR binds the other RDATA fields to the RRset of the "type covered" RRs with that owner name and class.
 /// This covered RRset is thereby authenticated.
 /// To accomplish this, a data sequence is constructed as follows:
 ///
 /// data = RDATA | RR(s)...
 ///
 /// where "|" is concatenation,
 ///
 /// RDATA is the wire format of all the RDATA fields in the SIG RR itself (including the canonical form of the signer's name) before but not including the signature,
 /// and RR(s) is the RRset of the RR(s) of the type covered with the same owner name and class as the SIG RR in canonical form and order.
 ///
 /// How this data sequence is processed into the signature is algorithm dependent.
 /// </param>
 public DnsResourceDataSignature(DnsType typeCovered, DnsAlgorithm algorithm, byte labels, uint originalTtl, SerialNumber32 signatureExpiration,
                                 SerialNumber32 signatureInception, ushort keyTag, DnsDomainName signersName, DataSegment signature)
 {
     TypeCovered         = typeCovered;
     Algorithm           = algorithm;
     Labels              = labels;
     OriginalTtl         = originalTtl;
     SignatureExpiration = signatureExpiration;
     SignatureInception  = signatureInception;
     KeyTag              = keyTag;
     SignersName         = signersName;
     Signature           = signature;
 }
示例#14
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < MinimumLength)
            {
                return(null);
            }

            ushort order      = dns.ReadUShort(offsetInDns + Offset.Order, Endianity.Big);
            ushort preference = dns.ReadUShort(offsetInDns + Offset.Preference, Endianity.Big);

            DataSegment data       = dns.Subsegment(offsetInDns + ConstantPartLength, length - ConstantPartLength);
            int         dataOffset = 0;

            DataSegment flags = ReadString(data, ref dataOffset);

            if (flags == null || !IsLegalFlags(flags))
            {
                return(null);
            }

            DataSegment services = ReadString(data, ref dataOffset);

            if (services == null)
            {
                return(null);
            }

            DataSegment regexp = ReadString(data, ref dataOffset);

            if (regexp == null)
            {
                return(null);
            }

            DnsDomainName replacement;
            int           replacementLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns + ConstantPartLength + dataOffset, length - ConstantPartLength - dataOffset,
                                        out replacement, out replacementLength))
            {
                return(null);
            }

            if (ConstantPartLength + dataOffset + replacementLength != length)
            {
                return(null);
            }

            return(new DnsResourceDataNamingAuthorityPointer(order, preference, flags, services, regexp, replacement));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength + DnsDomainName.RootLength)
            {
                return(null);
            }

            DnsDomainName algorithm;
            int           algorithmLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length - ConstantPartLength, out algorithm, out algorithmLength))
            {
                return(null);
            }
            offsetInDns += algorithmLength;
            length      -= algorithmLength;

            if (length < ConstantPartLength)
            {
                return(null);
            }

            uint inception              = dns.ReadUInt(offsetInDns + OffsetAfterAlgorithm.Inception, Endianity.Big);
            uint expiration             = dns.ReadUInt(offsetInDns + OffsetAfterAlgorithm.Expiration, Endianity.Big);
            DnsTransactionKeyMode mode  = (DnsTransactionKeyMode)dns.ReadUShort(offsetInDns + OffsetAfterAlgorithm.Mode, Endianity.Big);
            DnsResponseCode       error = (DnsResponseCode)dns.ReadUShort(offsetInDns + OffsetAfterAlgorithm.Error, Endianity.Big);

            int keySize = dns.ReadUShort(offsetInDns + OffsetAfterAlgorithm.KeySize, Endianity.Big);

            if (length < ConstantPartLength + keySize)
            {
                return(null);
            }
            DataSegment key = dns.Subsegment(offsetInDns + OffsetAfterAlgorithm.KeyData, keySize);

            int totalReadAfterAlgorithm = OffsetAfterAlgorithm.KeyData + keySize;

            offsetInDns += totalReadAfterAlgorithm;
            length      -= totalReadAfterAlgorithm;
            int otherSize = dns.ReadUShort(offsetInDns, Endianity.Big);

            if (length != sizeof(ushort) + otherSize)
            {
                return(null);
            }
            DataSegment other = dns.Subsegment(offsetInDns + sizeof(ushort), otherSize);

            return(new DnsResourceDataTransactionKey(algorithm, inception, expiration, mode, error, key, other));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength + DnsDomainName.RootLength)
            {
                return(null);
            }

            DnsDomainName algorithm;
            int           algorithmLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length - ConstantPartLength, out algorithm, out algorithmLength))
            {
                return(null);
            }
            offsetInDns += algorithmLength;
            length      -= algorithmLength;

            if (length < ConstantPartLength)
            {
                return(null);
            }

            UInt48 timeSigned = dns.ReadUInt48(offsetInDns + OffsetAfterAlgorithm.TimeSigned, Endianity.Big);
            ushort fudge      = dns.ReadUShort(offsetInDns + OffsetAfterAlgorithm.Fudge, Endianity.Big);
            int    messageAuthenticationCodeLength = dns.ReadUShort(offsetInDns + OffsetAfterAlgorithm.MessageAuthenticationCodeSize, Endianity.Big);

            if (length < ConstantPartLength + messageAuthenticationCodeLength)
            {
                return(null);
            }
            DataSegment messageAuthenticationCode = dns.Subsegment(offsetInDns + OffsetAfterAlgorithm.MessageAuthenticationCode, messageAuthenticationCodeLength);
            int         totalReadAfterAlgorithm   = OffsetAfterAlgorithm.MessageAuthenticationCode + messageAuthenticationCodeLength;

            offsetInDns += totalReadAfterAlgorithm;
            length      -= totalReadAfterAlgorithm;

            ushort          originalId  = dns.ReadUShort(offsetInDns + OffsetAfterMessageAuthenticationCode.OriginalId, Endianity.Big);
            DnsResponseCode error       = (DnsResponseCode)dns.ReadUShort(offsetInDns + OffsetAfterMessageAuthenticationCode.Error, Endianity.Big);
            int             otherLength = dns.ReadUShort(offsetInDns + OffsetAfterMessageAuthenticationCode.OtherLength, Endianity.Big);

            if (length != OffsetAfterMessageAuthenticationCode.OtherData + otherLength)
            {
                return(null);
            }
            DataSegment other = dns.Subsegment(offsetInDns + OffsetAfterMessageAuthenticationCode.OtherData, otherLength);

            return(new DnsResourceDataTransactionSignature(algorithm, timeSigned, fudge, messageAuthenticationCode, originalId, error, other));
        }
示例#17
0
        internal static bool TryRead(out DnsDomainName first, out DnsDomainName second,
                                     DnsDatagram dns, int offsetInDns, int length)
        {
            List <DnsDomainName> domainNames = ReadDomainNames(dns, offsetInDns, length, NumDomains);

            if (domainNames == null || domainNames.Count != NumDomains)
            {
                first  = null;
                second = null;
                return(false);
            }

            first  = domainNames[0];
            second = domainNames[1];
            return(true);
        }
示例#18
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < MinimumLength)
            {
                return(null);
            }

            byte prefixLength = dns[offsetInDns + Offset.PrefixLength];

            if (prefixLength > MaxPrefixLength)
            {
                return(null);
            }
            offsetInDns += ConstantPartLength;
            length      -= ConstantPartLength;

            int addressSuffixLength = CalculateAddressSuffixLength(prefixLength);

            if (length < addressSuffixLength)
            {
                return(null);
            }
            IpV6Address addressSuffix = new IpV6Address((UInt128)dns.ReadUnsignedBigInteger(offsetInDns, addressSuffixLength, Endianity.Big));

            offsetInDns += addressSuffixLength;
            length      -= addressSuffixLength;

            if (IsAddressSuffixTooSmall(prefixLength, addressSuffix) || IsAddressSuffixTooBig(prefixLength, addressSuffix))
            {
                return(null);
            }

            DnsDomainName prefixName;
            int           prefixNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out prefixName, out prefixNameLength))
            {
                return(null);
            }
            if (prefixNameLength != length)
            {
                return(null);
            }

            return(new DnsResourceDataA6(prefixLength, addressSuffix, prefixName));
        }
示例#19
0
        /// <summary>
        /// Constructs the resource data from the prefix length, address suffix and prefix name fields.
        /// </summary>
        /// <param name="prefixLength">Encoded as an eight-bit unsigned integer with value between 0 and 128 inclusive.</param>
        /// <param name="addressSuffix">
        /// An IPv6 address suffix, encoded in network order (high-order octet first).
        /// There must be exactly enough octets in this field to contain a number of bits equal to 128 minus prefix length,
        /// with 0 to 7 leading pad bits to make this field an integral number of octets.
        /// Pad bits, if present, must be set to zero when loading a zone file and ignored (other than for SIG verification) on reception.
        /// </param>
        /// <param name="prefixName">The name of the prefix, encoded as a domain name. This name must not be compressed. </param>
        public DnsResourceDataA6(byte prefixLength, IpV6Address addressSuffix, DnsDomainName prefixName)
        {
            if (IsAddressSuffixTooSmall(prefixLength, addressSuffix))
            {
                throw new ArgumentOutOfRangeException("addressSuffix",
                                                      string.Format(CultureInfo.InvariantCulture, "Value is too small for prefix length {0}", prefixLength));
            }
            if (IsAddressSuffixTooBig(prefixLength, addressSuffix))
            {
                throw new ArgumentOutOfRangeException("addressSuffix",
                                                      string.Format(CultureInfo.InvariantCulture, "Value is too big for prefix length {0}", prefixLength));
            }

            PrefixLength  = prefixLength;
            AddressSuffix = addressSuffix;
            PrefixName    = prefixName;
        }
示例#20
0
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            int           numBytesRead;
            DnsDomainName domainName;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out numBytesRead))
            {
                return(null);
            }
            length -= numBytesRead;

            if (length != 0)
            {
                return(null);
            }

            return(new DnsResourceDataDomainName(domainName));
        }
        internal static List <DnsDomainName> ReadDomainNames(DnsDatagram dns, int offsetInDns, int length, int numExpected = 0)
        {
            List <DnsDomainName> domainNames = new List <DnsDomainName>(numExpected);

            while (length != 0)
            {
                DnsDomainName domainName;
                int           domainNameLength;
                if (!DnsDomainName.TryParse(dns, offsetInDns, length, out domainName, out domainNameLength))
                {
                    return(null);
                }
                offsetInDns += domainNameLength;
                length      -= domainNameLength;
                domainNames.Add(domainName);
            }

            return(domainNames);
        }
示例#22
0
        internal static bool TryParseBase(DnsDatagram dns, int offsetInDns,
                                          out DnsDomainName domainName, out DnsType type, out DnsClass dnsClass, out int numBytesRead)
        {
            type     = DnsType.Any;
            dnsClass = DnsClass.Any;
            if (!DnsDomainName.TryParse(dns, offsetInDns, dns.Length - offsetInDns, out domainName, out numBytesRead))
            {
                return(false);
            }

            if (offsetInDns + numBytesRead + MinimumLengthAfterDomainName > dns.Length)
            {
                return(false);
            }

            type          = (DnsType)dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterDomainName.Type, Endianity.Big);
            dnsClass      = (DnsClass)dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterDomainName.DnsClass, Endianity.Big);
            numBytesRead += MinimumLengthAfterDomainName;
            return(true);
        }
示例#23
0
        /// <summary>
        /// Constructs an instance from next domain name and type bitmap.
        /// </summary>
        /// <param name="nextDomainName">The next domain name according to the canonical DNS name order.</param>
        /// <param name="typeBitmap">
        /// One bit per RR type present for the owner name.
        /// A one bit indicates that at least one RR of that type is present for the owner name.
        /// A zero indicates that no such RR is present.
        /// All bits not specified because they are beyond the end of the bit map are assumed to be zero.
        /// Note that bit 30, for NXT, will always be on so the minimum bit map length is actually four octets.
        /// Trailing zero octets are prohibited in this format.
        /// The first bit represents RR type zero (an illegal type which can not be present) and so will be zero in this format.
        /// This format is not used if there exists an RR with a type number greater than 127.
        /// If the zero bit of the type bit map is a one, it indicates that a different format is being used which will always be
        /// the case if a type number greater than 127 is present.
        /// </param>
        public DnsResourceDataNextDomain(DnsDomainName nextDomainName, DataSegment typeBitmap)
        {
            if (typeBitmap == null)
            {
                throw new ArgumentNullException("typeBitmap");
            }

            if (typeBitmap.Length > MaxTypeBitmapLength)
            {
                throw new ArgumentOutOfRangeException("typeBitmap", typeBitmap.Length,
                                                      string.Format(CultureInfo.InvariantCulture, "Cannot be longer than {0} bytes.", MaxTypeBitmapLength));
            }
            if (typeBitmap.Length > 0 && typeBitmap.Last == 0)
            {
                throw new ArgumentOutOfRangeException("typeBitmap", typeBitmap, "Last byte cannot be 0x00");
            }

            NextDomainName = nextDomainName;
            TypeBitmap     = typeBitmap;
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            DnsDomainName nextDomainName;
            int           nextDomainNameLength;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out nextDomainName, out nextDomainNameLength))
            {
                return(null);
            }
            offsetInDns += nextDomainNameLength;
            length      -= nextDomainNameLength;

            DnsTypeBitmaps typeBitmaps = DnsTypeBitmaps.CreateInstance(dns.Buffer, dns.StartOffset + offsetInDns, length);

            if (typeBitmaps == null)
            {
                return(null);
            }

            return(new DnsResourceDataNextDomainSecure(nextDomainName, typeBitmaps));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength)
            {
                return(null);
            }

            int hostIdentityTagLength = dns[offsetInDns + Offset.HostIdentityTagLength];
            DnsPublicKeyAlgorithm publicKeyAlgorithm = (DnsPublicKeyAlgorithm)dns[offsetInDns + Offset.PublicKeyAlgorithm];
            int publicKeyLength = dns.ReadUShort(offsetInDns + Offset.PublicKeyLength, Endianity.Big);

            if (length < ConstantPartLength + hostIdentityTagLength + publicKeyLength)
            {
                return(null);
            }
            DataSegment hostIdentityTag = dns.Subsegment(offsetInDns + Offset.HostIdentityTag, hostIdentityTagLength);
            int         publicKeyOffset = offsetInDns + ConstantPartLength + hostIdentityTagLength;
            DataSegment publicKey       = dns.Subsegment(publicKeyOffset, publicKeyLength);

            offsetInDns += ConstantPartLength + hostIdentityTagLength + publicKeyLength;
            length      -= ConstantPartLength + hostIdentityTagLength + publicKeyLength;

            List <DnsDomainName> rendezvousServers = new List <DnsDomainName>();

            while (length != 0)
            {
                DnsDomainName rendezvousServer;
                int           rendezvousServerLength;
                if (!DnsDomainName.TryParse(dns, offsetInDns, length, out rendezvousServer, out rendezvousServerLength))
                {
                    return(null);
                }
                rendezvousServers.Add(rendezvousServer);
                offsetInDns += rendezvousServerLength;
                length      -= rendezvousServerLength;
            }

            return(new DnsResourceDataHostIdentityProtocol(hostIdentityTag, publicKeyAlgorithm, publicKey, rendezvousServers));
        }
        internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
        {
            if (length < ConstantPartLength)
            {
                return(null);
            }

            ushort preference = dns.ReadUShort(offsetInDns + Offset.Preference, Endianity.Big);

            offsetInDns += ConstantPartLength;
            length      -= ConstantPartLength;

            DnsDomainName map822;
            int           map822Length;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out map822, out map822Length))
            {
                return(null);
            }
            offsetInDns += map822Length;
            length      -= map822Length;

            DnsDomainName mapX400;
            int           mapX400Length;

            if (!DnsDomainName.TryParse(dns, offsetInDns, length, out mapX400, out mapX400Length))
            {
                return(null);
            }
            length -= mapX400Length;

            if (length != 0)
            {
                return(null);
            }

            return(new DnsResourceDataX400Pointer(preference, map822, mapX400));
        }
示例#27
0
 internal DnsResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass)
 {
     DomainName = domainName;
     DnsType    = type;
     DnsClass   = dnsClass;
 }
 /// <summary>
 /// Constructs the resource data from the previous and next fields.
 /// </summary>
 /// <param name="previous">The start, or previous name.</param>
 /// <param name="next">End or next name in the list.</param>
 public DnsResourceDataTrustAnchorLink(DnsDomainName previous, DnsDomainName next)
 {
     Previous = previous;
     Next     = next;
 }
示例#29
0
 /// <summary>
 /// Creates a resource record from domain name, type, class, ttl and data.
 /// </summary>
 /// <param name="domainName">An owner name, i.e., the name of the node to which this resource record pertains.</param>
 /// <param name="type">Two octets containing one of the RR TYPE codes.</param>
 /// <param name="dnsClass">Two octets containing one of the RR CLASS codes.</param>
 /// <param name="ttl">
 /// A 32 bit signed integer that specifies the time interval that the resource record may be cached before the source of the information should again be consulted.
 /// Zero values are interpreted to mean that the RR can only be used for the transaction in progress, and should not be cached.
 /// For example, SOA records are always distributed with a zero TTL to prohibit caching.
 /// Zero values can also be used for extremely volatile data.
 /// </param>
 /// <param name="data">
 /// A variable length string of octets that describes the resource.
 /// The format of this information varies according to the TYPE and CLASS of the resource record.
 /// For example, the if the TYPE is A and the CLASS is IN, the RDATA field is a 4 octet ARPA Internet address.
 /// </param>
 public DnsDataResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass, int ttl, DnsResourceData data)
     : base(domainName, type, dnsClass)
 {
     Ttl  = ttl;
     Data = data;
 }
示例#30
0
 internal DnsResourceData2DomainNames(DnsDomainName first, DnsDomainName second)
     : base(first, second)
 {
 }