Commit b4143c20 authored by Brickner_cp's avatar Brickner_cp

Added Router Alert IPv4 Option.

parent ca31c6f5
...@@ -37,6 +37,9 @@ namespace PcapDotNet.Core.Test ...@@ -37,6 +37,9 @@ namespace PcapDotNet.Core.Test
case IpV4OptionType.TraceRoute: case IpV4OptionType.TraceRoute:
return "Unknown (0x52) (12 bytes)"; return "Unknown (0x52) (12 bytes)";
case IpV4OptionType.RouterAlert:
return "Router Alert: Unknown (" + ((IpV4OptionRouterAlert)option).Value + ")";
default: default:
throw new InvalidOperationException("Illegal option type " + option.OptionType); throw new InvalidOperationException("Illegal option type " + option.OptionType);
} }
...@@ -49,6 +52,7 @@ namespace PcapDotNet.Core.Test ...@@ -49,6 +52,7 @@ namespace PcapDotNet.Core.Test
case IpV4OptionType.EndOfOptionList: case IpV4OptionType.EndOfOptionList:
case IpV4OptionType.NoOperation: case IpV4OptionType.NoOperation:
case IpV4OptionType.StreamIdentifier: case IpV4OptionType.StreamIdentifier:
case IpV4OptionType.RouterAlert:
break; break;
case IpV4OptionType.LooseSourceRouting: case IpV4OptionType.LooseSourceRouting:
......
...@@ -75,7 +75,7 @@ namespace PcapDotNet.Core.Test ...@@ -75,7 +75,7 @@ namespace PcapDotNet.Core.Test
[TestMethod] [TestMethod]
public void ComparePacketsToWiresharkTest() public void ComparePacketsToWiresharkTest()
{ {
for (int i = 0; i != 1; ++i) for (int i = 0; i != 10; ++i)
{ {
// Create packets // Create packets
List<Packet> packets = new List<Packet>(CreateRandomPackets(100)); List<Packet> packets = new List<Packet>(CreateRandomPackets(100));
......
...@@ -190,6 +190,9 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -190,6 +190,9 @@ namespace PcapDotNet.Packets.TestUtils
case IpV4OptionType.TraceRoute: case IpV4OptionType.TraceRoute:
return new IpV4OptionTraceRoute(random.NextUShort(), random.NextUShort(), random.NextUShort(), random.NextIpV4Address()); return new IpV4OptionTraceRoute(random.NextUShort(), random.NextUShort(), random.NextUShort(), random.NextIpV4Address());
case IpV4OptionType.RouterAlert:
return new IpV4OptionRouterAlert(random.NextUShort());
default: default:
throw new InvalidOperationException("optionType = " + optionType); throw new InvalidOperationException("optionType = " + optionType);
} }
......
...@@ -76,6 +76,11 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -76,6 +76,11 @@ namespace PcapDotNet.Packets.IpV4
get { return (this[Offset.VersionAndHeaderLength] & 0x0F) * 4; } get { return (this[Offset.VersionAndHeaderLength] & 0x0F) * 4; }
} }
public int RealHeaderLength
{
get { return Math.Min(HeaderLength, Length); }
}
/// <summary> /// <summary>
/// Type of Service field. /// Type of Service field.
/// </summary> /// </summary>
...@@ -169,7 +174,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -169,7 +174,7 @@ namespace PcapDotNet.Packets.IpV4
get get
{ {
if (_options == null) if (_options == null)
_options = new IpV4Options(Buffer, StartOffset + Offset.Options, HeaderLength - HeaderMinimumLength); _options = new IpV4Options(Buffer, StartOffset + Offset.Options, RealHeaderLength - HeaderMinimumLength);
return _options; return _options;
} }
} }
......
...@@ -109,17 +109,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -109,17 +109,8 @@ namespace PcapDotNet.Packets.IpV4
case IpV4OptionType.NoOperation: case IpV4OptionType.NoOperation:
return Nop; return Nop;
case IpV4OptionType.BasicSecurity: default:
case IpV4OptionType.LooseSourceRouting: return IpV4OptionComplex.ReadOptionComplex(optionType, buffer, ref offset, offsetEnd - offset);
case IpV4OptionType.StrictSourceRouting:
case IpV4OptionType.RecordRoute:
case IpV4OptionType.StreamIdentifier:
case IpV4OptionType.InternetTimestamp:
case IpV4OptionType.TraceRoute:
return IpV4OptionComplex.ReadOptionComplex(optionType, buffer, ref offset, offsetEnd - offset);
default:
return null;
} }
} }
......
...@@ -5,16 +5,6 @@ using System.Reflection; ...@@ -5,16 +5,6 @@ using System.Reflection;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
internal class IpV4OptionTypeRegistrationAttribute : Attribute
{
public IpV4OptionTypeRegistrationAttribute(IpV4OptionType optionType)
{
OptionType = optionType;
}
public IpV4OptionType OptionType { get; set; }
}
internal interface IIpv4OptionComplexFactory internal interface IIpv4OptionComplexFactory
{ {
IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength); IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength);
...@@ -26,8 +16,6 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -26,8 +16,6 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public abstract class IpV4OptionComplex : IpV4Option public abstract class IpV4OptionComplex : IpV4Option
{ {
private static readonly Dictionary<IpV4OptionType, IIpv4OptionComplexFactory> _complexOptions;
static IpV4OptionComplex() static IpV4OptionComplex()
{ {
var complexOptions = var complexOptions =
...@@ -43,20 +31,21 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -43,20 +31,21 @@ namespace PcapDotNet.Packets.IpV4
_complexOptions = complexOptions.ToDictionary(option => option.OptionType, option => option.Option); _complexOptions = complexOptions.ToDictionary(option => option.OptionType, option => option.Option);
} }
private static IpV4OptionTypeRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registraionAttributes = type.GetCustomAttributes(typeof(IpV4OptionTypeRegistrationAttribute), false);
if (registraionAttributes.Length == 0)
return null;
return ((IpV4OptionTypeRegistrationAttribute)registraionAttributes[0]);
}
/// <summary> /// <summary>
/// The header length in bytes for the option (type and size). /// The header length in bytes for the option (type and size).
/// </summary> /// </summary>
public const int OptionHeaderLength = 2; public const int OptionHeaderLength = 2;
internal class IpV4OptionTypeRegistrationAttribute : Attribute
{
public IpV4OptionTypeRegistrationAttribute(IpV4OptionType optionType)
{
OptionType = optionType;
}
public IpV4OptionType OptionType { get; set; }
}
internal static IpV4OptionComplex ReadOptionComplex(IpV4OptionType optionType, byte[] buffer, ref int offset, int length) internal static IpV4OptionComplex ReadOptionComplex(IpV4OptionType optionType, byte[] buffer, ref int offset, int length)
{ {
if (length < 1) if (length < 1)
...@@ -86,5 +75,16 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -86,5 +75,16 @@ namespace PcapDotNet.Packets.IpV4
: base(type) : base(type)
{ {
} }
private static IpV4OptionTypeRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registraionAttributes = type.GetCustomAttributes(typeof(IpV4OptionTypeRegistrationAttribute), false);
if (registraionAttributes.Length == 0)
return null;
return ((IpV4OptionTypeRegistrationAttribute)registraionAttributes[0]);
}
private static readonly Dictionary<IpV4OptionType, IIpv4OptionComplexFactory> _complexOptions;
} }
} }
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.IpV4
{
/// <summary>
/// The Router Alert option has the semantic "routers should examine this packet more closely".
/// By including the Router Alert option in the IP header of its protocol message,
/// RSVP can cause the message to be intercepted while causing little or no performance
/// penalty on the forwarding of normal data packets.
///
/// Routers that support option processing in the fast path already demultiplex processing based on the option type field.
/// If all option types are supported in the fast path, then the addition of another option type to process is unlikely to impact performance.
/// If some option types are not supported in the fast path,
/// this new option type will be unrecognized and cause packets carrying it to be kicked out into the slow path,
/// so no change to the fast path is necessary, and no performance penalty will be incurred for regular data packets.
///
/// Routers that do not support option processing in the fast path will cause packets carrying this new option
/// to be forwarded through the slow path, so no change to the fast path is necessary and no performance penalty
/// will be incurred for regular data packets.
///
/// The Router Alert option has the following format:
/// +--------+--------+--------+--------+
/// |10010100|00000100| 2 octet value |
/// +--------+--------+--------+--------+
/// </summary>
[IpV4OptionTypeRegistration(IpV4OptionType.RouterAlert)]
public class IpV4OptionRouterAlert : IpV4OptionComplex, IIpv4OptionComplexFactory, IEquatable<IpV4OptionRouterAlert>
{
/// <summary>
/// The number of bytes this option take.
/// </summary>
public const int OptionLength = 4;
/// <summary>
/// The number of bytes this option's value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Create the option according to the given value.
/// </summary>
public IpV4OptionRouterAlert(ushort value)
: base(IpV4OptionType.RouterAlert)
{
_value = value;
}
/// <summary>
/// Creates a 0 value router alert option
/// </summary>
public IpV4OptionRouterAlert()
: this(0)
{
}
/// <summary>
/// The value of the alert.
/// </summary>
public ushort Value
{
get { return _value; }
}
/// <summary>
/// The number of bytes this option will take.
/// </summary>
public override int Length
{
get { return OptionLength; }
}
/// <summary>
/// True iff this option may appear at most once in a datagram.
/// </summary>
public override bool IsAppearsAtMostOnce
{
get { return true; }
}
/// <summary>
/// Two stream identifier options are equal if they have the same identifier.
/// </summary>
public bool Equals(IpV4OptionRouterAlert other)
{
if (other == null)
return false;
return Value == other.Value;
}
/// <summary>
/// Two stream identifier options are equal if they have the same identifier.
/// </summary>
public override bool Equals(IpV4Option other)
{
return Equals(other as IpV4OptionRouterAlert);
}
/// <summary>
/// The hash code value is the xor of the base class hash code and the value hash code.
/// </summary>
public override int GetHashCode()
{
return base.GetHashCode() ^
Value.GetHashCode();
}
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{
if (valueLength != OptionHeaderLength)
return null;
ushort value = buffer.ReadUShort(ref offset, Endianity.Big);
return new IpV4OptionRouterAlert(value);
}
internal override void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
buffer.Write(ref offset, Value, Endianity.Big);
}
private readonly ushort _value;
}
}
\ No newline at end of file
...@@ -36,6 +36,14 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -36,6 +36,14 @@ namespace PcapDotNet.Packets.IpV4
_identifier = identifier; _identifier = identifier;
} }
/// <summary>
/// Creates a 0 stream identifier
/// </summary>
public IpV4OptionStreamIdentifier()
: this(0)
{
}
/// <summary> /// <summary>
/// The identifier of the stream. /// The identifier of the stream.
/// </summary> /// </summary>
...@@ -81,21 +89,12 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -81,21 +89,12 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// The hash code value is the xor of the base class hash code and the identifier hash code. /// The hash code value is the xor of the base class hash code and the identifier hash code.
/// </summary> /// </summary>
/// <returns></returns>
public override int GetHashCode() public override int GetHashCode()
{ {
return base.GetHashCode() ^ return base.GetHashCode() ^
Identifier.GetHashCode(); Identifier.GetHashCode();
} }
/// <summary>
/// Creates a 0 stream identifier
/// </summary>
public IpV4OptionStreamIdentifier()
: this(0)
{
}
public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength) public IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength)
{ {
if (valueLength != OptionHeaderLength) if (valueLength != OptionHeaderLength)
......
...@@ -72,6 +72,11 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -72,6 +72,11 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// Internet Timestamp. /// Internet Timestamp.
/// </summary> /// </summary>
InternetTimestamp = 68 InternetTimestamp = 68,
/// <summary>
/// Router Alert Option (RFC 2113).
/// </summary>
RouterAlert = 148
} }
} }
\ No newline at end of file
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
<Compile Include="IpV4\IpV4Option.cs" /> <Compile Include="IpV4\IpV4Option.cs" />
<Compile Include="IpV4\IpV4OptionComplex.cs" /> <Compile Include="IpV4\IpV4OptionComplex.cs" />
<Compile Include="IpV4\IpV4OptionLooseSourceRouting.cs" /> <Compile Include="IpV4\IpV4OptionLooseSourceRouting.cs" />
<Compile Include="IpV4\IpV4OptionRouterAlert.cs" />
<Compile Include="IpV4\IpV4OptionSecurityProtectionAuthority.cs" /> <Compile Include="IpV4\IpV4OptionSecurityProtectionAuthority.cs" />
<Compile Include="IpV4\IpV4OptionSimple.cs" /> <Compile Include="IpV4\IpV4OptionSimple.cs" />
<Compile Include="IpV4\IpV4OptionRecordRoute.cs" /> <Compile Include="IpV4\IpV4OptionRecordRoute.cs" />
......
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