Handles a basic Dns record From RFC 1035: 3.2.1. Format All RRs have the same top level format shown below: 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 / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ where: NAME an owner name, i.e., the name of the node to which this resource record pertains. TYPE two octets containing one of the RR TYPE codes. CLASS two octets containing one of the RR CLASS codes. 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. RDLENGTH an unsigned 16 bit integer that specifies the length in octets of the RDATA field. RDATA 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.
Inheritance: IDnsRecord
コード例 #1
0
ファイル: RtRecord.cs プロジェクト: Kim-SSi/DnDns
 public override void ParseRecord(ref MemoryStream ms)
 {
     byte[] preference = new byte[2];
     ms.Read(preference, 0, 2);
     //_preference = (ushort)Tools.ByteToUInt(preference);
     _preference       = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(preference, 0));
     _intermediateHost = DnsRecordBase.ParseName(ref ms);
     _answer           = "Preference: " + _preference + ", Intermediate Host: " + _intermediateHost;
 }
コード例 #2
0
ファイル: AfsdbRecord.cs プロジェクト: Kim-SSi/DnDns
 public override void ParseRecord(ref MemoryStream ms)
 {
     byte[] type = new byte[2];
     ms.Read(type, 0, 2);
     // _port = (ushort)Tools.ByteToUInt(type);
     _port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(type, 0));
     _name = DnsRecordBase.ParseName(ref ms);
     //_type = (short)Tools.ByteToUInt(type);
     _type   = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(type, 0));
     _answer = "Name: " + _name + ", Port: " + _port + ", Type: " + _type;
 }
コード例 #3
0
ファイル: MxRecord.cs プロジェクト: Kim-SSi/DnDns
        public override void ParseRecord(ref MemoryStream ms)
        {
            // Preference is a function of MX records
            byte[] nsPreference = new byte[2];
            ms.Read(nsPreference, 0, 2);
            //_preference = (short)Tools.ByteToUInt(nsPreference);
            // TODO: Should this be a UShort instead of a short?
            _preference = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsPreference, 0));

            // Parse Name
            _mailExchange = DnsRecordBase.ParseName(ref ms);
            _answer       = "MX Preference: " + _preference + ", Mail Exchanger: " + _mailExchange;
        }
コード例 #4
0
ファイル: RecordHeader.cs プロジェクト: Kim-SSi/DnDns
        /// <summary>
        ///
        /// </summary>
        /// <param name="ms"></param>
        public void ParseRecordHeader(ref MemoryStream ms)
        {
            byte[] nsType       = new byte[2];
            byte[] nsClass      = new byte[2];
            byte[] nsTTL        = new byte[4];
            byte[] nsDataLength = new byte[2];

            // Read the name
            _name = DnsRecordBase.ParseName(ref ms);

            // Read the data header
            ms.Read(nsType, 0, 2);
            ms.Read(nsClass, 0, 2);
            ms.Read(nsTTL, 0, 4);
            ms.Read(nsDataLength, 0, 2);
            _nsType  = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0));
            _nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0));

            _timeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(nsTTL, 0));
            _dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsDataLength, 0));
        }
コード例 #5
0
        public override void ParseRecord(ref MemoryStream ms)
        {
            byte[] priority = new byte[2];
            ms.Read(priority, 0, 2);
            //_priority = (ushort)Tools.ByteToUInt(Priority);
            _priority = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(priority, 0));

            byte[] weight = new byte[2];
            ms.Read(weight, 0, 2);
            // _weight = (ushort)Tools.ByteToUInt(Weight);
            _weight = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(weight, 0));

            byte[] port = new byte[2];
            ms.Read(port, 0, 2);
            //_port = (ushort)Tools.ByteToUInt(port);
            _port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(port, 0));

            _hostName = DnsRecordBase.ParseName(ref ms);

            _answer = "Service Location: \r\nPriority: " + _priority + "\r\nWeight: " +
                      _weight + "\r\nPort: " + _port + "\r\nHostName: " + _hostName + "\r\n";
        }
