PageRenderTime 4773ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/PcapDotNet/src/PcapDotNet.Packets/Gre/GreLayer.cs

#
C# | 212 lines | 91 code | 22 blank | 99 comment | 25 complexity | 4bf5544a4d9f1678c1e48b15ae2d0e49 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Linq;
  4. using PcapDotNet.Base;
  5. using PcapDotNet.Packets.Ethernet;
  6. using PcapDotNet.Packets.IpV4;
  7. namespace PcapDotNet.Packets.Gre
  8. {
  9. /// <summary>
  10. /// Represents a GRE layer.
  11. /// <seealso cref="GreDatagram"/>
  12. /// </summary>
  13. public sealed class GreLayer : EthernetBaseLayer, IIpNextLayer, IEquatable<GreLayer>
  14. {
  15. /// <summary>
  16. /// The GRE Version Number.
  17. /// </summary>
  18. public GreVersion Version { get; set; }
  19. /// <summary>
  20. /// The Protocol Type field contains the protocol type of the payload packet.
  21. /// These Protocol Types are defined in [RFC1700] as "ETHER TYPES" and in [ETYPES].
  22. /// An implementation receiving a packet containing a Protocol Type which is not listed in [RFC1700] or [ETYPES] SHOULD discard the packet.
  23. /// </summary>
  24. public EthernetType ProtocolType
  25. {
  26. get { return EtherType; }
  27. set { EtherType = value; }
  28. }
  29. /// <summary>
  30. /// Recursion control contains a three bit unsigned integer which contains the number of additional encapsulations which are permissible.
  31. /// This SHOULD default to zero.
  32. /// </summary>
  33. public byte RecursionControl { get; set; }
  34. /// <summary>
  35. /// Must be set to zero (0).
  36. /// </summary>
  37. public byte FutureUseBits { get; set; }
  38. /// <summary>
  39. /// If the Checksum Present bit is set to 1, then the Checksum field is present and contains valid information.
  40. /// If either the Checksum Present bit or the Routing Present bit are set, BOTH the Checksum and Offset fields are present in the GRE packet.
  41. /// </summary>
  42. public bool ChecksumPresent { get; set; }
  43. /// <summary>
  44. /// The Checksum field contains the IP (one's complement) checksum sum of the all the 16 bit words in the GRE header and the payload packet.
  45. /// For purposes of computing the checksum, the value of the checksum field is zero.
  46. /// This field is present only if the Checksum Present bit is set to one.
  47. /// In order to calculate the Checksum automatically, leave null in this field and set the ChecksumPresent field to true.
  48. /// </summary>
  49. public ushort? Checksum { get; set; }
  50. /// <summary>
  51. /// The Key field contains a four octet number which was inserted by the encapsulator.
  52. /// It may be used by the receiver to authenticate the source of the packet.
  53. /// The Key field is only present if the Key Present field is set to 1.
  54. /// null iff the Key isn't present.
  55. /// </summary>
  56. public uint? Key { get; set; }
  57. /// <summary>
  58. /// (High 2 octets of Key) Size of the payload, not including the GRE header.
  59. /// </summary>
  60. public ushort? KeyPayloadLength
  61. {
  62. get { return Key == null ? null : (ushort?)((Key.Value & 0xFFFF0000) >> 16); }
  63. }
  64. /// <summary>
  65. /// (Low 2 octets of Key) Contains the Peer's Call ID for the session to which this packet belongs.
  66. /// </summary>
  67. public ushort? KeyCallId
  68. {
  69. get { return Key == null ? null : (ushort?)(Key.Value & 0x0000FFFF); }
  70. }
  71. /// <summary>
  72. /// Sets the key according to the payload length and call id.
  73. /// </summary>
  74. /// <param name="keyPayloadLength">(High 2 octets of Key) Size of the payload, not including the GRE header.</param>
  75. /// <param name="keyCallId">(Low 2 octets of Key) Contains the Peer's Call ID for the session to which this packet belongs.</param>
  76. public void SetKey(ushort keyPayloadLength, ushort keyCallId)
  77. {
  78. Key = BitSequence.Merge(keyPayloadLength, keyCallId);
  79. }
  80. /// <summary>
  81. /// The Sequence Number field contains an unsigned 32 bit integer which is inserted by the encapsulator.
  82. /// It may be used by the receiver to establish the order in which packets have been transmitted from the encapsulator to the receiver.
  83. /// null off the sequence number present bit is 0.
  84. /// </summary>
  85. public uint? SequenceNumber { get; set; }
  86. /// <summary>
  87. /// Contains the sequence number of the highest numbered GRE packet received by the sending peer for this user session.
  88. /// Present if A bit (Bit 8) is one (1).
  89. /// null iff not present.
  90. /// </summary>
  91. public uint? AcknowledgmentSequenceNumber { get; set; }
  92. /// <summary>
  93. /// The offset field indicates the octet offset from the start of the Routing field to the first octet of the active Source Route Entry to be examined.
  94. /// This field is present if the Routing Present or the Checksum Present bit is set to 1, and contains valid information only if the Routing Present bit is set to 1.
  95. /// Should be null iff the Routing is null (routing is not present).
  96. /// </summary>
  97. public ushort? RoutingOffset { get; set; }
  98. /// <summary>
  99. /// The Routing field is optional and is present only if the Routing Present bit is set to 1.
  100. /// The Routing field is a list of Source Route Entries (SREs).
  101. /// null iff the routing isn't present.
  102. /// </summary>
  103. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
  104. public ReadOnlyCollection<GreSourceRouteEntry> Routing { get; set; }
  105. /// <summary>
  106. /// If the source route is incomplete, then the Strict Source Route bit is checked.
  107. /// If the source route is a strict source route and the next IP destination or autonomous system is NOT an adjacent system, the packet MUST be dropped.
  108. /// </summary>
  109. public bool StrictSourceRoute { get; set; }
  110. /// <summary>
  111. /// The number of bytes this layer will take.
  112. /// </summary>
  113. public override int Length
  114. {
  115. get
  116. {
  117. return GreDatagram.GetHeaderLength(ChecksumPresent, Key != null, SequenceNumber != null, AcknowledgmentSequenceNumber != null, Routing);
  118. }
  119. }
  120. /// <summary>
  121. /// Writes the layer to the buffer.
  122. /// </summary>
  123. /// <param name="buffer">The buffer to write the layer to.</param>
  124. /// <param name="offset">The offset in the buffer to start writing the layer at.</param>
  125. /// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
  126. /// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
  127. /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
  128. public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
  129. {
  130. EthernetType protocolType = ProtocolType;
  131. if (protocolType == EthernetType.None)
  132. {
  133. if (nextLayer == null)
  134. throw new ArgumentException("Can't determine protocol type automatically from next layer because there is not next layer");
  135. IEthernetNextLayer ethernetNextLayer = nextLayer as IEthernetNextLayer;
  136. if (ethernetNextLayer == null)
  137. throw new ArgumentException("Can't determine protocol type automatically from next layer (" + nextLayer.GetType() + ")");
  138. protocolType = ethernetNextLayer.PreviousLayerEtherType;
  139. }
  140. GreDatagram.WriteHeader(buffer, offset, RecursionControl, FutureUseBits, Version, protocolType, ChecksumPresent, Key, SequenceNumber, AcknowledgmentSequenceNumber, Routing, RoutingOffset, StrictSourceRoute);
  141. }
  142. /// <summary>
  143. /// Finalizes the layer data in the buffer.
  144. /// Used for fields that must be calculated according to the layer's payload (like checksum).
  145. /// </summary>
  146. /// <param name="buffer">The buffer to finalize the layer in.</param>
  147. /// <param name="offset">The offset in the buffer the layer starts.</param>
  148. /// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
  149. /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
  150. public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer)
  151. {
  152. if (ChecksumPresent)
  153. GreDatagram.WriteChecksum(buffer, offset, Length + payloadLength, Checksum);
  154. }
  155. /// <summary>
  156. /// True iff the two objects are equal Layers.
  157. /// </summary>
  158. public bool Equals(GreLayer other)
  159. {
  160. return other != null &&
  161. Version.Equals(other.Version) &&
  162. ProtocolType.Equals(other.ProtocolType) &&
  163. RecursionControl.Equals(other.RecursionControl) &&
  164. FutureUseBits.Equals(other.FutureUseBits) &&
  165. ChecksumPresent.Equals(other.ChecksumPresent) &&
  166. (Checksum == null ? other.Checksum == null : Checksum.Equals(other.Checksum)) &&
  167. (Key == null ? other.Key == null : Key.Equals(other.Key)) &&
  168. (SequenceNumber == null ? other.SequenceNumber == null : SequenceNumber.Equals(other.SequenceNumber)) &&
  169. (AcknowledgmentSequenceNumber == null ? other.AcknowledgmentSequenceNumber == null : AcknowledgmentSequenceNumber.Equals(other.AcknowledgmentSequenceNumber)) &&
  170. (RoutingOffset == null ? other.RoutingOffset == null : RoutingOffset.Equals(other.RoutingOffset)) &&
  171. (Routing == null ? other.Routing == null : Routing.SequenceEqual(other.Routing)) &&
  172. StrictSourceRoute.Equals(other.StrictSourceRoute);
  173. }
  174. /// <summary>
  175. /// True iff the two objects are equal Layers.
  176. /// </summary>
  177. public override bool Equals(Layer other)
  178. {
  179. return Equals(other as GreLayer);
  180. }
  181. /// <summary>
  182. /// The protocol that should be written in the previous (IPv4) layer.
  183. /// This is GRE.
  184. /// </summary>
  185. public IpV4Protocol PreviousLayerProtocol
  186. {
  187. get { return IpV4Protocol.Gre; }
  188. }
  189. }
  190. }