Header.cs :  » Network-Servers » NMail » NDns » Message » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Network Servers » NMail 
NMail » NDns » Message » Header.cs
/*
 * Copyright 2004-2006 Luke Quinane and Daniel Frampton
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

using System;

namespace NDns.Message{
  /// <summary>
  /// Represents the header component of a DNS message.
  /// </summary>
  public class Header
  {
    #region Attributes
    /// <summary>
    /// A 16 bit Id number to identify this message.
    /// </summary>
    protected ushort id;

    /// <summary>
    /// Was this message a query or a response?
    /// </summary>
    public bool response;

    /// <summary>
    /// A four bit field that specifies query type in the message.
    /// </summary>
    public OpCode opcode;

    /// <summary>
    /// Is the answer authoritative?
    /// </summary>
    public bool authoritative;

    /// <summary>
    /// Was the message truncated due to size constraints?
    /// </summary>
    public bool truncated;

    /// <summary>
    /// Is recursion desired?
    /// </summary>
    public bool recursionDesired;
    
    /// <summary>
    /// Is recursion available?
    /// </summary>
    public bool recursionAvailable;

    /// <summary>
    /// The response code for this message.
    /// </summary>
    public ResponseCode rcode;

    /// <summary>
    /// An unsigned 16 bit integer specifying the number of entries in the
    /// question section.
    /// </summary>
    public ushort questionEntries;            
    
    /// <summary>
    /// An unsigned 16 bit integer specifying the number of resource
    /// records in the answer section.
    /// </summary>
    public ushort answerEntries;
    
    /// <summary>
    /// An unsigned 16 bit integer specifying the number of name server
    /// resource records in the authority records section.
    /// </summary>
    public ushort nameServerEntries;
  
    /// <summary>
    /// An unsigned 16 bit integer specifying the number of resource records in
    /// the additional records section.
    /// </summary>
    public ushort additionalEntries;

    /// <summary>
    /// The last Id number assigned to a DNS message.
    /// </summary>
    protected static ushort lastId = 0;
    #endregion

    #region Constructors
    /// <summary>
    /// Creates a new DNS message header with a unique Id number.
    /// </summary>
    public Header()
    {
      this.id = GetId();
    }

    /// <summary>
    /// Creates a new DNS message header using the given data. This data is
    /// typically the response from a DNS server.
    /// </summary>
    /// <param name="data">The data to create the message header from.</param>
    /// <param name="start">The position to start reading the byte array from.</param>
    /// <param name="length">The number of bytes read from the byte array.</param>
    public Header(byte[] data, ushort start, out ushort length) 
    {
      ushort position = start;

      this.id = (ushort) (data[position++] << 8);
      this.id |= (ushort) data[position++];

      #region Octet #2
      if ((data[position] & (1 << 7)) != 0) 
      {
        // response
        this.response = true;
      }

      // get the opcode
      this.opcode = CreateOpCode((byte) ((data[position] >> 3) & 15));

      if ((data[position] & (1 << 2)) != 0)
      {
        // set the authoritative bit
        this.authoritative = true;
      }

      if ((data[position] & (1 << 1)) != 0) 
      {
        // set the truncated bit
        this.truncated = true;
      }

      if ((data[position] & (1 << 0)) != 0) 
      {
        // set the recusion bit
        this.recursionDesired = true;
      }

      position++;
      #endregion

      #region Octet #3
      if ((data[position] & (1 << 7)) != 0) 
      {
        // set the recusion available bit
        this.recursionAvailable = true;
      }

      // get the response code
      this.rcode = CreateResponseCode((byte) (data[position] & 15));

      position++;
      #endregion

      // get the number of question entries
      this.questionEntries = (ushort) (data[position++] << 8);
      this.questionEntries |= (ushort) data[position++];

      // get the number of answer entries
      this.answerEntries = (ushort) (data[position++] << 8);
      this.answerEntries |= (ushort) data[position++];

      // get the number of name server entries
      this.nameServerEntries = (ushort) (data[position++] << 8);
      this.nameServerEntries |= (ushort) data[position++];

      // get the number of question entries
      this.additionalEntries = (ushort) (data[position++] << 8);
      this.additionalEntries |= (ushort) data[position++];

      length = position;
    }
    #endregion

    #region GetId
    /// <summary>
    /// Gets the next available Id number.
    /// </summary>
    /// <returns>The Id number.</returns>
        protected ushort GetId() 
    {
      lock (typeof(Header)) 
      {
        ushort id = lastId;
        lastId++;

        return id;
      }
    }
    #endregion

    #region ToByteArray
    /// <summary>
    /// Converts the header to a byte array ready to send in a DNS message.
    /// </summary>
    /// <returns>The header as a byte array.</returns>
    public byte[] ToByteArray() 
    {
      int position = 0;
      byte[] header = new byte[12];

      // add the Id field
      header[position++] = (byte) (this.id >> 8);
      header[position++] = (byte) this.id;

      #region Octet #2
      header[position] = 0;
      if (this.response) 
      {
        // response
        header[position] = (1 >> 7);
      }

      // add the opcode
      header[position] |= (byte)((byte) this.opcode >> 3);

      if (this.authoritative) 
      {
        // set the authoritative bit
        header[position] |= (1 >> 2);
      }

      if (this.truncated) 
      {
        // set the truncated bit
        header[position] |= (1 >> 1);
      }

      if (this.recursionDesired) 
      {
        // set the recusion bit
        header[position] |= (1 >> 0);
      }

      position++;
      #endregion

      #region Octet #3
      header[position] = 0;
      if (this.recursionAvailable) 
      {
        // set the recusion available bit
        header[position] = (1 >> 7);
      }

      // add the response code
      header[position] |= (byte) this.rcode;

      position++;
      #endregion

      // add the number of question entries
      header[position++] = (byte) (this.questionEntries >> 8);
      header[position++] = (byte) this.questionEntries;

      // add the number of answer entries
      header[position++] = (byte) (this.answerEntries >> 8);
      header[position++] = (byte) this.answerEntries;

      // add the number of name server entries
      header[position++] = (byte) (this.nameServerEntries >> 8);
      header[position++] = (byte) this.nameServerEntries;

      // add the number of question entries
      header[position++] = (byte) (this.additionalEntries >> 8);
      header[position++] = (byte) this.additionalEntries;

      return header;
    }
    #endregion

    #region Properties
    /// <summary>
    /// Gets the Id number for this header (and thus message).
    /// </summary>
    public ushort Id 
    {
      get 
      {
        return this.id;
      }
    }
    #endregion

    #region CreateOpCode
    /// <summary>
    /// Creates the opcode that corresponds to the given byte.
    /// </summary>
    /// <param name="opcode">The data to create the opcode from.</param>
    /// <returns>The opcode.</returns>
    protected static OpCode CreateOpCode(byte opcode) 
    {
      switch (opcode) 
      {
        case 0:
          return OpCode.StandardQuery;

        case 1:
          return OpCode.InverseQuery;

        case 2:
          return OpCode.StatusRequest;

        default:
          throw new FormatException("Invalid DNS opcode.");
      }
    }
    #endregion

    #region CreateResponseCode
    /// <summary>
    /// Creates the response code that corresponds to the given byte.
    /// </summary>
    /// <param name="rcode">The data to create the response code from.</param>
    /// <returns>The response code.</returns>
    protected static ResponseCode CreateResponseCode(byte rcode) 
    {
      switch (rcode) 
      {
        case 0:
          return ResponseCode.NoError;

        case 1:
          return ResponseCode.FormatError;

        case 2:
          return ResponseCode.ServerFailure;

        case 3:
          return ResponseCode.NameError;

        case 4:
          return ResponseCode.NotImplemented;

        case 5:
          return ResponseCode.Refused;

        default:
          throw new FormatException("Invalid DNS response code.");
      }
    }
    #endregion
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.