Commit 356b7864 authored by Brickner_cp's avatar Brickner_cp

Refactor ICMP with limited IPv4 payload.

parent 762de5ab
......@@ -83,7 +83,7 @@ namespace PcapDotNet.Packets.Test
icmpPayloadLength = icmpPayloadLayers.Select(layer => layer.Length).Sum();
IcmpParameterProblemLayer icmpParameterProblemLayer = (IcmpParameterProblemLayer)icmpLayer;
icmpParameterProblemLayer.Pointer = (byte)(icmpParameterProblemLayer.Pointer % icmpPayloadLength);
icmpParameterProblemLayer.OriginalDatagramLength = icmpPayloadLength;
icmpParameterProblemLayer.OriginalDatagramLength = icmpPayloadLength - icmpPayloadLayers.First().Length;
break;
case IcmpMessageType.SecurityFailures:
......
......@@ -39,5 +39,15 @@ namespace PcapDotNet.Packets.Icmp
return IpV4.Payload.Length == OriginalDatagramPayloadLength;
}
internal override bool IsIpV4PayloadLimited
{
get { return true; }
}
internal override int IpV4PayloadLimit
{
get { return OriginalDatagramPayloadLength; }
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -31,9 +32,15 @@ namespace PcapDotNet.Packets.Icmp
{
if (_ipV4 == null && Length >= HeaderLength)
{
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength);
// TODO: Do this processing without recreating the datagram again.
ProcessIpV4Payload(ref _ipV4);
if (IsIpV4PayloadLimited)
{
int ipV4HeaderLength = IpV4Datagram.GetHeaderLength(Subsegment(HeaderLength, Length - HeaderLength));
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Math.Min(Length - HeaderLength, ipV4HeaderLength + IpV4PayloadLimit));
}
else
{
_ipV4 = new IpV4Datagram(Buffer, StartOffset + HeaderLength, Length - HeaderLength);
}
}
return _ipV4;
}
......@@ -52,8 +59,14 @@ namespace PcapDotNet.Packets.Icmp
return (ip.Length >= IpV4Datagram.HeaderMinimumLength && ip.Length >= ip.HeaderLength);
}
internal virtual void ProcessIpV4Payload(ref IpV4Datagram ipV4)
internal virtual int IpV4PayloadLimit
{
get { throw new NotImplementedException(); }
}
internal virtual bool IsIpV4PayloadLimited
{
get { return false; }
}
private IpV4Datagram _ipV4;
......
......@@ -74,10 +74,14 @@ namespace PcapDotNet.Packets.Icmp
return new IcmpParameterProblemDatagram(buffer, offset, length);
}
internal override void ProcessIpV4Payload(ref IpV4Datagram ipV4)
internal override bool IsIpV4PayloadLimited
{
if (ipV4.Payload.Length > OriginalDatagramLength)
ipV4 = new IpV4Datagram(ipV4.Buffer, ipV4.StartOffset, ipV4.HeaderLength + OriginalDatagramLength);
get { return true; }
}
internal override int IpV4PayloadLimit
{
get { return OriginalDatagramLength; }
}
private IcmpParameterProblemDatagram(byte[] buffer, int offset, int length)
......
......@@ -71,7 +71,7 @@ namespace PcapDotNet.Packets.IpV4
/// </summary>
public int HeaderLength
{
get { return (this[Offset.VersionAndHeaderLength] & 0x0F) * 4; }
get { return ReadHeaderLength(this); }
}
/// <summary>
......@@ -95,7 +95,7 @@ namespace PcapDotNet.Packets.IpV4
/// </summary>
public override int TotalLength
{
get { return ReadUShort(Offset.TotalLength, Endianity.Big); }
get { return ReadTotalLength(this); }
}
/// <summary>
......@@ -228,12 +228,23 @@ namespace PcapDotNet.Packets.IpV4
return Subsegment(HeaderLength, Length - HeaderLength);
}
internal static int GetTotalLength(Datagram ipV4Datagram)
internal static int GetHeaderLength(DataSegment ipV4Datagram)
{
if (ipV4Datagram.Length < HeaderMinimumLength)
return ipV4Datagram.Length;
ushort totalLength = ipV4Datagram.ReadUShort(Offset.TotalLength, Endianity.Big);
int headerLength = ReadHeaderLength(ipV4Datagram);
if (ipV4Datagram.Length < headerLength)
return ipV4Datagram.Length;
return headerLength;
}
internal static int GetTotalLength(DataSegment ipV4Datagram)
{
if (ipV4Datagram.Length < HeaderMinimumLength)
return ipV4Datagram.Length;
ushort totalLength = ReadTotalLength(ipV4Datagram);
if (ipV4Datagram.Length < totalLength)
return ipV4Datagram.Length;
......@@ -323,6 +334,16 @@ namespace PcapDotNet.Packets.IpV4
return CalculateTransportChecksum(Buffer, StartOffset, HeaderLength, (ushort)Transport.Length, Transport.ChecksumOffset, Transport.IsChecksumOptional, Destination);
}
private static int ReadHeaderLength(DataSegment ipV4Datagram)
{
return (ipV4Datagram[Offset.VersionAndHeaderLength] & 0x0F) * 4;
}
private static ushort ReadTotalLength(DataSegment ipV4Datagram)
{
return ipV4Datagram.ReadUShort(Offset.TotalLength, Endianity.Big);
}
private ushort CalculateHeaderChecksum()
{
uint sum = Sum16Bits(Buffer, StartOffset, Math.Min(Offset.HeaderChecksum, Length)) +
......
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