コード例 #6
0
ファイル: BaseDnsRecord.cs プロジェクト: Kim-SSi/DnDns
        // RFC
        //        4.1.4. Message compression
        //
        // In order to reduce the size of messages, the domain system utilizes a
        // compression scheme which eliminates the repetition of domain names in a
        // message.  In this scheme, an entire domain name or a list of labels at
        // the end of a domain name is replaced with a pointer to a prior occurance
        // of the same name.
        //
        // The pointer takes the form of a two octet sequence:
        //
        //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        //    | 1  1|                OFFSET                   |
        //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        //
        // The first two bits are ones.  This allows a pointer to be distinguished
        // from a label, since the label must begin with two zero bits because
        // labels are restricted to 63 octets or less.  (The 10 and 01 combinations
        // are reserved for future use.)  The OFFSET field specifies an offset from
        // the start of the message (i.e., the first octet of the ID field in the
        // domain header).  A zero offset specifies the first byte of the ID field,
        // etc.
        //
        // The compression scheme allows a domain name in a message to be
        // represented as either:
        //
        //   - a sequence of labels ending in a zero octet
        //   - a pointer
        //   - a sequence of labels ending with a pointer
        //

        internal static string ParseName(ref MemoryStream ms)
        {
            Debug.WriteLine("Reading Name...");
            StringBuilder sb = new StringBuilder();

            uint next = (uint)ms.ReadByte();

            Debug.WriteLine("Next is 0x" + next.ToString("x2"));
            int bPointer;

            while ((next != 0x00))
            {
                // Isolate 2 most significat bits -> e.g. 11xx xxxx
                // if it's 0xc0 (11000000b} then pointer
                switch (0xc0 & next)
                {
                // 0xc0 -> Name is a pointer.
                case 0xc0:
                {
                    // Isolate Offset
                    int offsetMASK = ~0xc0;

                    // Example on how to calculate the offset
                    // e.g.
                    //
                    // So if given the following 2 bytes - 0xc1 0x1c (11000001 00011100)
                    //
                    //  The pointer takes the form of a two octet sequence:
                    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
                    //    | 1  1|                OFFSET                   |
                    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
                    //    | 1  1| 0  0  0  0  0  1  0  0  0  1  1  1  0  0|
                    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
                    //
                    // A pointer is indicated by the a 1 in the two most significant bits
                    // The Offset is the remaining bits.
                    //
                    // The Pointer = 0xc0 (11000000 00000000)
                    // The offset = 0x11c (00000001 00011100)

                    // Move offset into the proper position
                    int offset = (int)(offsetMASK & next) << 8;

                    // extract the pointer to the data in the stream
                    bPointer = ms.ReadByte() + offset;
                    // store the position so we can resume later
                    long oldPtr = ms.Position;
                    // Move to the specified position in the stream and
                    // parse the name (recursive call)
                    ms.Position = bPointer;
                    sb.Append(DnsRecordBase.ParseName(ref ms));
                    Debug.WriteLine(sb.ToString());
                    // Move back to original position, and continue
                    ms.Position = oldPtr;
                    next        = 0x00;
                    break;
                }

                case 0x00:
                {
                    Debug.Assert(next < 0xc0, "Offset cannot be greater then 0xc0.");
                    byte[] buffer = new byte[next];
                    ms.Read(buffer, 0, (int)next);
                    sb.Append(Encoding.ASCII.GetString(buffer, 0, buffer.Length) + ".");
                    next = (uint)ms.ReadByte();
                    Debug.WriteLine("0x" + next.ToString("x2"));
                    break;
                }

                default:
                    throw new InvalidOperationException("There was a problem decompressing the DNS Message.");
                }
            }
            return(sb.ToString());
        }
コード例 #7
0
ファイル: BaseDnsRecord.cs プロジェクト: Kim-SSi/DnDns
 public virtual void ParseRecord(ref MemoryStream ms)
 {
     // Default implementation - the most common.
     _answer = DnsRecordBase.ParseName(ref ms);
 }
コード例 #8
0
ファイル: MInfoRecord.cs プロジェクト: Kim-SSi/DnDns
 public override void ParseRecord(ref MemoryStream ms)
 {
     _responsibleMb = DnsRecordBase.ParseName(ref ms);
     _errorMb       = DnsRecordBase.ParseName(ref ms);
     _answer        = "Responsible MailBox: " + _responsibleMb + ", Error MailBox: " + _errorMb;
 }
コード例 #9
0
ファイル: SoaRecord.cs プロジェクト: Kim-SSi/DnDns
        public override void ParseRecord(ref MemoryStream ms)
        {
            StringBuilder sb = new StringBuilder();

            // Parse Name
            _primaryNameServer = DnsRecordBase.ParseName(ref ms);
            sb.Append("Primary NameServer: ");
            sb.Append(_primaryNameServer);
            sb.Append("\r\n");

            // Parse Responsible Persons Mailbox (Parse Name)
            _responsiblePerson = DnsRecordBase.ParseName(ref ms);
            sb.Append("Responsible Person: ");
            sb.Append(_responsiblePerson);
            sb.Append("\r\n");

            byte[] serial          = new Byte[4];
            byte[] refreshInterval = new Byte[4];
            byte[] retryInterval   = new Byte[4];
            byte[] expirationLimit = new Byte[4];
            byte[] minTTL          = new Byte[4];

            // Parse Serial (4 bytes)
            ms.Read(serial, 0, 4);
            //_serial = Tools.ByteToUInt(serial);
            _serial = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(serial, 0));
            sb.Append("Serial: ");
            sb.Append(_serial);
            sb.Append("\r\n");

            // Parse Refresh Interval (4 bytes)
            ms.Read(refreshInterval, 0, 4);
            // _refreshInterval = Tools.ByteToUInt(refreshInterval);
            _refreshInterval = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(refreshInterval, 0));
            sb.Append("Refresh Interval: ");
            sb.Append(_refreshInterval);
            sb.Append("\r\n");

            // Parse Retry Interval (4 bytes)
            ms.Read(retryInterval, 0, 4);
            //_retryInterval = Tools.ByteToUInt(retryInterval);
            _retryInterval = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(retryInterval, 0));
            sb.Append("Retry Interval: ");
            sb.Append(_retryInterval);
            sb.Append("\r\n");

            // Parse Expiration limit (4 bytes)
            ms.Read(expirationLimit, 0, 4);
            // _expirationLimit = Tools.ByteToUInt(expirationLimit);
            _expirationLimit = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(expirationLimit, 0));
            sb.Append("Expire: ");
            sb.Append(_expirationLimit);
            sb.Append("\r\n");

            // Parse Min TTL (4 bytes)
            ms.Read(minTTL, 0, 4);
            // _minTTL = Tools.ByteToUInt(minTTL);
            _minimumTimeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(minTTL, 0));
            sb.Append("TTL: ");
            sb.Append(_minimumTimeToLive);
            sb.Append("\r\n");

            _answer = sb.ToString();
        }
コード例 #10
0
 public override void ParseRecord(ref MemoryStream ms)
 {
     _name         = DnsRecordBase.ParseName(ref ms);
     _textLocation = DnsRecordBase.ParseName(ref ms);
     _answer       = _name + ", " + _textLocation;
 }