Commit 5a676ce0 authored by Brickner_cp's avatar Brickner_cp

IPv6

parent 3cd99e60
...@@ -43,6 +43,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -43,6 +43,7 @@ namespace PcapDotNet.Packets.IpV6
case IpV4Protocol.IpV6Route: // 43 case IpV4Protocol.IpV6Route: // 43
case IpV4Protocol.FragmentHeaderForIpV6: // 44 case IpV4Protocol.FragmentHeaderForIpV6: // 44
case IpV4Protocol.IpV6Opts: // 60 case IpV4Protocol.IpV6Opts: // 60
case IpV4Protocol.MobilityHeader: // 135
return CreateStandardInstance(nextHeader, extensionHeaderData, out numBytesRead); return CreateStandardInstance(nextHeader, extensionHeaderData, out numBytesRead);
case IpV4Protocol.EncapsulatingSecurityPayload: // 50 case IpV4Protocol.EncapsulatingSecurityPayload: // 50
...@@ -50,13 +51,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -50,13 +51,7 @@ namespace PcapDotNet.Packets.IpV6
case IpV4Protocol.AuthenticationHeader: // 51 case IpV4Protocol.AuthenticationHeader: // 51
return IpV6ExtensionHeaderAuthentication.CreateInstance(extensionHeaderData, out numBytesRead); return IpV6ExtensionHeaderAuthentication.CreateInstance(extensionHeaderData, out numBytesRead);
/*
case IpV4Protocol.MobilityHeader: // 135
return IpV6MobilityExtensionHeader.Parse(data);
*/
default: default:
throw new InvalidOperationException("Invalid nextHeader value" + nextHeader); throw new InvalidOperationException("Invalid nextHeader value" + nextHeader);
} }
...@@ -90,6 +85,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -90,6 +85,9 @@ namespace PcapDotNet.Packets.IpV6
case IpV4Protocol.IpV6Opts: // 60 case IpV4Protocol.IpV6Opts: // 60
return IpV6ExtensionHeaderDestinationOptions.ParseData(nextNextHeader, data); return IpV6ExtensionHeaderDestinationOptions.ParseData(nextNextHeader, data);
case IpV4Protocol.MobilityHeader: // 135
return IpV6ExtensionHeaderMobility.ParseData(nextNextHeader, data);
default: default:
throw new InvalidOperationException("Invalid nextHeader value" + nextHeader); throw new InvalidOperationException("Invalid nextHeader value" + nextHeader);
} }
......
...@@ -39,4 +39,42 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -39,4 +39,42 @@ namespace PcapDotNet.Packets.IpV6
get { return sizeof(byte); } get { return sizeof(byte); }
} }
} }
/// <summary>
/// RFC 6275.
/// <pre>
/// +-----+-------------+-------------------------+
/// | Bit | 0-7 | 8-15 |
/// +-----+-------------+-------------------------+
/// | 0 | Option Type | Opt Data Len (optional) |
/// +-----+-------------+-------------------------+
/// | 16 | Option Data (optional) |
/// | ... | |
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
public abstract class IpV6MobilityOption : Option
{
/// <summary>
/// The type of the IP option.
/// </summary>
public IpV6MobilityOptionType OptionType { get; private set; }
internal abstract IpV6MobilityOption CreateInstance(DataSegment data);
protected IpV6MobilityOption(IpV6MobilityOptionType type)
{
OptionType = type;
}
internal override void Write(byte[] buffer, ref int offset)
{
buffer[offset++] = (byte)OptionType;
}
public override int Length
{
get { return sizeof(byte); }
}
}
} }
\ No newline at end of file
...@@ -36,4 +36,41 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -36,4 +36,41 @@ namespace PcapDotNet.Packets.IpV6
internal abstract void WriteData(byte[] buffer, ref int offset); internal abstract void WriteData(byte[] buffer, ref int offset);
} }
/// <summary>
/// RFC 6275.
/// <pre>
/// +-----+-------------+--------------+
/// | Bit | 0-7 | 8-15 |
/// +-----+-------------+--------------+
/// | 0 | Option Type | Opt Data Len |
/// +-----+-------------+--------------+
/// | 16 | Option Data |
/// | ... | |
/// +-----+----------------------------+
/// </pre>
/// </summary>
public abstract class IpV6MobilityOptionComplex : IpV6MobilityOption
{
protected IpV6MobilityOptionComplex(IpV6MobilityOptionType type)
: base(type)
{
}
public override sealed int Length
{
get { return base.Length + sizeof(byte) + DataLength; }
}
internal abstract int DataLength { get; }
internal override sealed void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
buffer[offset++] = (byte)DataLength;
WriteData(buffer, ref offset);
}
internal abstract void WriteData(byte[] buffer, ref int offset);
}
} }
\ No newline at end of file
...@@ -22,4 +22,28 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -22,4 +22,28 @@ namespace PcapDotNet.Packets.IpV6
return new IpV6OptionPad1(); return new IpV6OptionPad1();
} }
} }
/// <summary>
/// RFC 6275.
/// +-----+-----+
/// | Bit | 0-7 |
/// +-----+-----+
/// | 0 | 0 |
/// +-----+-----+
/// </summary>
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.Pad1)]
public class IpV6MobilityOptionPad1 : IpV6MobilityOption
{
public const int OptionLength = sizeof(byte);
public IpV6MobilityOptionPad1()
: base(IpV6MobilityOptionType.Pad1)
{
}
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
return new IpV6MobilityOptionPad1();
}
}
} }
\ No newline at end of file
...@@ -67,4 +67,301 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -67,4 +67,301 @@ namespace PcapDotNet.Packets.IpV6
/// </summary> /// </summary>
LineIdentification = 0x8C, LineIdentification = 0x8C,
} }
}
\ No newline at end of file public enum IpV6MobilityOptionType : byte
{
/// <summary>
/// RFC 6275.
/// </summary>
Pad1 = 0x00,
/// <summary>
/// RFC 6275.
/// </summary>
PadN = 0x01,
/// <summary>
/// RFC 6275.
/// </summary>
BindingRefreshAdvice = 0x02,
/// <summary>
/// RFC 6275.
/// Alternate Care-of Address.
/// </summary>
AlternateCareOfAddress = 0x03,
/// <summary>
/// RFC 6275.
/// </summary>
NonceIndices = 0x04,
/// <summary>
/// RFC 6275.
/// </summary>
AuthorizationData = 0x05,
/// <summary>
/// RFC 3963.
/// Mobile Network Prefix Option.
/// </summary>
MobileNetworkPrefix = 0x06,
/// <summary>
/// RFC 5568.
/// Mobility Header Link-Layer Address option.
/// </summary>
MobilityHeaderLinkLayerAddress = 0x07,
/// <summary>
/// RFC 4283.
/// MN-ID-OPTION-TYPE.
/// </summary>
MnId = 0x08,
/// <summary>
/// RFC 4285.
/// AUTH-OPTION-TYPE.
/// </summary>
Auth = 0x09,
/// <summary>
/// RFC 4285.
/// MESG-ID-OPTION-TYPE
/// </summary>
MesgId = 0x0A,
/// <summary>
/// RFC 4866.
/// CGA Parameters Request.
/// </summary>
CgaParametersRequest = 0x0B,
/// <summary>
/// RFC 4866.
/// CGA Parameters.
/// </summary>
CgaParameters = 0x0C,
/// <summary>
/// RFC 4866.
/// </summary>
Signature = 0x0D,
/// <summary>
/// RFC 4866.
/// </summary>
PermanentHomeKeygenToken = 0x0E,
/// <summary>
/// RFC 4866.
/// Care-of Test Init
/// </summary>
CareOfTestInit = 0x0F,
/// <summary>
/// RFC 4866.
/// Care-of Test.
/// </summary>
CareOfTest = 0x10,
/// <summary>
/// RFC 5026.
/// DNS-UPDATE-TYPE.
/// </summary>
DnsUpdateType = 0x11,
/// <summary>
/// RFC 5096.
/// Experimental Mobility Option.
/// </summary>
ExperimentalMobilityOption = 0x12,
/// <summary>
/// RFC 5094.
/// </summary>
VendorSpecificMobilityOption = 0x13,
/// <summary>
/// RFC 5149.
/// </summary>
ServiceSelectionMobilityOption = 0x14,
/// <summary>
/// RFC 5568.
/// Binding Authorization Data for FMIPv6 (BADF).
/// </summary>
BindingAuthorizationDataForFmIpV6 = 0x15,
/// <summary>
/// RFC 5213.
/// </summary>
HomeNetworkPrefixOption = 0x16,
/// <summary>
/// RFC 5213.
/// </summary>
HandoffIndicatorOption = 0x17,
/// <summary>
/// RFC 5213.
/// </summary>
AccessTechnologyTypeOption = 0x18,
/// <summary>
/// RFC 5213.
/// Mobile Node Link-layer Identifier Option
/// </summary>
MobileNodeLinkLayerIdentifierOption = 0x19,
/// <summary>
/// RFC 5213.
/// Link-local Address Option.
/// </summary>
LinkLocalAddressOption = 0x1A,
/// <summary>
/// RFC 5213.
/// </summary>
TimestampOption = 0x1B,
/// <summary>
/// RFC 5847.
/// </summary>
RestartCounter = 0x1C,
/// <summary>
/// RFC 5555.
/// IPv4 Home Address.
/// </summary>
IpV4HomeAddress = 0x1D,
/// <summary>
/// RFC 5555.
/// IPv4 Address Acknowledgement.
/// </summary>
IpV4AddressAcknowledgement = 0x1E,
/// <summary>
/// RFC 5555.
/// NAT Detection.
/// </summary>
NatDetection = 0x1F,
/// <summary>
/// RFC 5555.
/// IPv4 Care-of Address.
/// </summary>
IpV4CareOfAddress = 0x20,
/// <summary>
/// RFC 5845.
/// GRE Key Option.
/// </summary>
GreKeyOption = 0x21,
/// <summary>
/// RFC 5568.
/// Mobility Header IPv6 Address/Prefix.
/// </summary>
MobilityHeaderIpV6AddressPrefix = 0x22,
/// <summary>
/// RFC 5648.
/// </summary>
BindingIdentifier = 0x23,
/// <summary>
/// RFC5844.
/// IPv4 Home Address Request.
/// </summary>
IpV4HomeAddressRequest = 0x24,
/// <summary>
/// RFC 5844.
/// IPv4 Home Address Reply.
/// </summary>
IpV4HomeAddressReply = 0x25,
/// <summary>
/// RFC 5844.
/// IPv4 Default-Router Address.
/// </summary>
IpV4DefaultRouterAddress = 0x26,
/// <summary>
/// RFC 5844.
/// IPv4 DHCP Support Mode.
/// </summary>
IpV4DHCPSupportMode = 0x27,
/// <summary>
/// RFC 5949.
/// </summary>
ContextRequestOption = 0x28,
/// <summary>
/// RFC 5949.
/// </summary>
LocalMobilityAnchorAddressOption = 0x29,
/// <summary>
/// RFC 5949.
/// Mobile Node Link-local Address Interface Identifier Option.
/// </summary>
MobileNodeLinkLocalAddressInterfaceIdentifierOption = 0x2A,
/// <summary>
/// RFC 6058.
/// </summary>
TransientBinding = 0x2B,
/// <summary>
/// RFC 6089
/// </summary>
FlowSummaryMobilityOption = 0x2C,
/// <summary>
/// RFC 6089.
/// </summary>
FlowIdentificationMobilityOption = 0x2D,
/// <summary>
/// RFC 6463.
/// Redirect-Capability Mobility Option.
/// </summary>
RedirectCapabilityMobilityOption = 0x2E,
/// <summary>
/// RFC 6463.
/// </summary>
RedirectMobilityOption = 0x2F,
/// <summary>
/// RFC 6463.
/// </summary>
LoadInformationMobilityOption = 0x30,
/// <summary>
/// RFC 6463.
/// Alternate IPv4 Care-of Address.
/// </summary>
AlternateIpV4CareOfAddress = 0x31,
/// <summary>
/// RFC 6602.
/// </summary>
MobileNodeGroupIdentifier = 0x32,
/// <summary>
/// RFC 6705.
/// MAG IPv6 Address.
/// </summary>
MagIpV6Address = 0x33,
/// <summary>
/// RFC 6757.
/// </summary>
AccessNetworkIdentifier = 0x34,
}
}
...@@ -11,4 +11,14 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -11,4 +11,14 @@ namespace PcapDotNet.Packets.IpV6
public IpV6OptionType OptionType { get; private set; } public IpV6OptionType OptionType { get; private set; }
} }
internal sealed class IpV6MobilityOptionTypeRegistrationAttribute : Attribute
{
public IpV6MobilityOptionTypeRegistrationAttribute(IpV6MobilityOptionType optionType)
{
OptionType = optionType;
}
public IpV6MobilityOptionType OptionType { get; private set; }
}
} }
\ No newline at end of file
...@@ -40,4 +40,43 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -40,4 +40,43 @@ namespace PcapDotNet.Packets.IpV6
buffer.Write(ref offset, Data); buffer.Write(ref offset, Data);
} }
} }
/// <summary>
/// RFC 6275.
/// <pre>
/// +-----+-------------+--------------+
/// | Bit | 0-7 | 8-15 |
/// +-----+-------------+--------------+
/// | 0 | Option Type | Opt Data Len |
/// +-----+-------------+--------------+
/// | 16 | Option Data |
/// | ... | |
/// +-----+----------------------------+
/// </pre>
/// </summary>
public class IpV6MobilityOptionUnknown : IpV6MobilityOptionComplex
{
public IpV6MobilityOptionUnknown(IpV6MobilityOptionType type, DataSegment data)
: base(type)
{
Data = data;
}
public DataSegment Data { get; private set; }
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
throw new InvalidOperationException("IpV6MobilityOptionUnknown shouldn't be registered.");
}
internal override int DataLength
{
get { return Data.Length; }
}
internal override void WriteData(byte[] buffer, ref int offset)
{
buffer.Write(ref offset, Data);
}
}
} }
\ No newline at end of file
...@@ -91,4 +91,91 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -91,4 +91,91 @@ namespace PcapDotNet.Packets.IpV6
return registraionAttributes.First(); return registraionAttributes.First();
} }
} }
public class IpV6MobilityOptions : Options<IpV6MobilityOption>
{
public IpV6MobilityOptions(DataSegment data)
: this(Read(data))
{
}
private IpV6MobilityOptions(Tuple<IList<IpV6MobilityOption>, bool> optionsAndIsValid)
: base(optionsAndIsValid.Item1, optionsAndIsValid.Item2, null)
{
}
public static Tuple<IList<IpV6MobilityOption>, bool> Read(DataSegment data)
{
int offset = 0;
List<IpV6MobilityOption> options = new List<IpV6MobilityOption>();
bool isValid = true;
while (offset < data.Length)
{
IpV6MobilityOptionType optionType = (IpV6MobilityOptionType)data[offset++];
if (optionType == IpV6MobilityOptionType.Pad1)
{
options.Add(new IpV6MobilityOptionPad1());
continue;
}
if (offset >= data.Length)
{
isValid = false;
break;
}
byte optionDataLength = data[offset++];
if (offset + optionDataLength > data.Length)
{
isValid = false;
break;
}
IpV6MobilityOption option = CreateOption(optionType, data.Subsegment(ref offset, optionDataLength));
if (option == null)
{
isValid = false;
break;
}
options.Add(option);
}
return new Tuple<IList<IpV6MobilityOption>, bool>(options, isValid);
}
private static IpV6MobilityOption CreateOption(IpV6MobilityOptionType optionType, DataSegment data)
{
IpV6MobilityOption prototype;
if (!_prototypes.TryGetValue(optionType, out prototype))
return new IpV6MobilityOptionUnknown(optionType, data);
return prototype.CreateInstance(data);
}
private static readonly Dictionary<IpV6MobilityOptionType, IpV6MobilityOption> _prototypes = InitializePrototypes();
private static Dictionary<IpV6MobilityOptionType, IpV6MobilityOption> InitializePrototypes()
{
var prototypes =
from type in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IpV6MobilityOption).IsAssignableFrom(type) &&
GetRegistrationAttribute(type) != null
select new
{
GetRegistrationAttribute(type).OptionType,
Option = (IpV6MobilityOption)Activator.CreateInstance(type)
};
return prototypes.ToDictionary(option => option.OptionType, option => option.Option);
}
private static IpV6MobilityOptionTypeRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registraionAttributes = type.GetCustomAttributes<IpV6MobilityOptionTypeRegistrationAttribute>(false);
if (!registraionAttributes.Any())
return null;
return registraionAttributes.First();
}
}
} }
\ No newline at end of file
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