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