Commit 8aeae762 authored by Brickner_cp's avatar Brickner_cp

Code Analysis and Documentation - 69 warnings left.

parent 87c38e83
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Core.Test
{
......@@ -74,5 +77,39 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual(expectedPacket, actualPacket);
}
}
[TestMethod]
public void Temp()
{
EthernetLayer ethernetLayer = new EthernetLayer
{
Source = new MacAddress("00:01:02:03:04:05"),
Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
};
IpV4Layer ipV4Layer = new IpV4Layer
{
Source = new IpV4Address("1.2.3.4"),
Ttl = 128,
};
IcmpEchoLayer icmpLayer = new IcmpEchoLayer();
PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
List<Packet> packets = new List<Packet>();
for (int i = 0; i != 100; ++i)
{
ipV4Layer.Destination = new IpV4Address("2.3.4." + i);
ipV4Layer.Identification = (ushort)i;
icmpLayer.SequenceNumber = (ushort)i;
icmpLayer.Identifier = (ushort)i;
packets.Add(builder.Build(DateTime.Now));
}
PacketDumpFile.Dump(@"c:\users\boaz\temp.pcap", new PcapDataLink(DataLinkKind.Ethernet), int.MaxValue, packets);
}
}
}
\ No newline at end of file
......@@ -64,22 +64,16 @@ namespace PcapDotNet.Packets.Ethernet
/// Ethernet source address.
/// </summary>
public MacAddress Source
{
get
{
return ReadMacAddress(Offset.Source, Endianity.Big);
}
{
get { return ReadMacAddress(Offset.Source, Endianity.Big); }
}
/// <summary>
/// Ethernet destination address.
/// </summary>
public MacAddress Destination
{
get
{
return ReadMacAddress(Offset.Destination, Endianity.Big);
}
{
get { return ReadMacAddress(Offset.Destination, Endianity.Big); }
}
/// <summary>
......
......@@ -3,12 +3,15 @@ using PcapDotNet.Packets.Arp;
namespace PcapDotNet.Packets.Ethernet
{
/// <summary>
/// Represents an Ethernet layer.
/// <seealso cref="EthernetDatagram"/>
/// </summary>
public class EthernetLayer : Layer, IArpPreviousLayer
{
public MacAddress Source { get; set; }
public MacAddress Destination { get; set; }
public EthernetType EtherType { get; set; }
/// <summary>
/// Creates an instance with zero values.
/// </summary>
public EthernetLayer()
{
Source = MacAddress.Zero;
......@@ -16,11 +19,37 @@ namespace PcapDotNet.Packets.Ethernet
EtherType = EthernetType.None;
}
/// <summary>
/// Ethernet source address.
/// </summary>
public MacAddress Source { get; set; }
/// <summary>
/// Ethernet destination address.
/// </summary>
public MacAddress Destination { get; set; }
/// <summary>
/// Ethernet type (next protocol).
/// </summary>
public EthernetType EtherType { get; set; }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return EthernetDatagram.HeaderLength; }
}
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
EthernetType etherType = EtherType;
......@@ -44,11 +73,18 @@ namespace PcapDotNet.Packets.Ethernet
EthernetDatagram.WriteHeader(buffer, 0, Source, destination, etherType);
}
/// <summary>
/// The kind of the data link of the layer.
/// Can be null if this is not the first layer in the packet.
/// </summary>
public override DataLinkKind? DataLink
{
get { return DataLinkKind.Ethernet; }
}
/// <summary>
/// The ARP Hardware Type of the layer before the ARP layer.
/// </summary>
public ArpHardwareType PreviousLayerHardwareType
{
get { return ArpHardwareType.Ethernet; }
......
......@@ -14,6 +14,9 @@ namespace PcapDotNet.Packets.Ethernet
/// </summary>
public const int SizeOf = UInt48.SizeOf;
/// <summary>
/// A MAC Address of all zeros (00:00:00:00:00:00).
/// </summary>
public static MacAddress Zero
{
get { return _zero; }
......
......@@ -21,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpAddressMaskReplyLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpAddressMaskReplyLayer : IcmpAddressMaskRequestLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.AddressMaskReply; }
......
......@@ -19,7 +19,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpAddressMaskRequestDatagram : IcmpIdentifiedDatagram
{
/// <summary>
/// The number of bytes this Datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 4;
private static class Offset
......@@ -40,6 +47,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpAddressMaskRequestLayer
......
......@@ -2,34 +2,57 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 950.
/// Represents an ICMP Trace Route message layer.
/// <seealso cref="IcmpAddressMaskRequestDatagram"/>
/// </summary>
public class IcmpAddressMaskRequestLayer : IcmpIdentifiedLayer
{
/// <summary>
/// A 32-bit mask.
/// </summary>
public IpV4Address AddressMask { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.AddressMaskRequest; }
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength
{
get
{
return IcmpAddressMaskRequestDatagram.PayloadLength;
}
get { return IcmpAddressMaskRequestDatagram.PayloadLength; }
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected override void WritePayload(byte[] buffer, int offset)
{
IcmpAddressMaskRequestDatagram.WriteHeaderAdditional(buffer, offset, AddressMask);
}
/// <summary>
/// Two ICMP Address Mask Request layers are equal if they have the same sequence number, identifier and address mask.
/// </summary>
public bool Equals(IcmpAddressMaskRequestLayer other)
{
return other != null &&
AddressMask == other.AddressMask;
}
/// <summary>
/// Two ICMP Address Mask Request layers are equal if they have the same sequence number, identifier and address mask.
/// </summary>
public override sealed bool Equals(IcmpLayer other)
{
return base.Equals(other) && Equals(other as IcmpAddressMaskRequestLayer);
......
......@@ -24,6 +24,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram
{
/// <summary>
/// The number of bytes that should be taken from the original datagram for an unsupported transport protocol ICMP code.
/// </summary>
public const int OriginalDatagramLengthForUnsupportedTransportProtocol = 256;
private static class Offset
......@@ -39,6 +42,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUInt(Offset.Pointer, Endianity.Big); }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpConversionFailedLayer
......@@ -73,11 +79,17 @@ namespace PcapDotNet.Packets.Icmp
}
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -2,30 +2,43 @@ namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1475.
/// Represents a Conversion Failed ICMP layer.
/// <seealso cref="IcmpConversionFailedDatagram"/>
/// </summary>
public class IcmpConversionFailedLayer : IcmpLayer
{
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeConversionFailed Code { get; set; }
/// <summary>
/// An offset from the start of the original datagram to the beginning of the offending field.
/// </summary>
public uint Pointer { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.ConversionFailed; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get
{
return (byte)Code;
}
get { return (byte)Code; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
return Pointer;
}
get { return Pointer; }
}
}
}
\ No newline at end of file
......@@ -43,11 +43,17 @@ namespace PcapDotNet.Packets.Icmp
get { return (IcmpMessageType)this[Offset.Type]; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public byte Code
{
get { return this[Offset.Code]; }
}
/// <summary>
/// A combination of the ICMP Message Type and Code.
/// </summary>
public IcmpMessageTypeAndCode MessageTypeAndCode
{
get { return (IcmpMessageTypeAndCode)ReadUShort(Offset.Type, Endianity.Big); }
......@@ -63,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Checksum, Endianity.Big); }
}
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
public uint Variable
{
get { return ReadUInt(Offset.Variable, Endianity.Big); }
......@@ -81,6 +90,9 @@ namespace PcapDotNet.Packets.Icmp
}
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override abstract ILayer ExtractLayer();
public Datagram Payload
......@@ -114,16 +126,25 @@ namespace PcapDotNet.Packets.Icmp
buffer.Write(offset + Offset.Checksum, checksumValue, Endianity.Big);
}
/// <summary>
/// ICMP is valid if the datagram's length is OK, the checksum is correct and the code is in the expected range.
/// </summary>
protected override bool CalculateIsValid()
{
return Length >= HeaderLength && IsChecksumCorrect && Code >= MinCodeValue && Code <= MaxCodeValue;
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected virtual byte MinCodeValue
{
get { return 0; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected virtual byte MaxCodeValue
{
get { return 0; }
......
......@@ -26,16 +26,24 @@ namespace PcapDotNet.Packets.Icmp
public const int NextHopMtu = 6;
}
public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
internal IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// The size in octets of the largest datagram that could be forwarded,
/// along the path of the original datagram, without being fragmented at this router.
/// The size includes the IP header and IP data, and does not include any lower-level headers.
/// </summary>
public ushort NextHopMaximumTransmissionUnit
{
get { return ReadUShort(Offset.NextHopMtu, Endianity.Big); }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpDestinationUnreachableLayer
......@@ -53,11 +61,17 @@ namespace PcapDotNet.Packets.Icmp
NextHopMaximumTransmissionUnit == 0);
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -2,35 +2,42 @@ namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792 and RFC 1191.
/// <seealso cref="IcmpDestinationUnreachableDatagram"/>
/// </summary>
public class IcmpDestinationUnreachableLayer : IcmpLayer
{
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeDestinationUnreachable Code { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.DestinationUnreachable; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get { return (byte)Code; }
}
/// <summary>
/// The size in octets of the largest datagram that could be forwarded,
/// along the path of the original datagram, without being fragmented at this router.
/// The size includes the IP header and IP data, and does not include any lower-level headers.
/// </summary>
public ushort NextHopMaximumTransmissionUnit { get; set; }
public bool Equals(IcmpDestinationUnreachableLayer other)
{
return other != null &&
NextHopMaximumTransmissionUnit == other.NextHopMaximumTransmissionUnit;
}
public override sealed bool Equals(IcmpLayer other)
{
return base.Equals(other) && Equals(other as IcmpDestinationUnreachableLayer);
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get { return NextHopMaximumTransmissionUnit; }
}
......
......@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpDomainNameRequestLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpDomainNameRequestLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.DomainNameRequest; }
......
......@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpEchoDatagram : IcmpIdentifiedDatagram
{
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpEchoLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpEchoLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Echo; }
......
......@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpEchoReplyDatagram : IcmpIdentifiedDatagram
{
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpEchoReplyLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpEchoReplyLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.EchoReply; }
......
......@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Icmp
}
/// <summary>
/// If code = 0, an identifier to aid in matching requests and replies, may be zero.
/// An identifier to aid in matching requests and replies, may be zero.
/// </summary>
public ushort Identifier
{
......@@ -29,7 +29,7 @@ namespace PcapDotNet.Packets.Icmp
}
/// <summary>
/// If code = 0, a sequence number to aid in matching requests and replies, may be zero.
/// A sequence number to aid in matching requests and replies, may be zero.
/// </summary>
public ushort SequenceNumber
{
......
......@@ -5,16 +5,22 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public abstract class IcmpIdentifiedLayer : IcmpLayer
{
/// <summary>
/// An identifier to aid in matching requests and replies, may be zero.
/// </summary>
public ushort Identifier { get; set; }
/// <summary>
/// A sequence number to aid in matching requests and replies, may be zero.
/// </summary>
public ushort SequenceNumber { get; set; }
protected override sealed uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override sealed uint Variable
{
get
{
return (uint)((Identifier << 16) | SequenceNumber);
}
get { return (uint)((Identifier << 16) | SequenceNumber); }
}
}
}
\ No newline at end of file
......@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpInformationReplyLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpInformationReplyLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.InformationReply; }
......
......@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpInformationRequestLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpInformationRequestLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.InformationRequest; }
......
......@@ -20,6 +20,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram
{
/// <summary>
/// The number of bytes this payload includes from the original data datagram.
/// </summary>
public const int OriginalDatagramPayloadLength = 8;
internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length)
......@@ -27,6 +30,10 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// ICMP with IPv4 payload and 64 bits IPv4 payload is valid if the datagram's length is OK, the checksum is correct, the code is in the expected range,
/// the IPv4 payload contains at least an IPv4 header and the IPv4's payload is in the expected size.
/// </summary>
protected override bool CalculateIsValid()
{
if (!base.CalculateIsValid())
......
......@@ -22,6 +22,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// The ICMP payload as an IPv4 datagram.
/// </summary>
public IpV4Datagram IpV4
{
get
......@@ -32,6 +35,10 @@ namespace PcapDotNet.Packets.Icmp
}
}
/// <summary>
/// ICMP with IPv4 payload is valid if the datagram's length is OK, the checksum is correct, the code is in the expected range,
/// and the IPv4 payload contains at least an IPv4 header.
/// </summary>
protected override bool CalculateIsValid()
{
if (!base.CalculateIsValid())
......
......@@ -3,43 +3,84 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// Represents an ICMP layer.
/// <seealso cref="IcmpDatagram"/>
/// </summary>
public abstract class IcmpLayer : SimpleLayer, IIpV4NextLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public abstract IcmpMessageType MessageType { get; }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public virtual byte CodeValue
{
get { return 0; }
}
public IcmpMessageTypeAndCode MessageTypeAndCode
/// <summary>
/// A combination of the ICMP Message Type and Code.
/// </summary>
public IcmpMessageTypeAndCode MessageTypeAndCode
{
get
{
return (IcmpMessageTypeAndCode)(((ushort)MessageType << 8) | CodeValue);
}
get { return (IcmpMessageTypeAndCode)(((ushort)MessageType << 8) | CodeValue); }
}
/// <summary>
/// The checksum is the 16-bit ones's complement of the one's complement sum of the ICMP message starting with the ICMP Type.
/// For computing the checksum, the checksum field should be zero.
/// This checksum may be replaced in the future.
/// null means that this checksum should be calculated to be correct.
/// </summary>
public ushort? Checksum { get; set; }
protected virtual uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected virtual uint Variable
{
get { return 0; }
}
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override sealed int Length
{
get { return IcmpDatagram.HeaderLength + PayloadLength; }
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected virtual int PayloadLength
{
get { return 0; }
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected override sealed void Write(byte[] buffer, int offset)
{
IcmpDatagram.WriteHeader(buffer, offset, MessageType, CodeValue, Value);
IcmpDatagram.WriteHeader(buffer, offset, MessageType, CodeValue, Variable);
WritePayload(buffer, offset + IcmpDatagram.HeaderLength);
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected virtual void WritePayload(byte[] buffer, int offset)
{
}
......@@ -49,6 +90,9 @@ namespace PcapDotNet.Packets.Icmp
IcmpDatagram.WriteChecksum(buffer, offset, Length + payloadLength, Checksum);
}
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.InternetControlMessageProtocol; }
......@@ -59,7 +103,7 @@ namespace PcapDotNet.Packets.Icmp
return other != null &&
MessageType == other.MessageType && CodeValue == other.CodeValue &&
Checksum == other.Checksum &&
Value == other.Value;
Variable == other.Variable;
}
public sealed override bool Equals(Layer other)
......@@ -70,12 +114,12 @@ namespace PcapDotNet.Packets.Icmp
public override int GetHashCode()
{
return base.GetHashCode() ^
MessageTypeAndCode.GetHashCode() ^ Checksum.GetHashCode() ^ Value.GetHashCode();
MessageTypeAndCode.GetHashCode() ^ Checksum.GetHashCode() ^ Variable.GetHashCode();
}
public override string ToString()
{
return MessageType + "." + CodeValue + "(" + Value + ")";
return MessageType + "." + CodeValue + "(" + Variable + ")";
}
}
}
\ No newline at end of file
......@@ -39,6 +39,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpParameterProblemLayer
......
......@@ -5,19 +5,26 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpParameterProblemLayer : IcmpLayer
{
/// <summary>
/// The pointer identifies the octet of the original datagram's header where the error was detected (it may be in the middle of an option).
/// For example, 1 indicates something is wrong with the Type of Service, and (if there are options present) 20 indicates something is wrong with the type code of the first option.
/// </summary>
public byte Pointer { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.ParameterProblem; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
return (uint)(Pointer << 24);
}
get { return (uint)(Pointer << 24); }
}
}
}
\ No newline at end of file
......@@ -51,11 +51,17 @@ namespace PcapDotNet.Packets.Icmp
};
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -2,29 +2,45 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// Represents an ICMP Redirect message layer.
/// <seealso cref="IcmpRedirectDatagram"/>
/// </summary>
public class IcmpRedirectLayer : IcmpLayer
{
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeRedirect Code { get; set; }
public IpV4Address GatewayInternetAddress{get;set;}
/// <summary>
/// Address of the gateway to which traffic for the network specified in the internet destination network field of the original datagram's data should be sent.
/// </summary>
public IpV4Address GatewayInternetAddress { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Redirect; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get
{
return (byte)Code;
}
get { return (byte)Code; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
return GatewayInternetAddress.ToValue();
}
get { return GatewayInternetAddress.ToValue(); }
}
}
}
\ No newline at end of file
......@@ -31,6 +31,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpDatagram
{
/// <summary>
/// The default number of 32-bit words of information per each router address.
/// </summary>
public const int DefaultAddressEntrySize = 2;
private static class Offset
......@@ -99,6 +102,9 @@ namespace PcapDotNet.Packets.Icmp
}
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpRouterAdvertisementLayer(Entries.ToList())
......
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
public class IcmpRouterAdvertisementEntry
/// <summary>
/// RFC 1256.
/// Represents an entry in Router Advertisement ICMP message.
/// </summary>
public class IcmpRouterAdvertisementEntry : IEquatable<IcmpRouterAdvertisementEntry>
{
/// <summary>
/// Creates an instance using the given router address and preference.
/// </summary>
/// <param name="routerAddress">The sending router's IP address(es) on the interface from which this message is sent.</param>
/// <param name="routerAddressPreference">The preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet. A signed, twos-complement value; higher values mean more preferable.</param>
public IcmpRouterAdvertisementEntry(IpV4Address routerAddress, int routerAddressPreference)
{
_routerAddress = routerAddress;
_routerAddressPreference = routerAddressPreference;
}
/// <summary>
/// The sending router's IP address(es) on the interface from which this message is sent.
/// </summary>
public IpV4Address RouterAddress
{
get { return _routerAddress;}
}
/// <summary>
/// The preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet. A signed, twos-complement value; higher values mean more preferable.
/// </summary>
public int RouterAddressPreference
{
get {return _routerAddressPreference; }
}
/// <summary>
/// Two entries are equal if they have the same router address and preference.
/// </summary>
public bool Equals(IcmpRouterAdvertisementEntry other)
{
return other != null &&
......@@ -27,6 +46,9 @@ namespace PcapDotNet.Packets.Icmp
RouterAddressPreference == other.RouterAddressPreference;
}
/// <summary>
/// Two entries are equal if they have the same router address and preference.
/// </summary>
public override bool Equals(object obj)
{
return Equals(obj as IcmpRouterAdvertisementEntry);
......
......@@ -5,22 +5,50 @@ using System.Linq;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1256.
/// An ICMP Router Advertisement layer.
/// <seealso cref="IcmpRouterAdvertisementDatagram"/>
/// </summary>
public class IcmpRouterAdvertisementLayer : IcmpLayer
{
/// <summary>
/// Creates an instance with the given router advertisement entries.
/// </summary>
/// <param name="entries">
/// The pairs of sending router's IP address(es) on the interface from which this message is sent
/// and the preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet.
/// A signed, twos-complement value; higher values mean more preferable.
/// </param>
public IcmpRouterAdvertisementLayer(IList<IcmpRouterAdvertisementEntry> entries)
{
_entries = entries;
}
/// <summary>
/// The maximum time that the router addresses may be considered valid.
/// </summary>
public TimeSpan Lifetime { get; set; }
public IList<IcmpRouterAdvertisementEntry> Entries { get { return _entries;} }
/// <summary>
/// The pairs of sending router's IP address(es) on the interface from which this message is sent
/// and the preferability of each Router Address[i] as a default router address, relative to other router addresses on the same subnet.
/// A signed, twos-complement value; higher values mean more preferable.
/// </summary>
public IList<IcmpRouterAdvertisementEntry> Entries { get { return _entries; } }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.RouterAdvertisement; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
......@@ -30,14 +58,20 @@ namespace PcapDotNet.Packets.Icmp
}
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength
{
get
{
return IcmpRouterAdvertisementDatagram.GetPayloadLength(Entries.Count);
}
get { return IcmpRouterAdvertisementDatagram.GetPayloadLength(Entries.Count); }
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected override void WritePayload(byte[] buffer, int offset)
{
IcmpRouterAdvertisementDatagram.WriteHeaderAdditional(buffer, offset, Entries);
......
......@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpRouterSolicitationLayer();
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpRouterSolicitationLayer : IcmpLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.RouterSolicitation; }
......
......@@ -41,6 +41,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Pointer, Endianity.Big); }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpSecurityFailuresLayer
......@@ -56,11 +59,17 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Pointer < IpV4.Length;
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -2,30 +2,44 @@ namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 2521.
/// Represents an ICMP Security Failures layer.
/// <seealso cref="IcmpSecurityFailuresDatagram"/>
/// </summary>
public class IcmpSecurityFailuresLayer : IcmpLayer
{
public IcmpCodeSecurityFailure Code{get; set ;}
public ushort Pointer{get; set ;}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeSecurityFailure Code { get; set; }
/// <summary>
/// An offset into the Original Internet Headers that locates the most significant octet of the offending SPI.
/// Will be zero when no SPI is present.
/// </summary>
public ushort Pointer { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.SecurityFailures; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get
{
return (byte)Code;
}
get { return (byte)Code; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
return Pointer;
}
get { return Pointer; }
}
}
}
\ No newline at end of file
......@@ -20,11 +20,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
public IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
internal IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpSourceQuenchLayer
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpSourceQuenchLayer : IcmpLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.SourceQuench; }
......
......@@ -21,11 +21,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
public IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
internal IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpTimeExceededLayer
......@@ -35,11 +38,17 @@ namespace PcapDotNet.Packets.Icmp
};
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -5,13 +5,22 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimeExceededLayer : IcmpLayer
{
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeTimeExceeded Code { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.TimeExceeded; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get { return (byte)Code; }
......
......@@ -23,7 +23,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{
/// <summary>
/// The number of bytes this datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 12;
private static class Offset
......@@ -62,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadIpV4TimeOfDay(Offset.TransmitTimestamp, Endianity.Big); }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpTimestampLayer
......
......@@ -2,24 +2,50 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// Represents an ICMP Timestamp layer.
/// <seealso cref="IcmpTimestampDatagram"/>
/// </summary>
public class IcmpTimestampLayer : IcmpIdentifiedLayer
{
/// <summary>
/// The time the sender last touched the message before sending it.
/// </summary>
public IpV4TimeOfDay OriginateTimestamp { get; set; }
/// <summary>
/// The time the echoer first touched it on receipt.
/// </summary>
public IpV4TimeOfDay ReceiveTimestamp { get; set; }
/// <summary>
/// The time the echoer last touched the message on sending it.
/// </summary>
public IpV4TimeOfDay TransmitTimestamp { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.Timestamp; }
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength
{
get
{
return IcmpTimestampDatagram.PayloadLength;
}
get { return IcmpTimestampDatagram.PayloadLength; }
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected override void WritePayload(byte[] buffer, int offset)
{
IcmpTimestampDatagram.WriteHeaderAdditional(buffer, offset,
......
......@@ -25,6 +25,9 @@ namespace PcapDotNet.Packets.Icmp
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpTimestampReplyLayer
......
......@@ -5,12 +5,12 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTimestampReplyLayer : IcmpTimestampLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get
{
return IcmpMessageType.TimestampReply;
}
get { return IcmpMessageType.TimestampReply; }
}
}
}
\ No newline at end of file
......@@ -24,8 +24,19 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTraceRouteDatagram : IcmpDatagram
{
/// <summary>
/// The number of bytes this datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 12;
/// <summary>
/// The value the Return Hop Count should be for an outbound ICMP packet.
/// </summary>
public const ushort OutboundReturnHopCountValue = 0xFFFF;
private static class Offset
......@@ -92,6 +103,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReturnHopCount == OutboundReturnHopCountValue; }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpTraceRouteLayer
......@@ -111,11 +125,17 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Length == DatagramLength;
}
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue
{
get { return _minCode; }
}
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue
{
get { return _maxCode; }
......
......@@ -2,49 +2,86 @@ using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1393.
/// Represents an ICMP Trace Route message layer.
/// <seealso cref="IcmpTraceRouteDatagram"/>
/// </summary>
public class IcmpTraceRouteLayer : IcmpLayer
{
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeTraceRoute Code { get; set; }
public ushort Identification{get;set;}
public ushort OutboundHopCount{get;set;}
/// <summary>
/// The ID Number as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// This is NOT related to the ID number in the IP header.
/// </summary>
public ushort Identification { get; set; }
public ushort ReturnHopCount{get;set;}
/// <summary>
/// The Outbound Hop Count as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// </summary>
public ushort OutboundHopCount { get; set; }
public uint OutputLinkSpeed{get;set;}
public uint OutputLinkMaximumTransmissionUnit{get;set;}
/// <summary>
/// The Return Hop Count as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// </summary>
public ushort ReturnHopCount { get; set; }
/// <summary>
/// The speed, in OCTETS per second, of the link over which the Outbound/Return Packet will be sent.
/// Since it will not be long before network speeds exceed 4.3Gb/s, and since some machines deal poorly with fields longer than 32 bits, octets per second was chosen over bits per second.
/// If this value cannot be determined, the field should be set to zero.
/// </summary>
public uint OutputLinkSpeed { get; set; }
/// <summary>
/// The MTU, in bytes, of the link over which the Outbound/Return Packet will be sent.
/// MTU refers to the data portion (includes IP header; excludes datalink header/trailer) of the packet.
/// If this value cannot be determined, the field should be set to zero.
/// </summary>
public uint OutputLinkMaximumTransmissionUnit { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get { return IcmpMessageType.TraceRoute; }
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength
{
get
{
return IcmpTraceRouteDatagram.PayloadLength;
}
get { return IcmpTraceRouteDatagram.PayloadLength; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get
{
return (byte)Code;
}
get { return (byte)Code; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get
{
return (uint)(Identification << 16);
}
get { return (uint)(Identification << 16); }
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected override void WritePayload(byte[] buffer, int offset)
{
IcmpTraceRouteDatagram.WriteHeaderAdditional(buffer, offset, OutboundHopCount, ReturnHopCount, OutputLinkSpeed, OutputLinkMaximumTransmissionUnit);
......
......@@ -5,11 +5,20 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpUnknownDatagram : IcmpDatagram
{
public IcmpUnknownDatagram(byte[] buffer, int offset, int length)
/// <summary>
/// Take only part of the bytes as a datagarm.
/// </summary>
/// <param name="buffer">The bytes to take the datagram from.</param>
/// <param name="offset">The offset in the buffer to start taking the bytes from.</param>
/// <param name="length">The number of bytes to take.</param>
internal IcmpUnknownDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IcmpUnknownLayer
......@@ -17,11 +26,14 @@ namespace PcapDotNet.Packets.Icmp
LayerMessageType = (byte)MessageType,
LayerCode = Code,
Checksum = Checksum,
LayerValue = Variable,
LayerVariable = Variable,
Payload = Payload
};
}
/// <summary>
/// Unknown ICMP datagrams are always invalid.
/// </summary>
protected override bool CalculateIsValid()
{
return false;
......
......@@ -2,43 +2,69 @@ namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// Represents an ICMP layer with an unknown message type.
/// <seealso cref="IcmpUnknownDatagram"/>
/// </summary>
public class IcmpUnknownLayer : IcmpLayer
{
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public byte LayerMessageType { get; set; }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public byte LayerCode { get; set; }
public uint LayerValue { get; set; }
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
public uint LayerVariable { get; set; }
/// <summary>
/// The payload of the ICMP.
/// All the data without the ICMP header.
/// </summary>
public Datagram Payload { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType
{
get
{
return (IcmpMessageType)LayerMessageType;
}
get { return (IcmpMessageType)LayerMessageType; }
}
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue
{
get
{
return LayerCode;
}
get { return LayerCode; }
}
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength
{
get
{
return Payload.Length;
}
get { return Payload.Length; }
}
protected override uint Value
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
protected override uint Variable
{
get { return LayerValue; }
get { return LayerVariable; }
}
/// <summary>
/// Writes the ICMP payload to the buffer.
/// Doesn't include payload in the next layers.
/// </summary>
/// <param name="buffer">The buffer to write the ICMP payload to.</param>
/// <param name="offset">The offset in the buffer to start writing the payload at.</param>
protected override void WritePayload(byte[] buffer, int offset)
{
Payload.Write(buffer, offset);
......
......@@ -2,8 +2,18 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// Represents an IGMP layer that contains a Group Address.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public interface IIgmpLayerWithGroupAddress
{
/// <summary>
/// The Group Address field is set to zero when sending a General Query,
/// and set to the IP multicast address being queried when sending a Group-Specific Query or Group-and-Source-Specific Query.
/// In a Membership Report of version 1 or 2 or Leave Group message, the group address field holds the IP multicast group address of the group being reported or left.
/// In a Membership Report of version 3 this field is meaningless.
/// </summary>
IpV4Address GroupAddress { get; set; }
}
}
\ No newline at end of file
......@@ -484,6 +484,9 @@ namespace PcapDotNet.Packets.Igmp
}
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
switch (MessageType)
......
......@@ -4,15 +4,34 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// The base of all IGMP layers.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpLayer : SimpleLayer, IIpV4NextLayer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public abstract IgmpMessageType MessageType { get; }
/// <summary>
/// The IGMP version of a Membership Query message.
/// If the type is not a query, None will be returned.
/// </summary>
public virtual IgmpQueryVersion QueryVersion
{
get { return IgmpQueryVersion.None; }
}
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public abstract TimeSpan MaxResponseTimeValue { get; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.InternetGroupManagementProtocol; }
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public class IgmpLeaveGroupVersion2Layer : IgmpVersion2Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.LeaveGroupVersion2; }
......
......@@ -5,11 +5,18 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public class IgmpQueryVersion1Layer : IgmpVersion1Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipQuery; }
}
/// <summary>
/// The IGMP version of a Membership Query message.
/// If the type is not a query, None will be returned.
/// </summary>
public override IgmpQueryVersion QueryVersion
{
get
......
......@@ -5,17 +5,21 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public class IgmpQueryVersion2Layer : IgmpVersion2Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipQuery; }
}
/// <summary>
/// The IGMP version of a Membership Query message.
/// If the type is not a query, None will be returned.
/// </summary>
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version2;
}
get { return IgmpQueryVersion.Version2; }
}
}
}
\ No newline at end of file
......@@ -7,33 +7,82 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 3376.
/// Represents an IGMP Query version 3 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public class IgmpQueryVersion3Layer : IgmpLayer, IIgmpLayerWithGroupAddress
{
/// <summary>
/// A query on 0 source addresses.
/// </summary>
public IgmpQueryVersion3Layer()
:this(new List<IpV4Address>())
{
}
/// <summary>
/// A query on the given source addresses.
/// </summary>
public IgmpQueryVersion3Layer(IList<IpV4Address> sourceAddresses)
{
_sourceAddresses = sourceAddresses;
}
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public TimeSpan MaxResponseTime { get; set; }
public IpV4Address GroupAddress { get; set; }
public bool IsSuppressRouterSideProcessing { get; set; }
public byte QueryRobustnessVariable{get; set ;}
public TimeSpan QueryInterval{get; set ;}
/// <summary>
/// The Group Address field is set to zero when sending a General Query,
/// and set to the IP multicast address being queried when sending a Group-Specific Query or Group-and-Source-Specific Query.
/// In a Membership Report of version 1 or 2 or Leave Group message, the group address field holds the IP multicast group address of the group being reported or left.
/// In a Membership Report of version 3 this field is meaningless.
/// </summary>
public IpV4Address GroupAddress { get; set; }
public IList<IpV4Address> SourceAddresses{get { return _sourceAddresses;}}
/// <summary>
/// When set to one, the S Flag indicates to any receiving multicast routers that they are to suppress the normal timer updates they perform upon hearing a Query.
/// It does not, however, suppress the querier election or the normal "host-side" processing of a Query
/// that a router may be required to perform as a consequence of itself being a group member.
/// </summary>
public bool IsSuppressRouterSideProcessing { get; set; }
/// <summary>
/// If non-zero, the QRV field contains the [Robustness Variable] value used by the querier, i.e., the sender of the Query.
/// If the querier's [Robustness Variable] exceeds 7, the maximum value of the QRV field, the QRV is set to zero.
/// Routers adopt the QRV value from the most recently received Query as their own [Robustness Variable] value,
/// unless that most recently received QRV was zero, in which case the receivers use the default [Robustness Variable] value or a statically configured value.
/// </summary>
public byte QueryRobustnessVariable { get; set; }
/// <summary>
/// The actual interval, called the Querier's Query Interval (QQI).
/// </summary>
public TimeSpan QueryInterval { get; set; }
/// <summary>
/// The Source Address [i] fields are a vector of n IP unicast addresses,
/// where n is the value in the Number of Sources (N) field.
/// </summary>
public IList<IpV4Address> SourceAddresses { get { return _sourceAddresses; } }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return IgmpDatagram.GetQueryVersion3Length(SourceAddresses.Count); }
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected override void Write(byte[] buffer, int offset)
{
IgmpDatagram.WriteQueryVersion3(buffer, offset,
......@@ -41,19 +90,26 @@ namespace PcapDotNet.Packets.Igmp
QueryInterval, SourceAddresses);
}
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipQuery; }
}
/// <summary>
/// The IGMP version of a Membership Query message.
/// If the type is not a query, None will be returned.
/// </summary>
public override IgmpQueryVersion QueryVersion
{
get
{
return IgmpQueryVersion.Version3;
}
get { return IgmpQueryVersion.Version3; }
}
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue
{
get { return MaxResponseTime; }
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public class IgmpReportVersion1Layer : IgmpVersion1Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipReportVersion1; }
......
......@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public class IgmpReportVersion2Layer : IgmpVersion2Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipReportVersion2; }
......
......@@ -6,38 +6,70 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 3376.
/// Represents an IGMP Report version 3 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public class IgmpReportVersion3Layer : IgmpLayer
{
/// <summary>
/// Creates an instance with no group records.
/// </summary>
public IgmpReportVersion3Layer()
:this(new List<IgmpGroupRecord>())
{
}
/// <summary>
/// Creates an instance with the given group records.
/// </summary>
/// <param name="groupRecords">
/// Each Group Record is a block of fields containing information pertaining to the sender's membership in a single multicast group on the interface from which the Report is sent.
/// </param>
public IgmpReportVersion3Layer(IList<IgmpGroupRecord> groupRecords)
{
_groupRecords = groupRecords;
}
/// <summary>
/// Each Group Record is a block of fields containing information pertaining to the sender's membership in a single multicast group on the interface from which the Report is sent.
/// </summary>
public IList<IgmpGroupRecord> GroupRecords
{
get { return _groupRecords; }
}
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return IgmpDatagram.GetReportVersion3Length(GroupRecords); }
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected override void Write(byte[] buffer, int offset)
{
IgmpDatagram.WriteReportVersion3(buffer, offset, GroupRecords);
}
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.MembershipReportVersion3; }
}
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue
{
get { return TimeSpan.Zero; }
......
......@@ -2,14 +2,35 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// Represents a Simple IGMP layer.
/// A simple layer only has the 8 bytes header without additional fields.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpSimpleLayer : IgmpLayer, IIgmpLayerWithGroupAddress
{
/// <summary>
/// The Group Address field is set to zero when sending a General Query,
/// and set to the IP multicast address being queried when sending a Group-Specific Query or Group-and-Source-Specific Query.
/// In a Membership Report of version 1 or 2 or Leave Group message, the group address field holds the IP multicast group address of the group being reported or left.
/// In a Membership Report of version 3 this field is meaningless.
/// </summary>
public IpV4Address GroupAddress { get; set; }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return IgmpDatagram.HeaderLength; }
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected override void Write(byte[] buffer, int offset)
{
IgmpDatagram.WriteHeader(buffer, offset,
......
......@@ -2,8 +2,16 @@ using System;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 1112.
/// Represents an IGMP version 1 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpVersion1Layer : IgmpSimpleLayer
{
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue
{
get { return TimeSpan.Zero; }
......
......@@ -2,9 +2,21 @@ using System;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 2236.
/// Represents a generic IGMP version 2 datagram.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpVersion2Layer : IgmpSimpleLayer
{
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public TimeSpan MaxResponseTime { get; set; }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue
{
get { return MaxResponseTime; }
......
......@@ -6,6 +6,9 @@ namespace PcapDotNet.Packets.IpV4
/// </summary>
public interface IIpV4NextLayer : ILayer
{
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
IpV4Protocol PreviousLayerProtocol { get; }
}
}
\ No newline at end of file
......@@ -6,10 +6,27 @@ namespace PcapDotNet.Packets.IpV4
/// </summary>
public interface IIpV4NextTransportLayer : IIpV4NextLayer
{
/// <summary>
/// Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header,
/// the Transport header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.
/// If null is given, the Checksum will be calculated to be correct according to the data.
/// </summary>
ushort? Checksum { get; set; }
/// <summary>
/// Whether the checksum should be calculated.
/// Can be false in UDP because the checksum is optional. false means that the checksum will be left zero.
/// </summary>
bool CalculateChecksum { get; }
int NextLayerChecksumOffset { get; }
bool NextLayerIsChecksumOptional { get; }
bool NextLayerCalculateChecksum { get; }
/// <summary>
/// The offset in the layer where the checksum should be written.
/// </summary>
int ChecksumOffset { get; }
/// <summary>
/// Whether the checksum is optional in the layer.
/// </summary>
bool IsChecksumOptional { get; }
}
}
\ No newline at end of file
......@@ -138,7 +138,7 @@ namespace PcapDotNet.Packets.IpV4
}
/// <summary>
/// The header check sum value.
/// The header checksum value.
/// </summary>
public ushort HeaderChecksum
{
......@@ -207,6 +207,9 @@ namespace PcapDotNet.Packets.IpV4
}
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new IpV4Layer
......
......@@ -3,8 +3,15 @@ using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets.IpV4
{
/// <summary>
/// Represents IPv4 layer.
/// <seealso cref="IpV4Datagram"/>
/// </summary>
public class IpV4Layer : Layer, IEthernetNextLayer
{
/// <summary>
/// Creates an IPv4 layer with all zero values.
/// </summary>
public IpV4Layer()
{
TypeOfService = 0;
......@@ -18,39 +25,86 @@ namespace PcapDotNet.Packets.IpV4
Options = IpV4Options.None;
}
/// <summary>
/// Type of Service field.
/// </summary>
public byte TypeOfService { get; set; }
/// <summary>
/// The value of the IPv4 ID field.
/// </summary>
public ushort Identification { get; set; }
/// <summary>
/// The fragmentation information field.
/// </summary>
public IpV4Fragmentation Fragmentation { get; set; }
/// <summary>
/// The TTL field.
/// </summary>
public byte Ttl { get; set; }
/// <summary>
/// The IPv4 (next) protocol field.
/// null means that this value should be calculated according to the next layer.
/// </summary>
public IpV4Protocol? Protocol { get; set; }
/// <summary>
/// The header checksum value.
/// null means that this value should be calculated to be correct according to the data.
/// </summary>
public ushort? HeaderChecksum { get; set; }
/// <summary>
/// The source address.
/// </summary>
public IpV4Address Source { get; set; }
/// <summary>
/// The destination address.
/// </summary>
public IpV4Address Destination { get; set; }
/// <summary>
/// The options field with all the parsed options if any exist.
/// </summary>
public IpV4Options Options { get; set; }
/// <summary>
/// The Ethernet Type the Ethernet layer should write when this layer is the Ethernet payload.
/// </summary>
public EthernetType PreviousLayerEtherType
{
get { return EthernetType.IpV4; }
}
/// <summary>
/// The default MAC Address value when this layer is the Ethernet payload.
/// null means there is no default value.
/// </summary>
public MacAddress? PreviousLayerDefaultDestination
{
get { return null; }
}
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return IpV4Datagram.HeaderMinimumLength + Options.BytesLength; }
}
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
IpV4Protocol protocol;
......@@ -73,16 +127,23 @@ namespace PcapDotNet.Packets.IpV4
Options, payloadLength);
}
/// <summary>
/// Finalizes the layer data in the buffer.
/// Used for fields that must be calculated according to the layer's payload (like checksum).
/// </summary>
/// <param name="buffer">The buffer to finalize the layer in.</param>
/// <param name="offset">The offset in the buffer the layer starts.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer)
{
IIpV4NextTransportLayer nextTransportLayer = nextLayer as IIpV4NextTransportLayer;
if (nextTransportLayer == null || !nextTransportLayer.NextLayerCalculateChecksum)
if (nextTransportLayer == null || !nextTransportLayer.CalculateChecksum)
return;
if (nextTransportLayer.CalculateChecksum)
IpV4Datagram.WriteTransportChecksum(buffer, offset, Length, (ushort)payloadLength,
nextTransportLayer.NextLayerChecksumOffset, nextTransportLayer.NextLayerIsChecksumOptional,
nextTransportLayer.Checksum);
IpV4Datagram.WriteTransportChecksum(buffer, offset, Length, (ushort)payloadLength,
nextTransportLayer.ChecksumOffset, nextTransportLayer.IsChecksumOptional,
nextTransportLayer.Checksum);
}
public bool Equals(IpV4Layer other)
......
......@@ -9,13 +9,37 @@ namespace PcapDotNet.Packets
/// </summary>
public abstract class Layer : ILayer
{
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public abstract int Length { get; }
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public abstract void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer);
/// <summary>
/// Finalizes the layer data in the buffer.
/// Used for fields that must be calculated according to the layer's payload (like checksum).
/// </summary>
/// <param name="buffer">The buffer to finalize the layer in.</param>
/// <param name="offset">The offset in the buffer the layer starts.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public virtual void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer)
{
}
/// <summary>
/// The kind of the data link of the layer.
/// Can be null if this is not the first layer in the packet.
/// </summary>
public virtual DataLinkKind? DataLink
{
get { return null; }
......
......@@ -4,6 +4,44 @@ using System.Linq;
namespace PcapDotNet.Packets
{
/// <summary>
/// This class is used to build different packets.
/// Packets are built from layers.
/// This class can be used using static Build methods by giving the Packet's timestamp and layers.
/// This class can be instantiated with different layers and then use the Build method by only giving the Packet's timestamp.
/// If a layer that an instance of this class holds is modified, the PacketBuilder instance will create different packets.
/// <example>This sample shows how to create ICMP Echo Request packets to different servers with different IP ID and ICMP sequence numbers and identifiers.
/// <code>
/// EthernetLayer ethernetLayer = new EthernetLayer
/// {
/// Source = new MacAddress("00:01:02:03:04:05"),
/// Destination = new MacAddress("A0:A1:A2:A3:A4:A5")
/// };
///
/// IpV4Layer ipV4Layer = new IpV4Layer
/// {
/// Source = new IpV4Address("1.2.3.4"),
/// Ttl = 128,
/// };
///
/// IcmpEchoLayer icmpLayer = new IcmpEchoLayer();
///
/// PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
///
/// List&lt;Packet&gt; packets = new List&lt;Packet&gt;();
///
/// for (int i = 0; i != 100; ++i)
/// {
/// ipV4Layer.Destination = new IpV4Address("2.3.4." + i);
/// ipV4Layer.Identification = (ushort)i;
/// icmpLayer.SequenceNumber = (ushort)i;
/// icmpLayer.Identifier = (ushort)i;
///
/// packets.Add(builder.Build(DateTime.Now));
/// }
/// </code>
/// </example>
/// </summary>
public class PacketBuilder
{
public static Packet Build(DateTime timestamp, params ILayer[] layers)
......
using System;
namespace PcapDotNet.Packets
{
/// <summary>
/// Represents a layer that adds a simple payload.
/// Actually can be any buffer of bytes.
/// </summary>
public class PayloadLayer : SimpleLayer
public class PayloadLayer : SimpleLayer, IEquatable<PayloadLayer>
{
public Datagram Data { get; set; }
/// <summary>
/// Creates an empty payload.
/// </summary>
public PayloadLayer()
{
Data = Datagram.Empty;
}
/// <summary>
/// The Payload data.
/// </summary>
public Datagram Data { get; set; }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return Data.Length; }
}
/// <summary>
/// Two payload layers are equal if they have same data.
/// </summary>
public bool Equals(PayloadLayer other)
{
return other != null &&
Data.Equals(other.Data);
}
/// <summary>
/// Two payload layers are equal if they have same data.
/// </summary>
public override sealed bool Equals(Layer other)
{
return base.Equals(other) && Equals(other as PayloadLayer);
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected override void Write(byte[] buffer, int offset)
{
Data.Write(buffer, offset);
......
......@@ -5,11 +5,25 @@ namespace PcapDotNet.Packets
/// </summary>
public abstract class SimpleLayer : Layer
{
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override sealed void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
Write(buffer, offset);
}
/// <summary>
/// Writes the layer to the buffer.
/// This method ignores the payload length, and the previous and next layers.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
protected abstract void Write(byte[] buffer, int offset);
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ using System;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// RFC 793.
/// TCP Header Format
/// <pre>
/// +-----+-------------+----------+----+-----+-----+-----+-----+-----+-----+-----+-----+------------------+
......@@ -154,7 +155,7 @@ namespace PcapDotNet.Packets.Transport
}
/// <summary>
/// Returns the tcp options contained in this TCP Datagram.
/// Returns the TCP options contained in this TCP Datagram.
/// </summary>
public TcpOptions Options
{
......@@ -238,6 +239,9 @@ namespace PcapDotNet.Packets.Transport
get { return (ControlBits & TcpControlBits.Fin) == TcpControlBits.Fin; }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new TcpLayer
......
......@@ -2,45 +2,88 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// RFC 793.
/// Represents the TCP layer.
/// <seealso cref="TcpDatagram"/>
/// </summary>
public class TcpLayer : TransportLayer
{
/// <summary>
/// The sequence number of the first data octet in this segment (except when SYN is present).
/// If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.
/// </summary>
public uint SequenceNumber { get; set; }
/// <summary>
/// If the ACK control bit is set this field contains the value of the next sequence number
/// the sender of the segment is expecting to receive.
/// Once a connection is established this is always sent.
/// </summary>
public uint AcknowledgmentNumber { get; set; }
/// <summary>
/// A collection of bits for the TCP control.
/// </summary>
public TcpControlBits ControlBits { get; set; }
/// <summary>
/// The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept.
/// </summary>
public ushort Window { get; set; }
/// <summary>
/// This field communicates the current value of the urgent pointer as a positive offset from the sequence number in this segment.
/// The urgent pointer points to the sequence number of the octet following the urgent data.
/// This field is only be interpreted in segments with the URG control bit set.
/// </summary>
public ushort UrgentPointer { get; set; }
/// <summary>
/// The TCP options contained in this TCP Datagram.
/// </summary>
public TcpOptions Options { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public override IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.Tcp; }
}
public override int NextLayerChecksumOffset
/// <summary>
/// The offset in the layer where the checksum should be written.
/// </summary>
public override int ChecksumOffset
{
get { return TcpDatagram.Offset.Checksum; }
}
public override bool NextLayerIsChecksumOptional
/// <summary>
/// Whether the checksum is optional in the layer.
/// </summary>
public override bool IsChecksumOptional
{
get { return false; }
}
public override bool NextLayerCalculateChecksum
{
get { return true; }
}
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return TcpDatagram.HeaderMinimumLength + Options.BytesLength; }
}
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
TcpDatagram.WriteHeader(buffer, offset,
......
......@@ -2,23 +2,54 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// Contains the common part of UDP and TCP layers.
/// <seealso cref="TransportDatagram"/>
/// </summary>
public abstract class TransportLayer : Layer, IIpV4NextTransportLayer
{
/// <summary>
/// Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header,
/// the Transport header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.
/// </summary>
public ushort? Checksum { get; set; }
/// <summary>
/// Indicates the port of the sending process.
/// In UDP, this field is optional and may only be assumed to be the port
/// to which a reply should be addressed in the absence of any other information.
/// If not used in UDP, a value of zero is inserted.
/// </summary>
public ushort SourcePort { get; set; }
/// <summary>
/// Destination Port has a meaning within the context of a particular internet destination address.
/// </summary>
public ushort DestinationPort { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public abstract IpV4Protocol PreviousLayerProtocol { get; }
/// <summary>
/// Whether the checksum should be calculated.
/// Can be false in UDP because the checksum is optional. false means that the checksum will be left zero.
/// </summary>
public virtual bool CalculateChecksum
{
get { return true; }
}
public abstract int NextLayerChecksumOffset { get; }
public abstract bool NextLayerIsChecksumOptional { get; }
public abstract bool NextLayerCalculateChecksum { get; }
/// <summary>
/// The offset in the layer where the checksum should be written.
/// </summary>
public abstract int ChecksumOffset { get; }
/// <summary>
/// Whether the checksum is optional in the layer.
/// </summary>
public abstract bool IsChecksumOptional { get; }
public virtual bool Equals(TransportLayer other)
{
......
......@@ -3,6 +3,7 @@ using System;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// RFC 768.
/// This User Datagram Protocol (UDP) is defined to make available a datagram mode of packet-switched computer communication
/// in the environment of an interconnected set of computer networks.
/// This protocol assumes that the Internet Protocol (IP) is used as the underlying protocol.
......@@ -72,6 +73,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return new UdpLayer
......
......@@ -2,40 +2,68 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// RFC 768.
/// Represents the UDP layer.
/// <seealso cref="UdpDatagram"/>
/// </summary>
public class UdpLayer : TransportLayer
{
/// <summary>
/// Whether the checksum should be calculated.
/// Can be false in UDP because the checksum is optional. false means that the checksum will be left zero.
/// </summary>
public override bool CalculateChecksum
{
get{return CalculateChecksumValue;}
}
/// <summary>
/// Whether the checksum should be calculated.
/// Can be false in UDP because the checksum is optional. false means that the checksum will be left zero.
/// </summary>
public bool CalculateChecksumValue { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public override IpV4Protocol PreviousLayerProtocol
{
get { return IpV4Protocol.Udp; }
}
public override int NextLayerChecksumOffset
/// <summary>
/// The offset in the layer where the checksum should be written.
/// </summary>
public override int ChecksumOffset
{
get { return UdpDatagram.Offset.Checksum; }
}
public override bool NextLayerIsChecksumOptional
/// <summary>
/// Whether the checksum is optional in the layer.
/// </summary>
public override bool IsChecksumOptional
{
get { return true; }
}
public override bool NextLayerCalculateChecksum
{
get { return CalculateChecksum; }
}
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return UdpDatagram.HeaderLength; }
}
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
UdpDatagram.WriteHeader(buffer, offset, SourcePort, DestinationPort, payloadLength);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment