Commit 8aeae762 authored by Brickner_cp's avatar Brickner_cp

Code Analysis and Documentation - 69 warnings left.

parent 87c38e83
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets; using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Icmp;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Core.Test namespace PcapDotNet.Core.Test
{ {
...@@ -74,5 +77,39 @@ namespace PcapDotNet.Core.Test ...@@ -74,5 +77,39 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual(expectedPacket, actualPacket); 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 ...@@ -64,22 +64,16 @@ namespace PcapDotNet.Packets.Ethernet
/// Ethernet source address. /// Ethernet source address.
/// </summary> /// </summary>
public MacAddress Source public MacAddress Source
{ {
get get { return ReadMacAddress(Offset.Source, Endianity.Big); }
{
return ReadMacAddress(Offset.Source, Endianity.Big);
}
} }
/// <summary> /// <summary>
/// Ethernet destination address. /// Ethernet destination address.
/// </summary> /// </summary>
public MacAddress Destination public MacAddress Destination
{ {
get get { return ReadMacAddress(Offset.Destination, Endianity.Big); }
{
return ReadMacAddress(Offset.Destination, Endianity.Big);
}
} }
/// <summary> /// <summary>
......
...@@ -3,12 +3,15 @@ using PcapDotNet.Packets.Arp; ...@@ -3,12 +3,15 @@ using PcapDotNet.Packets.Arp;
namespace PcapDotNet.Packets.Ethernet namespace PcapDotNet.Packets.Ethernet
{ {
/// <summary>
/// Represents an Ethernet layer.
/// <seealso cref="EthernetDatagram"/>
/// </summary>
public class EthernetLayer : Layer, IArpPreviousLayer public class EthernetLayer : Layer, IArpPreviousLayer
{ {
public MacAddress Source { get; set; } /// <summary>
public MacAddress Destination { get; set; } /// Creates an instance with zero values.
public EthernetType EtherType { get; set; } /// </summary>
public EthernetLayer() public EthernetLayer()
{ {
Source = MacAddress.Zero; Source = MacAddress.Zero;
...@@ -16,11 +19,37 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -16,11 +19,37 @@ namespace PcapDotNet.Packets.Ethernet
EtherType = EthernetType.None; 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 public override int Length
{ {
get { return EthernetDatagram.HeaderLength; } 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) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
EthernetType etherType = EtherType; EthernetType etherType = EtherType;
...@@ -44,11 +73,18 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -44,11 +73,18 @@ namespace PcapDotNet.Packets.Ethernet
EthernetDatagram.WriteHeader(buffer, 0, Source, destination, etherType); 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 public override DataLinkKind? DataLink
{ {
get { return DataLinkKind.Ethernet; } get { return DataLinkKind.Ethernet; }
} }
/// <summary>
/// The ARP Hardware Type of the layer before the ARP layer.
/// </summary>
public ArpHardwareType PreviousLayerHardwareType public ArpHardwareType PreviousLayerHardwareType
{ {
get { return ArpHardwareType.Ethernet; } get { return ArpHardwareType.Ethernet; }
......
...@@ -14,6 +14,9 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -14,6 +14,9 @@ namespace PcapDotNet.Packets.Ethernet
/// </summary> /// </summary>
public const int SizeOf = UInt48.SizeOf; public const int SizeOf = UInt48.SizeOf;
/// <summary>
/// A MAC Address of all zeros (00:00:00:00:00:00).
/// </summary>
public static MacAddress Zero public static MacAddress Zero
{ {
get { return _zero; } get { return _zero; }
......
...@@ -21,6 +21,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpAddressMaskReplyLayer return new IcmpAddressMaskReplyLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpAddressMaskReplyLayer : IcmpAddressMaskRequestLayer public class IcmpAddressMaskReplyLayer : IcmpAddressMaskRequestLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.AddressMaskReply; } get { return IcmpMessageType.AddressMaskReply; }
......
...@@ -19,7 +19,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -19,7 +19,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpAddressMaskRequestDatagram : IcmpIdentifiedDatagram public class IcmpAddressMaskRequestDatagram : IcmpIdentifiedDatagram
{ {
/// <summary>
/// The number of bytes this Datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength; public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 4; public const int PayloadLength = 4;
private static class Offset private static class Offset
...@@ -40,6 +47,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpAddressMaskRequestLayer return new IcmpAddressMaskRequestLayer
......
...@@ -2,34 +2,57 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,34 +2,57 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// RFC 950.
/// Represents an ICMP Trace Route message layer.
/// <seealso cref="IcmpAddressMaskRequestDatagram"/>
/// </summary>
public class IcmpAddressMaskRequestLayer : IcmpIdentifiedLayer public class IcmpAddressMaskRequestLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// A 32-bit mask.
/// </summary>
public IpV4Address AddressMask { get; set; } public IpV4Address AddressMask { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.AddressMaskRequest; } get { return IcmpMessageType.AddressMaskRequest; }
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength protected override int PayloadLength
{ {
get get { return IcmpAddressMaskRequestDatagram.PayloadLength; }
{
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) protected override void WritePayload(byte[] buffer, int offset)
{ {
IcmpAddressMaskRequestDatagram.WriteHeaderAdditional(buffer, offset, AddressMask); 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) public bool Equals(IcmpAddressMaskRequestLayer other)
{ {
return other != null && return other != null &&
AddressMask == other.AddressMask; 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) public override sealed bool Equals(IcmpLayer other)
{ {
return base.Equals(other) && Equals(other as IcmpAddressMaskRequestLayer); return base.Equals(other) && Equals(other as IcmpAddressMaskRequestLayer);
......
...@@ -24,6 +24,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -24,6 +24,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram 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; public const int OriginalDatagramLengthForUnsupportedTransportProtocol = 256;
private static class Offset private static class Offset
...@@ -39,6 +42,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -39,6 +42,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUInt(Offset.Pointer, Endianity.Big); } 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() public override ILayer ExtractLayer()
{ {
return new IcmpConversionFailedLayer return new IcmpConversionFailedLayer
...@@ -73,11 +79,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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 protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -2,30 +2,43 @@ namespace PcapDotNet.Packets.Icmp ...@@ -2,30 +2,43 @@ namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// RFC 1475. /// RFC 1475.
/// Represents a Conversion Failed ICMP layer.
/// <seealso cref="IcmpConversionFailedDatagram"/>
/// </summary> /// </summary>
public class IcmpConversionFailedLayer : IcmpLayer public class IcmpConversionFailedLayer : IcmpLayer
{ {
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeConversionFailed Code { get; set; } 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; } public uint Pointer { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.ConversionFailed; } get { return IcmpMessageType.ConversionFailed; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get get { return (byte)Code; }
{
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 get { return Pointer; }
{
return Pointer;
}
} }
} }
} }
\ No newline at end of file
...@@ -43,11 +43,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -43,11 +43,17 @@ namespace PcapDotNet.Packets.Icmp
get { return (IcmpMessageType)this[Offset.Type]; } get { return (IcmpMessageType)this[Offset.Type]; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public byte Code public byte Code
{ {
get { return this[Offset.Code]; } get { return this[Offset.Code]; }
} }
/// <summary>
/// A combination of the ICMP Message Type and Code.
/// </summary>
public IcmpMessageTypeAndCode MessageTypeAndCode public IcmpMessageTypeAndCode MessageTypeAndCode
{ {
get { return (IcmpMessageTypeAndCode)ReadUShort(Offset.Type, Endianity.Big); } get { return (IcmpMessageTypeAndCode)ReadUShort(Offset.Type, Endianity.Big); }
...@@ -63,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -63,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Checksum, Endianity.Big); } get { return ReadUShort(Offset.Checksum, Endianity.Big); }
} }
/// <summary>
/// A value that should be interpreted according to the specific message.
/// </summary>
public uint Variable public uint Variable
{ {
get { return ReadUInt(Offset.Variable, Endianity.Big); } get { return ReadUInt(Offset.Variable, Endianity.Big); }
...@@ -81,6 +90,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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 override abstract ILayer ExtractLayer();
public Datagram Payload public Datagram Payload
...@@ -114,16 +126,25 @@ namespace PcapDotNet.Packets.Icmp ...@@ -114,16 +126,25 @@ namespace PcapDotNet.Packets.Icmp
buffer.Write(offset + Offset.Checksum, checksumValue, Endianity.Big); 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() protected override bool CalculateIsValid()
{ {
return Length >= HeaderLength && IsChecksumCorrect && Code >= MinCodeValue && Code <= MaxCodeValue; 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 protected virtual byte MinCodeValue
{ {
get { return 0; } get { return 0; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected virtual byte MaxCodeValue protected virtual byte MaxCodeValue
{ {
get { return 0; } get { return 0; }
......
...@@ -26,16 +26,24 @@ namespace PcapDotNet.Packets.Icmp ...@@ -26,16 +26,24 @@ namespace PcapDotNet.Packets.Icmp
public const int NextHopMtu = 6; 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) : 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 public ushort NextHopMaximumTransmissionUnit
{ {
get { return ReadUShort(Offset.NextHopMtu, Endianity.Big); } 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() public override ILayer ExtractLayer()
{ {
return new IcmpDestinationUnreachableLayer return new IcmpDestinationUnreachableLayer
...@@ -53,11 +61,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -53,11 +61,17 @@ namespace PcapDotNet.Packets.Icmp
NextHopMaximumTransmissionUnit == 0); NextHopMaximumTransmissionUnit == 0);
} }
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -2,35 +2,42 @@ namespace PcapDotNet.Packets.Icmp ...@@ -2,35 +2,42 @@ namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// RFC 792 and RFC 1191. /// RFC 792 and RFC 1191.
/// <seealso cref="IcmpDestinationUnreachableDatagram"/>
/// </summary> /// </summary>
public class IcmpDestinationUnreachableLayer : IcmpLayer public class IcmpDestinationUnreachableLayer : IcmpLayer
{ {
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeDestinationUnreachable Code { get; set; } public IcmpCodeDestinationUnreachable Code { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.DestinationUnreachable; } get { return IcmpMessageType.DestinationUnreachable; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get { return (byte)Code; } 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 ushort NextHopMaximumTransmissionUnit { get; set; }
public bool Equals(IcmpDestinationUnreachableLayer other) /// <summary>
{ /// A value that should be interpreted according to the specific message.
return other != null && /// </summary>
NextHopMaximumTransmissionUnit == other.NextHopMaximumTransmissionUnit; protected override uint Variable
}
public override sealed bool Equals(IcmpLayer other)
{
return base.Equals(other) && Equals(other as IcmpDestinationUnreachableLayer);
}
protected override uint Value
{ {
get { return NextHopMaximumTransmissionUnit; } get { return NextHopMaximumTransmissionUnit; }
} }
......
...@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpDomainNameRequestLayer return new IcmpDomainNameRequestLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpDomainNameRequestLayer : IcmpIdentifiedLayer public class IcmpDomainNameRequestLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.DomainNameRequest; } get { return IcmpMessageType.DomainNameRequest; }
......
...@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpEchoDatagram : IcmpIdentifiedDatagram public class IcmpEchoDatagram : IcmpIdentifiedDatagram
{ {
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpEchoLayer return new IcmpEchoLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpEchoLayer : IcmpIdentifiedLayer public class IcmpEchoLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.Echo; } get { return IcmpMessageType.Echo; }
......
...@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -17,6 +17,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpEchoReplyDatagram : IcmpIdentifiedDatagram public class IcmpEchoReplyDatagram : IcmpIdentifiedDatagram
{ {
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpEchoReplyLayer return new IcmpEchoReplyLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpEchoReplyLayer : IcmpIdentifiedLayer public class IcmpEchoReplyLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.EchoReply; } get { return IcmpMessageType.EchoReply; }
......
...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -21,7 +21,7 @@ namespace PcapDotNet.Packets.Icmp
} }
/// <summary> /// <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> /// </summary>
public ushort Identifier public ushort Identifier
{ {
...@@ -29,7 +29,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -29,7 +29,7 @@ namespace PcapDotNet.Packets.Icmp
} }
/// <summary> /// <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> /// </summary>
public ushort SequenceNumber public ushort SequenceNumber
{ {
......
...@@ -5,16 +5,22 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,16 +5,22 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public abstract class IcmpIdentifiedLayer : IcmpLayer public abstract class IcmpIdentifiedLayer : IcmpLayer
{ {
/// <summary>
/// An identifier to aid in matching requests and replies, may be zero.
/// </summary>
public ushort Identifier { get; set; } 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; } 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 get { return (uint)((Identifier << 16) | SequenceNumber); }
{
return (uint)((Identifier << 16) | SequenceNumber);
}
} }
} }
} }
\ No newline at end of file
...@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpInformationReplyLayer return new IcmpInformationReplyLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpInformationReplyLayer : IcmpIdentifiedLayer public class IcmpInformationReplyLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.InformationReply; } get { return IcmpMessageType.InformationReply; }
......
...@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpInformationRequestLayer return new IcmpInformationRequestLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpInformationRequestLayer : IcmpIdentifiedLayer public class IcmpInformationRequestLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.InformationRequest; } get { return IcmpMessageType.InformationRequest; }
......
...@@ -20,6 +20,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -20,6 +20,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram
{ {
/// <summary>
/// The number of bytes this payload includes from the original data datagram.
/// </summary>
public const int OriginalDatagramPayloadLength = 8; public const int OriginalDatagramPayloadLength = 8;
internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length) internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length)
...@@ -27,6 +30,10 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() protected override bool CalculateIsValid()
{ {
if (!base.CalculateIsValid()) if (!base.CalculateIsValid())
......
...@@ -22,6 +22,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -22,6 +22,9 @@ namespace PcapDotNet.Packets.Icmp
{ {
} }
/// <summary>
/// The ICMP payload as an IPv4 datagram.
/// </summary>
public IpV4Datagram IpV4 public IpV4Datagram IpV4
{ {
get get
...@@ -32,6 +35,10 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() protected override bool CalculateIsValid()
{ {
if (!base.CalculateIsValid()) if (!base.CalculateIsValid())
......
...@@ -3,43 +3,84 @@ using PcapDotNet.Packets.IpV4; ...@@ -3,43 +3,84 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// Represents an ICMP layer.
/// <seealso cref="IcmpDatagram"/>
/// </summary>
public abstract class IcmpLayer : SimpleLayer, IIpV4NextLayer 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; } public abstract IcmpMessageType MessageType { get; }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public virtual byte CodeValue public virtual byte CodeValue
{ {
get { return 0; } get { return 0; }
} }
public IcmpMessageTypeAndCode MessageTypeAndCode
/// <summary>
/// A combination of the ICMP Message Type and Code.
/// </summary>
public IcmpMessageTypeAndCode MessageTypeAndCode
{ {
get get { return (IcmpMessageTypeAndCode)(((ushort)MessageType << 8) | CodeValue); }
{
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; } 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; } get { return 0; }
} }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override sealed int Length public override sealed int Length
{ {
get { return IcmpDatagram.HeaderLength + PayloadLength; } get { return IcmpDatagram.HeaderLength + PayloadLength; }
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected virtual int PayloadLength protected virtual int PayloadLength
{ {
get { return 0; } 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) 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); 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) protected virtual void WritePayload(byte[] buffer, int offset)
{ {
} }
...@@ -49,6 +90,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -49,6 +90,9 @@ namespace PcapDotNet.Packets.Icmp
IcmpDatagram.WriteChecksum(buffer, offset, Length + payloadLength, Checksum); IcmpDatagram.WriteChecksum(buffer, offset, Length + payloadLength, Checksum);
} }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public IpV4Protocol PreviousLayerProtocol public IpV4Protocol PreviousLayerProtocol
{ {
get { return IpV4Protocol.InternetControlMessageProtocol; } get { return IpV4Protocol.InternetControlMessageProtocol; }
...@@ -59,7 +103,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -59,7 +103,7 @@ namespace PcapDotNet.Packets.Icmp
return other != null && return other != null &&
MessageType == other.MessageType && CodeValue == other.CodeValue && MessageType == other.MessageType && CodeValue == other.CodeValue &&
Checksum == other.Checksum && Checksum == other.Checksum &&
Value == other.Value; Variable == other.Variable;
} }
public sealed override bool Equals(Layer other) public sealed override bool Equals(Layer other)
...@@ -70,12 +114,12 @@ namespace PcapDotNet.Packets.Icmp ...@@ -70,12 +114,12 @@ namespace PcapDotNet.Packets.Icmp
public override int GetHashCode() public override int GetHashCode()
{ {
return base.GetHashCode() ^ return base.GetHashCode() ^
MessageTypeAndCode.GetHashCode() ^ Checksum.GetHashCode() ^ Value.GetHashCode(); MessageTypeAndCode.GetHashCode() ^ Checksum.GetHashCode() ^ Variable.GetHashCode();
} }
public override string ToString() 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 ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpParameterProblemLayer return new IcmpParameterProblemLayer
......
...@@ -5,19 +5,26 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,19 +5,26 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpParameterProblemLayer : IcmpLayer 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; } public byte Pointer { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.ParameterProblem; } 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 get { return (uint)(Pointer << 24); }
{
return (uint)(Pointer << 24);
}
} }
} }
} }
\ No newline at end of file
...@@ -51,11 +51,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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 protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -2,29 +2,45 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,29 +2,45 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// RFC 792.
/// Represents an ICMP Redirect message layer.
/// <seealso cref="IcmpRedirectDatagram"/>
/// </summary>
public class IcmpRedirectLayer : IcmpLayer public class IcmpRedirectLayer : IcmpLayer
{ {
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeRedirect Code { get; set; } 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 public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.Redirect; } get { return IcmpMessageType.Redirect; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get get { return (byte)Code; }
{
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 get { return GatewayInternetAddress.ToValue(); }
{
return GatewayInternetAddress.ToValue();
}
} }
} }
} }
\ No newline at end of file
...@@ -31,6 +31,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -31,6 +31,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpRouterAdvertisementDatagram : IcmpDatagram public class IcmpRouterAdvertisementDatagram : IcmpDatagram
{ {
/// <summary>
/// The default number of 32-bit words of information per each router address.
/// </summary>
public const int DefaultAddressEntrySize = 2; public const int DefaultAddressEntrySize = 2;
private static class Offset private static class Offset
...@@ -99,6 +102,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpRouterAdvertisementLayer(Entries.ToList()) return new IcmpRouterAdvertisementLayer(Entries.ToList())
......
using System;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp 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) public IcmpRouterAdvertisementEntry(IpV4Address routerAddress, int routerAddressPreference)
{ {
_routerAddress = routerAddress; _routerAddress = routerAddress;
_routerAddressPreference = routerAddressPreference; _routerAddressPreference = routerAddressPreference;
} }
/// <summary>
/// The sending router's IP address(es) on the interface from which this message is sent.
/// </summary>
public IpV4Address RouterAddress public IpV4Address RouterAddress
{ {
get { return _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 public int RouterAddressPreference
{ {
get {return _routerAddressPreference; } get {return _routerAddressPreference; }
} }
/// <summary>
/// Two entries are equal if they have the same router address and preference.
/// </summary>
public bool Equals(IcmpRouterAdvertisementEntry other) public bool Equals(IcmpRouterAdvertisementEntry other)
{ {
return other != null && return other != null &&
...@@ -27,6 +46,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -27,6 +46,9 @@ namespace PcapDotNet.Packets.Icmp
RouterAddressPreference == other.RouterAddressPreference; RouterAddressPreference == other.RouterAddressPreference;
} }
/// <summary>
/// Two entries are equal if they have the same router address and preference.
/// </summary>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as IcmpRouterAdvertisementEntry); return Equals(obj as IcmpRouterAdvertisementEntry);
......
...@@ -5,22 +5,50 @@ using System.Linq; ...@@ -5,22 +5,50 @@ using System.Linq;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// RFC 1256.
/// An ICMP Router Advertisement layer.
/// <seealso cref="IcmpRouterAdvertisementDatagram"/>
/// </summary>
public class IcmpRouterAdvertisementLayer : IcmpLayer 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) public IcmpRouterAdvertisementLayer(IList<IcmpRouterAdvertisementEntry> entries)
{ {
_entries = entries; _entries = entries;
} }
/// <summary>
/// The maximum time that the router addresses may be considered valid.
/// </summary>
public TimeSpan Lifetime { get; set; } 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 public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.RouterAdvertisement; } 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 get
{ {
...@@ -30,14 +58,20 @@ namespace PcapDotNet.Packets.Icmp ...@@ -30,14 +58,20 @@ namespace PcapDotNet.Packets.Icmp
} }
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength protected override int PayloadLength
{ {
get get { return IcmpRouterAdvertisementDatagram.GetPayloadLength(Entries.Count); }
{
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) protected override void WritePayload(byte[] buffer, int offset)
{ {
IcmpRouterAdvertisementDatagram.WriteHeaderAdditional(buffer, offset, Entries); IcmpRouterAdvertisementDatagram.WriteHeaderAdditional(buffer, offset, Entries);
......
...@@ -19,6 +19,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpRouterSolicitationLayer(); return new IcmpRouterSolicitationLayer();
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpRouterSolicitationLayer : IcmpLayer public class IcmpRouterSolicitationLayer : IcmpLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.RouterSolicitation; } get { return IcmpMessageType.RouterSolicitation; }
......
...@@ -41,6 +41,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -41,6 +41,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Pointer, Endianity.Big); } 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() public override ILayer ExtractLayer()
{ {
return new IcmpSecurityFailuresLayer return new IcmpSecurityFailuresLayer
...@@ -56,11 +59,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -56,11 +59,17 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Pointer < IpV4.Length; return base.CalculateIsValid() && Pointer < IpV4.Length;
} }
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -2,30 +2,44 @@ namespace PcapDotNet.Packets.Icmp ...@@ -2,30 +2,44 @@ namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// RFC 2521. /// RFC 2521.
/// Represents an ICMP Security Failures layer.
/// <seealso cref="IcmpSecurityFailuresDatagram"/>
/// </summary> /// </summary>
public class IcmpSecurityFailuresLayer : IcmpLayer public class IcmpSecurityFailuresLayer : IcmpLayer
{ {
public IcmpCodeSecurityFailure Code{get; set ;} /// <summary>
public ushort Pointer{get; set ;} /// 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 public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.SecurityFailures; } get { return IcmpMessageType.SecurityFailures; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get get { return (byte)Code; }
{
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 get { return Pointer; }
{
return Pointer;
}
} }
} }
} }
\ No newline at end of file
...@@ -20,11 +20,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -20,11 +20,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram public class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
public IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length) internal IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpSourceQuenchLayer return new IcmpSourceQuenchLayer
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpSourceQuenchLayer : IcmpLayer public class IcmpSourceQuenchLayer : IcmpLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.SourceQuench; } get { return IcmpMessageType.SourceQuench; }
......
...@@ -21,11 +21,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -21,11 +21,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram public class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
public IcmpTimeExceededDatagram(byte[] buffer, int offset, int length) internal IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
} }
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpTimeExceededLayer return new IcmpTimeExceededLayer
...@@ -35,11 +38,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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 protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -5,13 +5,22 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,13 +5,22 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTimeExceededLayer : IcmpLayer public class IcmpTimeExceededLayer : IcmpLayer
{ {
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeTimeExceeded Code { get; set; } public IcmpCodeTimeExceeded Code { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.TimeExceeded; } get { return IcmpMessageType.TimeExceeded; }
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get { return (byte)Code; } get { return (byte)Code; }
......
...@@ -23,7 +23,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -23,7 +23,14 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{ {
/// <summary>
/// The number of bytes this datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength; public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 12; public const int PayloadLength = 12;
private static class Offset private static class Offset
...@@ -62,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -62,6 +69,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadIpV4TimeOfDay(Offset.TransmitTimestamp, Endianity.Big); } 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() public override ILayer ExtractLayer()
{ {
return new IcmpTimestampLayer return new IcmpTimestampLayer
......
...@@ -2,24 +2,50 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,24 +2,50 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// RFC 792.
/// Represents an ICMP Timestamp layer.
/// <seealso cref="IcmpTimestampDatagram"/>
/// </summary>
public class IcmpTimestampLayer : IcmpIdentifiedLayer public class IcmpTimestampLayer : IcmpIdentifiedLayer
{ {
/// <summary>
/// The time the sender last touched the message before sending it.
/// </summary>
public IpV4TimeOfDay OriginateTimestamp { get; set; } public IpV4TimeOfDay OriginateTimestamp { get; set; }
/// <summary>
/// The time the echoer first touched it on receipt.
/// </summary>
public IpV4TimeOfDay ReceiveTimestamp { get; set; } public IpV4TimeOfDay ReceiveTimestamp { get; set; }
/// <summary>
/// The time the echoer last touched the message on sending it.
/// </summary>
public IpV4TimeOfDay TransmitTimestamp { get; set; } public IpV4TimeOfDay TransmitTimestamp { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.Timestamp; } get { return IcmpMessageType.Timestamp; }
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength protected override int PayloadLength
{ {
get get { return IcmpTimestampDatagram.PayloadLength; }
{
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) protected override void WritePayload(byte[] buffer, int offset)
{ {
IcmpTimestampDatagram.WriteHeaderAdditional(buffer, offset, IcmpTimestampDatagram.WriteHeaderAdditional(buffer, offset,
......
...@@ -25,6 +25,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpTimestampReplyLayer return new IcmpTimestampReplyLayer
......
...@@ -5,12 +5,12 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,12 +5,12 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTimestampReplyLayer : IcmpTimestampLayer public class IcmpTimestampReplyLayer : IcmpTimestampLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get get { return IcmpMessageType.TimestampReply; }
{
return IcmpMessageType.TimestampReply;
}
} }
} }
} }
\ No newline at end of file
...@@ -24,8 +24,19 @@ namespace PcapDotNet.Packets.Icmp ...@@ -24,8 +24,19 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTraceRouteDatagram : IcmpDatagram public class IcmpTraceRouteDatagram : IcmpDatagram
{ {
/// <summary>
/// The number of bytes this datagram should take.
/// </summary>
public const int DatagramLength = HeaderLength + PayloadLength; public const int DatagramLength = HeaderLength + PayloadLength;
/// <summary>
/// The number of bytes this ICMP payload should take.
/// </summary>
public const int PayloadLength = 12; 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; public const ushort OutboundReturnHopCountValue = 0xFFFF;
private static class Offset private static class Offset
...@@ -92,6 +103,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -92,6 +103,9 @@ namespace PcapDotNet.Packets.Icmp
get { return ReturnHopCount == OutboundReturnHopCountValue; } get { return ReturnHopCount == OutboundReturnHopCountValue; }
} }
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpTraceRouteLayer return new IcmpTraceRouteLayer
...@@ -111,11 +125,17 @@ namespace PcapDotNet.Packets.Icmp ...@@ -111,11 +125,17 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Length == DatagramLength; return base.CalculateIsValid() && Length == DatagramLength;
} }
/// <summary>
/// The minimum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MinCodeValue protected override byte MinCodeValue
{ {
get { return _minCode; } get { return _minCode; }
} }
/// <summary>
/// The maximum valid ICMP code for this type of ICMP datagram.
/// </summary>
protected override byte MaxCodeValue protected override byte MaxCodeValue
{ {
get { return _maxCode; } get { return _maxCode; }
......
...@@ -2,49 +2,86 @@ using System; ...@@ -2,49 +2,86 @@ using System;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary>
/// RFC 1393.
/// Represents an ICMP Trace Route message layer.
/// <seealso cref="IcmpTraceRouteDatagram"/>
/// </summary>
public class IcmpTraceRouteLayer : IcmpLayer public class IcmpTraceRouteLayer : IcmpLayer
{ {
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public IcmpCodeTraceRoute Code { get; set; } public IcmpCodeTraceRoute Code { get; set; }
public ushort Identification{get;set;} /// <summary>
/// The ID Number as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
public ushort OutboundHopCount{get;set;} /// 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;} /// <summary>
/// The Return Hop Count as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
public uint OutputLinkMaximumTransmissionUnit{get;set;} /// </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 public override IcmpMessageType MessageType
{ {
get { return IcmpMessageType.TraceRoute; } get { return IcmpMessageType.TraceRoute; }
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength protected override int PayloadLength
{ {
get get { return IcmpTraceRouteDatagram.PayloadLength; }
{
return IcmpTraceRouteDatagram.PayloadLength;
}
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get get { return (byte)Code; }
{
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 get { return (uint)(Identification << 16); }
{
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) protected override void WritePayload(byte[] buffer, int offset)
{ {
IcmpTraceRouteDatagram.WriteHeaderAdditional(buffer, offset, OutboundHopCount, ReturnHopCount, OutputLinkSpeed, OutputLinkMaximumTransmissionUnit); IcmpTraceRouteDatagram.WriteHeaderAdditional(buffer, offset, OutboundHopCount, ReturnHopCount, OutputLinkSpeed, OutputLinkMaximumTransmissionUnit);
......
...@@ -5,11 +5,20 @@ namespace PcapDotNet.Packets.Icmp ...@@ -5,11 +5,20 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpUnknownDatagram : IcmpDatagram 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) : base(buffer, offset, length)
{ {
} }
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new IcmpUnknownLayer return new IcmpUnknownLayer
...@@ -17,11 +26,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -17,11 +26,14 @@ namespace PcapDotNet.Packets.Icmp
LayerMessageType = (byte)MessageType, LayerMessageType = (byte)MessageType,
LayerCode = Code, LayerCode = Code,
Checksum = Checksum, Checksum = Checksum,
LayerValue = Variable, LayerVariable = Variable,
Payload = Payload Payload = Payload
}; };
} }
/// <summary>
/// Unknown ICMP datagrams are always invalid.
/// </summary>
protected override bool CalculateIsValid() protected override bool CalculateIsValid()
{ {
return false; return false;
......
...@@ -2,43 +2,69 @@ namespace PcapDotNet.Packets.Icmp ...@@ -2,43 +2,69 @@ namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
/// Represents an ICMP layer with an unknown message type. /// Represents an ICMP layer with an unknown message type.
/// <seealso cref="IcmpUnknownDatagram"/>
/// </summary> /// </summary>
public class IcmpUnknownLayer : IcmpLayer public class IcmpUnknownLayer : IcmpLayer
{ {
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public byte LayerMessageType { get; set; } 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 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; } public Datagram Payload { get; set; }
/// <summary>
/// The value of this field determines the format of the remaining data.
/// </summary>
public override IcmpMessageType MessageType public override IcmpMessageType MessageType
{ {
get get { return (IcmpMessageType)LayerMessageType; }
{
return (IcmpMessageType)LayerMessageType;
}
} }
/// <summary>
/// A sub-type of the message. Specific method of this message type.
/// </summary>
public override byte CodeValue public override byte CodeValue
{ {
get get { return LayerCode; }
{
return LayerCode;
}
} }
/// <summary>
/// The number of bytes the ICMP payload takes.
/// </summary>
protected override int PayloadLength protected override int PayloadLength
{ {
get get { return Payload.Length; }
{
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) protected override void WritePayload(byte[] buffer, int offset)
{ {
Payload.Write(buffer, offset); Payload.Write(buffer, offset);
......
...@@ -2,8 +2,18 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,8 +2,18 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// Represents an IGMP layer that contains a Group Address.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public interface IIgmpLayerWithGroupAddress 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; } IpV4Address GroupAddress { get; set; }
} }
} }
\ No newline at end of file
...@@ -484,6 +484,9 @@ namespace PcapDotNet.Packets.Igmp ...@@ -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() public override ILayer ExtractLayer()
{ {
switch (MessageType) switch (MessageType)
......
...@@ -4,15 +4,34 @@ using PcapDotNet.Packets.IpV4; ...@@ -4,15 +4,34 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// The base of all IGMP layers.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpLayer : SimpleLayer, IIpV4NextLayer 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; } 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 public virtual IgmpQueryVersion QueryVersion
{ {
get { return IgmpQueryVersion.None; } get { return IgmpQueryVersion.None; }
} }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public abstract TimeSpan MaxResponseTimeValue { get; } public abstract TimeSpan MaxResponseTimeValue { get; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public IpV4Protocol PreviousLayerProtocol public IpV4Protocol PreviousLayerProtocol
{ {
get { return IpV4Protocol.InternetGroupManagementProtocol; } get { return IpV4Protocol.InternetGroupManagementProtocol; }
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary> /// </summary>
public class IgmpLeaveGroupVersion2Layer : IgmpVersion2Layer public class IgmpLeaveGroupVersion2Layer : IgmpVersion2Layer
{ {
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.LeaveGroupVersion2; } get { return IgmpMessageType.LeaveGroupVersion2; }
......
...@@ -5,11 +5,18 @@ namespace PcapDotNet.Packets.Igmp ...@@ -5,11 +5,18 @@ namespace PcapDotNet.Packets.Igmp
/// </summary> /// </summary>
public class IgmpQueryVersion1Layer : IgmpVersion1Layer public class IgmpQueryVersion1Layer : IgmpVersion1Layer
{ {
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipQuery; } 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 public override IgmpQueryVersion QueryVersion
{ {
get get
......
...@@ -5,17 +5,21 @@ namespace PcapDotNet.Packets.Igmp ...@@ -5,17 +5,21 @@ namespace PcapDotNet.Packets.Igmp
/// </summary> /// </summary>
public class IgmpQueryVersion2Layer : IgmpVersion2Layer public class IgmpQueryVersion2Layer : IgmpVersion2Layer
{ {
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipQuery; } 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 public override IgmpQueryVersion QueryVersion
{ {
get get { return IgmpQueryVersion.Version2; }
{
return IgmpQueryVersion.Version2;
}
} }
} }
} }
\ No newline at end of file
...@@ -7,33 +7,82 @@ using PcapDotNet.Packets.IpV4; ...@@ -7,33 +7,82 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// RFC 3376.
/// Represents an IGMP Query version 3 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public class IgmpQueryVersion3Layer : IgmpLayer, IIgmpLayerWithGroupAddress public class IgmpQueryVersion3Layer : IgmpLayer, IIgmpLayerWithGroupAddress
{ {
/// <summary>
/// A query on 0 source addresses.
/// </summary>
public IgmpQueryVersion3Layer() public IgmpQueryVersion3Layer()
:this(new List<IpV4Address>()) :this(new List<IpV4Address>())
{ {
} }
/// <summary>
/// A query on the given source addresses.
/// </summary>
public IgmpQueryVersion3Layer(IList<IpV4Address> sourceAddresses) public IgmpQueryVersion3Layer(IList<IpV4Address> sourceAddresses)
{ {
_sourceAddresses = sourceAddresses; _sourceAddresses = sourceAddresses;
} }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public TimeSpan MaxResponseTime { get; set; } 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 public override int Length
{ {
get { return IgmpDatagram.GetQueryVersion3Length(SourceAddresses.Count); } 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) protected override void Write(byte[] buffer, int offset)
{ {
IgmpDatagram.WriteQueryVersion3(buffer, offset, IgmpDatagram.WriteQueryVersion3(buffer, offset,
...@@ -41,19 +90,26 @@ namespace PcapDotNet.Packets.Igmp ...@@ -41,19 +90,26 @@ namespace PcapDotNet.Packets.Igmp
QueryInterval, SourceAddresses); QueryInterval, SourceAddresses);
} }
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipQuery; } 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 public override IgmpQueryVersion QueryVersion
{ {
get get { return IgmpQueryVersion.Version3; }
{
return IgmpQueryVersion.Version3;
}
} }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue public override TimeSpan MaxResponseTimeValue
{ {
get { return MaxResponseTime; } get { return MaxResponseTime; }
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary> /// </summary>
public class IgmpReportVersion1Layer : IgmpVersion1Layer public class IgmpReportVersion1Layer : IgmpVersion1Layer
{ {
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipReportVersion1; } get { return IgmpMessageType.MembershipReportVersion1; }
......
...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp ...@@ -5,6 +5,9 @@ namespace PcapDotNet.Packets.Igmp
/// </summary> /// </summary>
public class IgmpReportVersion2Layer : IgmpVersion2Layer public class IgmpReportVersion2Layer : IgmpVersion2Layer
{ {
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipReportVersion2; } get { return IgmpMessageType.MembershipReportVersion2; }
......
...@@ -6,38 +6,70 @@ using PcapDotNet.Base; ...@@ -6,38 +6,70 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// RFC 3376.
/// Represents an IGMP Report version 3 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public class IgmpReportVersion3Layer : IgmpLayer public class IgmpReportVersion3Layer : IgmpLayer
{ {
/// <summary>
/// Creates an instance with no group records.
/// </summary>
public IgmpReportVersion3Layer() public IgmpReportVersion3Layer()
:this(new List<IgmpGroupRecord>()) :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) public IgmpReportVersion3Layer(IList<IgmpGroupRecord> groupRecords)
{ {
_groupRecords = 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 public IList<IgmpGroupRecord> GroupRecords
{ {
get { return _groupRecords; } get { return _groupRecords; }
} }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length public override int Length
{ {
get { return IgmpDatagram.GetReportVersion3Length(GroupRecords); } 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) protected override void Write(byte[] buffer, int offset)
{ {
IgmpDatagram.WriteReportVersion3(buffer, offset, GroupRecords); IgmpDatagram.WriteReportVersion3(buffer, offset, GroupRecords);
} }
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType public override IgmpMessageType MessageType
{ {
get { return IgmpMessageType.MembershipReportVersion3; } get { return IgmpMessageType.MembershipReportVersion3; }
} }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue public override TimeSpan MaxResponseTimeValue
{ {
get { return TimeSpan.Zero; } get { return TimeSpan.Zero; }
......
...@@ -2,14 +2,35 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,14 +2,35 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp 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 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; } public IpV4Address GroupAddress { get; set; }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length public override int Length
{ {
get { return IgmpDatagram.HeaderLength; } 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) protected override void Write(byte[] buffer, int offset)
{ {
IgmpDatagram.WriteHeader(buffer, offset, IgmpDatagram.WriteHeader(buffer, offset,
......
...@@ -2,8 +2,16 @@ using System; ...@@ -2,8 +2,16 @@ using System;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// RFC 1112.
/// Represents an IGMP version 1 layer.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpVersion1Layer : IgmpSimpleLayer public abstract class IgmpVersion1Layer : IgmpSimpleLayer
{ {
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue public override TimeSpan MaxResponseTimeValue
{ {
get { return TimeSpan.Zero; } get { return TimeSpan.Zero; }
......
...@@ -2,9 +2,21 @@ using System; ...@@ -2,9 +2,21 @@ using System;
namespace PcapDotNet.Packets.Igmp namespace PcapDotNet.Packets.Igmp
{ {
/// <summary>
/// RFC 2236.
/// Represents a generic IGMP version 2 datagram.
/// <seealso cref="IgmpDatagram"/>
/// </summary>
public abstract class IgmpVersion2Layer : IgmpSimpleLayer public abstract class IgmpVersion2Layer : IgmpSimpleLayer
{ {
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public TimeSpan MaxResponseTime { get; set; } public TimeSpan MaxResponseTime { get; set; }
/// <summary>
/// The actual time allowed, called the Max Resp Time.
/// </summary>
public override TimeSpan MaxResponseTimeValue public override TimeSpan MaxResponseTimeValue
{ {
get { return MaxResponseTime; } get { return MaxResponseTime; }
......
...@@ -6,6 +6,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -6,6 +6,9 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public interface IIpV4NextLayer : ILayer public interface IIpV4NextLayer : ILayer
{ {
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
IpV4Protocol PreviousLayerProtocol { get; } IpV4Protocol PreviousLayerProtocol { get; }
} }
} }
\ No newline at end of file
...@@ -6,10 +6,27 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -6,10 +6,27 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public interface IIpV4NextTransportLayer : IIpV4NextLayer 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; } 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; } bool CalculateChecksum { get; }
int NextLayerChecksumOffset { get; }
bool NextLayerIsChecksumOptional { get; } /// <summary>
bool NextLayerCalculateChecksum { get; } /// 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 ...@@ -138,7 +138,7 @@ namespace PcapDotNet.Packets.IpV4
} }
/// <summary> /// <summary>
/// The header check sum value. /// The header checksum value.
/// </summary> /// </summary>
public ushort HeaderChecksum public ushort HeaderChecksum
{ {
...@@ -207,6 +207,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IpV4Layer return new IpV4Layer
......
...@@ -3,8 +3,15 @@ using PcapDotNet.Packets.Ethernet; ...@@ -3,8 +3,15 @@ using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
/// <summary>
/// Represents IPv4 layer.
/// <seealso cref="IpV4Datagram"/>
/// </summary>
public class IpV4Layer : Layer, IEthernetNextLayer public class IpV4Layer : Layer, IEthernetNextLayer
{ {
/// <summary>
/// Creates an IPv4 layer with all zero values.
/// </summary>
public IpV4Layer() public IpV4Layer()
{ {
TypeOfService = 0; TypeOfService = 0;
...@@ -18,39 +25,86 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -18,39 +25,86 @@ namespace PcapDotNet.Packets.IpV4
Options = IpV4Options.None; Options = IpV4Options.None;
} }
/// <summary>
/// Type of Service field.
/// </summary>
public byte TypeOfService { get; set; } public byte TypeOfService { get; set; }
/// <summary>
/// The value of the IPv4 ID field.
/// </summary>
public ushort Identification { get; set; } public ushort Identification { get; set; }
/// <summary>
/// The fragmentation information field.
/// </summary>
public IpV4Fragmentation Fragmentation { get; set; } public IpV4Fragmentation Fragmentation { get; set; }
/// <summary>
/// The TTL field.
/// </summary>
public byte Ttl { get; set; } 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; } 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; } public ushort? HeaderChecksum { get; set; }
/// <summary>
/// The source address.
/// </summary>
public IpV4Address Source { get; set; } public IpV4Address Source { get; set; }
/// <summary>
/// The destination address.
/// </summary>
public IpV4Address Destination { get; set; } public IpV4Address Destination { get; set; }
/// <summary>
/// The options field with all the parsed options if any exist.
/// </summary>
public IpV4Options Options { get; set; } 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 public EthernetType PreviousLayerEtherType
{ {
get { return EthernetType.IpV4; } 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 public MacAddress? PreviousLayerDefaultDestination
{ {
get { return null; } get { return null; }
} }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length public override int Length
{ {
get { return IpV4Datagram.HeaderMinimumLength + Options.BytesLength; } 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) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
IpV4Protocol protocol; IpV4Protocol protocol;
...@@ -73,16 +127,23 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -73,16 +127,23 @@ namespace PcapDotNet.Packets.IpV4
Options, payloadLength); 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) public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer)
{ {
IIpV4NextTransportLayer nextTransportLayer = nextLayer as IIpV4NextTransportLayer; IIpV4NextTransportLayer nextTransportLayer = nextLayer as IIpV4NextTransportLayer;
if (nextTransportLayer == null || !nextTransportLayer.NextLayerCalculateChecksum) if (nextTransportLayer == null || !nextTransportLayer.CalculateChecksum)
return; return;
if (nextTransportLayer.CalculateChecksum) IpV4Datagram.WriteTransportChecksum(buffer, offset, Length, (ushort)payloadLength,
IpV4Datagram.WriteTransportChecksum(buffer, offset, Length, (ushort)payloadLength, nextTransportLayer.ChecksumOffset, nextTransportLayer.IsChecksumOptional,
nextTransportLayer.NextLayerChecksumOffset, nextTransportLayer.NextLayerIsChecksumOptional, nextTransportLayer.Checksum);
nextTransportLayer.Checksum);
} }
public bool Equals(IpV4Layer other) public bool Equals(IpV4Layer other)
......
...@@ -9,13 +9,37 @@ namespace PcapDotNet.Packets ...@@ -9,13 +9,37 @@ namespace PcapDotNet.Packets
/// </summary> /// </summary>
public abstract class Layer : ILayer public abstract class Layer : ILayer
{ {
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public abstract int Length { get; } 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); 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) 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 public virtual DataLinkKind? DataLink
{ {
get { return null; } get { return null; }
......
...@@ -4,6 +4,44 @@ using System.Linq; ...@@ -4,6 +4,44 @@ using System.Linq;
namespace PcapDotNet.Packets 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 class PacketBuilder
{ {
public static Packet Build(DateTime timestamp, params ILayer[] layers) public static Packet Build(DateTime timestamp, params ILayer[] layers)
......
using System;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets
{ {
/// <summary> /// <summary>
/// Represents a layer that adds a simple payload. /// Represents a layer that adds a simple payload.
/// Actually can be any buffer of bytes. /// Actually can be any buffer of bytes.
/// </summary> /// </summary>
public class PayloadLayer : SimpleLayer public class PayloadLayer : SimpleLayer, IEquatable<PayloadLayer>
{ {
public Datagram Data { get; set; } /// <summary>
/// Creates an empty payload.
/// </summary>
public PayloadLayer() public PayloadLayer()
{ {
Data = Datagram.Empty; 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 public override int Length
{ {
get { return Data.Length; } get { return Data.Length; }
} }
/// <summary>
/// Two payload layers are equal if they have same data.
/// </summary>
public bool Equals(PayloadLayer other) public bool Equals(PayloadLayer other)
{ {
return other != null && return other != null &&
Data.Equals(other.Data); Data.Equals(other.Data);
} }
/// <summary>
/// Two payload layers are equal if they have same data.
/// </summary>
public override sealed bool Equals(Layer other) public override sealed bool Equals(Layer other)
{ {
return base.Equals(other) && Equals(other as PayloadLayer); 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) protected override void Write(byte[] buffer, int offset)
{ {
Data.Write(buffer, offset); Data.Write(buffer, offset);
......
...@@ -5,11 +5,25 @@ namespace PcapDotNet.Packets ...@@ -5,11 +5,25 @@ namespace PcapDotNet.Packets
/// </summary> /// </summary>
public abstract class SimpleLayer : Layer 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) public override sealed void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
Write(buffer, offset); 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); protected abstract void Write(byte[] buffer, int offset);
} }
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ using System; ...@@ -3,6 +3,7 @@ using System;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
/// RFC 793.
/// TCP Header Format /// TCP Header Format
/// <pre> /// <pre>
/// +-----+-------------+----------+----+-----+-----+-----+-----+-----+-----+-----+-----+------------------+ /// +-----+-------------+----------+----+-----+-----+-----+-----+-----+-----+-----+-----+------------------+
...@@ -154,7 +155,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -154,7 +155,7 @@ namespace PcapDotNet.Packets.Transport
} }
/// <summary> /// <summary>
/// Returns the tcp options contained in this TCP Datagram. /// Returns the TCP options contained in this TCP Datagram.
/// </summary> /// </summary>
public TcpOptions Options public TcpOptions Options
{ {
...@@ -238,6 +239,9 @@ namespace PcapDotNet.Packets.Transport ...@@ -238,6 +239,9 @@ namespace PcapDotNet.Packets.Transport
get { return (ControlBits & TcpControlBits.Fin) == TcpControlBits.Fin; } 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() public override ILayer ExtractLayer()
{ {
return new TcpLayer return new TcpLayer
......
...@@ -2,45 +2,88 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,45 +2,88 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary>
/// RFC 793.
/// Represents the TCP layer.
/// <seealso cref="TcpDatagram"/>
/// </summary>
public class TcpLayer : TransportLayer 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; } 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; } public uint AcknowledgmentNumber { get; set; }
/// <summary>
/// A collection of bits for the TCP control.
/// </summary>
public TcpControlBits ControlBits { get; set; } 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; } 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; } public ushort UrgentPointer { get; set; }
/// <summary>
/// The TCP options contained in this TCP Datagram.
/// </summary>
public TcpOptions Options { get; set; } public TcpOptions Options { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public override IpV4Protocol PreviousLayerProtocol public override IpV4Protocol PreviousLayerProtocol
{ {
get { return IpV4Protocol.Tcp; } 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; } 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; } get { return false; }
} }
public override bool NextLayerCalculateChecksum /// <summary>
{ /// The number of bytes this layer will take.
get { return true; } /// </summary>
}
public override int Length public override int Length
{ {
get { return TcpDatagram.HeaderMinimumLength + Options.BytesLength; } 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) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
TcpDatagram.WriteHeader(buffer, offset, TcpDatagram.WriteHeader(buffer, offset,
......
...@@ -2,23 +2,54 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,23 +2,54 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary>
/// Contains the common part of UDP and TCP layers.
/// <seealso cref="TransportDatagram"/>
/// </summary>
public abstract class TransportLayer : Layer, IIpV4NextTransportLayer 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; } 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; } 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; } public ushort DestinationPort { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public abstract IpV4Protocol PreviousLayerProtocol { get; } 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 public virtual bool CalculateChecksum
{ {
get { return true; } get { return true; }
} }
public abstract int NextLayerChecksumOffset { get; } /// <summary>
public abstract bool NextLayerIsChecksumOptional { get; } /// The offset in the layer where the checksum should be written.
public abstract bool NextLayerCalculateChecksum { get; } /// </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) public virtual bool Equals(TransportLayer other)
{ {
......
...@@ -3,6 +3,7 @@ using System; ...@@ -3,6 +3,7 @@ using System;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
/// RFC 768.
/// This User Datagram Protocol (UDP) is defined to make available a datagram mode of packet-switched computer communication /// 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. /// in the environment of an interconnected set of computer networks.
/// This protocol assumes that the Internet Protocol (IP) is used as the underlying protocol. /// This protocol assumes that the Internet Protocol (IP) is used as the underlying protocol.
...@@ -72,6 +73,9 @@ namespace PcapDotNet.Packets.Transport ...@@ -72,6 +73,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; } get { return true; }
} }
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return new UdpLayer return new UdpLayer
......
...@@ -2,40 +2,68 @@ using PcapDotNet.Packets.IpV4; ...@@ -2,40 +2,68 @@ using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary>
/// RFC 768.
/// Represents the UDP layer.
/// <seealso cref="UdpDatagram"/>
/// </summary>
public class UdpLayer : TransportLayer 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 public override bool CalculateChecksum
{ {
get{return CalculateChecksumValue;} 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; } public bool CalculateChecksumValue { get; set; }
/// <summary>
/// The protocol that should be written in the previous (IPv4) layer.
/// </summary>
public override IpV4Protocol PreviousLayerProtocol public override IpV4Protocol PreviousLayerProtocol
{ {
get { return IpV4Protocol.Udp; } 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; } 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; } get { return true; }
} }
public override bool NextLayerCalculateChecksum /// <summary>
{ /// The number of bytes this layer will take.
get { return CalculateChecksum; } /// </summary>
}
public override int Length public override int Length
{ {
get { return UdpDatagram.HeaderLength; } 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) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
UdpDatagram.WriteHeader(buffer, offset, SourcePort, DestinationPort, payloadLength); 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