Commit eeeea13e authored by Brickner_cp's avatar Brickner_cp

IPv6

parent 4d770fb0
......@@ -57,7 +57,7 @@ namespace PcapDotNet.Packets.Test
Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, payloadLayer);
// Ethernet
Assert.IsTrue(new[] {EthernetType.IpV4, EthernetType.Arp, EthernetType.VLanTaggedFrame}.Contains(packet.Ethernet.EtherType) ||
Assert.IsTrue(new[] {EthernetType.IpV4, EthernetType.IpV6, EthernetType.Arp, EthernetType.VLanTaggedFrame}.Contains(packet.Ethernet.EtherType) ||
packet.IsValid, "IsValid - EtherType = " + packet.Ethernet.EtherType);
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer(), "Ethernet Layer");
......
......@@ -68,7 +68,7 @@ namespace PcapDotNet.Packets.Test
Packet packet = packetBuilder.Build(DateTime.Now);
if (greLayer.Checksum == null &&
!new[] { EthernetType.IpV4, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(packet.Ethernet.IpV4.Gre.ProtocolType))
!new[] { EthernetType.IpV4, EthernetType.IpV6, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(packet.Ethernet.IpV4.Gre.ProtocolType))
{
Assert.IsTrue(packet.IsValid, "IsValid, ProtocolType=" + packet.Ethernet.IpV4.Gre.ProtocolType);
}
......@@ -222,7 +222,7 @@ namespace PcapDotNet.Packets.Test
PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer);
Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid ||
new[] {EthernetType.IpV4, EthernetType.Arp, EthernetType.VLanTaggedFrame}.Contains(greLayer.ProtocolType),
new[] { EthernetType.IpV4, EthernetType.IpV6, EthernetType.Arp, EthernetType.VLanTaggedFrame }.Contains(greLayer.ProtocolType),
"IsValid. ProtoclType=" + greLayer.ProtocolType);
GreDatagram gre = packet.Ethernet.IpV4.Gre;
......
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Base;
......@@ -59,7 +60,7 @@ namespace PcapDotNet.Packets.Test
EtherType = EthernetType
};
Random random = new Random(1);
Random random = new Random();
for (int i = 0; i != 1000; ++i)
{
......@@ -67,7 +68,10 @@ namespace PcapDotNet.Packets.Test
PayloadLayer payloadLayer = random.NextPayloadLayer(random.NextInt(0, 50 * 1024));
Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, ipV6Layer, payloadLayer);
List<ILayer> layers = new List<ILayer> {ethernetLayer, ipV6Layer};
if (ipV6Layer.ExtensionHeaders.LastHeader != IpV4Protocol.EncapsulatingSecurityPayload)
layers.Add(payloadLayer);
Packet packet = PacketBuilder.Build(DateTime.Now, layers);
Assert.IsTrue(packet.IsValid, string.Format("IsValid ({0}...{1})", ipV6Layer.NextHeader, ipV6Layer.ExtensionHeaders.NextHeader));
......
......@@ -16,11 +16,21 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV6Address(random.NextUInt128());
}
public static IpV6Address NextIpV6AddressWithLeadingZeroBytes(this Random random, int numLeadingZeros)
{
return new IpV6Address(random.NextUInt128() >> (8 * numLeadingZeros));
}
public static IpV6Address[] NextIpV6AddressArray(this Random random, int count)
{
return ((Func<IpV6Address>)(random.NextIpV6Address)).GenerateArray(count);
}
public static IpV6Address[] NextIpV6AddressWithLeadingZeroBytesArray(this Random random, int numLeadingZeros, int count)
{
return ((Func<IpV6Address>)(() => random.NextIpV6AddressWithLeadingZeroBytes(numLeadingZeros))).GenerateArray(count);
}
public static IpV6Layer NextIpV6Layer(this Random random)
{
IpV6ExtensionHeaders extensionHeaders = random.NextIpV6ExtensionHeaders(random.NextInt(0, 10));
......@@ -73,10 +83,14 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV6ExtensionHeaderRoutingHomeAddress(nextHeader, random.NextByte(), random.NextIpV6Address());
case IpV6RoutingType.RplSourceRouteHeader:
return new IpV6ExtensionHeaderRoutingRpl(nextHeader, random.NextByte(),
random.NextByte(IpV6ExtensionHeaderRoutingRpl.MaxCommonPrefixLength + 1),
random.NextByte(IpV6ExtensionHeaderRoutingRpl.MaxCommonPrefixLength + 1),
random.NextIpV6AddressArray(random.NextInt(0, 10)));
byte commonPrefixLengthForNonLastAddresses = random.NextByte(IpV6ExtensionHeaderRoutingRpl.MaxCommonPrefixLength + 1);
byte commonPrefixLengthForLastAddress = random.NextByte(IpV6ExtensionHeaderRoutingRpl.MaxCommonPrefixLength + 1);
IpV6Address[] addresses = random.NextIpV6AddressWithLeadingZeroBytesArray(commonPrefixLengthForNonLastAddresses,
random.NextInt(0, 10));
if (addresses.Any() || random.NextBool())
addresses = addresses.Concat(random.NextIpV6AddressWithLeadingZeroBytes(commonPrefixLengthForLastAddress)).ToArray();
return new IpV6ExtensionHeaderRoutingRpl(nextHeader, random.NextByte(), commonPrefixLengthForNonLastAddresses,
commonPrefixLengthForLastAddress, addresses);
default:
throw new InvalidOperationException(string.Format("Invalid routingType value {0}", routingType));
......@@ -155,7 +169,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV6ExtensionHeaderMobilityFastNeighborAdvertisement(nextHeader, checksum, random.NextIpV6MobilityOptions());
case IpV6MobilityHeaderType.Experimental: // 11
return new IpV6ExtensionHeaderMobilityExperimental(nextHeader, checksum, random.NextDataSegment(random.Next(100)));
return new IpV6ExtensionHeaderMobilityExperimental(nextHeader, checksum, random.NextDataSegment(2 + random.Next(10) * 8));
case IpV6MobilityHeaderType.HomeAgentSwitchMessage: // 12
return new IpV6ExtensionHeaderMobilityHomeAgentSwitchMessage(nextHeader, checksum, random.NextIpV6AddressArray(random.NextInt(0, 10)),
......@@ -260,7 +274,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV6OptionSmfDpdNull(identifier);
case IpV6TaggerIdType.Default:
return new IpV6OptionSmfDpdDefault(random.NextDataSegment(random.NextInt(0, 100)), identifier);
return new IpV6OptionSmfDpdDefault(random.NextDataSegment(random.NextInt(1, 17)), identifier);
case IpV6TaggerIdType.IpV4:
return new IpV6OptionSmfDpdIpV4(random.NextIpV4Address(), identifier);
......@@ -447,7 +461,7 @@ namespace PcapDotNet.Packets.TestUtils
return
new IpV6MobilityOptionContextRequest(
((Func<IpV6MobilityOptionContextRequestEntry>)(() => new IpV6MobilityOptionContextRequestEntry(
random.NextByte(), random.NextDataSegment(random.NextInt(0, 100))))).
random.NextByte(), random.NextDataSegment(random.NextInt(0, 25))))).
GenerateArray(random.NextInt(0, 10)));
case IpV6MobilityOptionType.LocalMobilityAnchorAddress:
......@@ -516,7 +530,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV6FlowIdentificationSubOptionBindingReference(((Func<ushort>)(random.NextUShort)).GenerateArray(random.NextInt(0, 10)));
case IpV6FlowIdentificationSubOptionType.TrafficSelector:
return new IpV6FlowIdentificationSubOptionTrafficSelector(random.NextEnum<IpV6FlowIdentificationTrafficSelectorFormat>(), random.NextDataSegment(random.NextInt(0, 100)));
return new IpV6FlowIdentificationSubOptionTrafficSelector(random.NextEnum<IpV6FlowIdentificationTrafficSelectorFormat>(), random.NextDataSegment(random.NextInt(0, 50)));
default:
throw new InvalidOperationException(string.Format("Invalid optionType value {0}", optionType));
......@@ -525,7 +539,18 @@ namespace PcapDotNet.Packets.TestUtils
public static IpV6AccessNetworkIdentifierSubOptions NextIpV6AccessNetworkIdentifierSubOptions(this Random random)
{
return new IpV6AccessNetworkIdentifierSubOptions(((Func<IpV6AccessNetworkIdentifierSubOption>)(random.NextIpV6AccessNetworkIdentifierSubOption)).GenerateArray(random.NextInt(0, 10)));
List<IpV6AccessNetworkIdentifierSubOption> subOptions = new List<IpV6AccessNetworkIdentifierSubOption>();
int numOptions = random.NextInt(0, 10);
int optionsBytesLength = 0;
for (int i = 0; i != numOptions; ++i)
{
IpV6AccessNetworkIdentifierSubOption subOption = random.NextIpV6AccessNetworkIdentifierSubOption();
if (optionsBytesLength + subOption.Length > byte.MaxValue - 2)
break;
subOptions.Add(subOption);
optionsBytesLength += subOption.Length;
}
return new IpV6AccessNetworkIdentifierSubOptions(subOptions);
}
public static IpV6AccessNetworkIdentifierSubOption NextIpV6AccessNetworkIdentifierSubOption(this Random random)
......
......@@ -248,12 +248,11 @@ namespace PcapDotNet.Packets.IpV6
protected override bool CalculateIsValid()
{
_isValid = true;
ParseExtensionHeaders();
return _isValid;
}
private IpV6ExtensionHeaders _extensionHeaders;
private bool _isValid;
private bool _isValid = true;
}
}
......@@ -244,6 +244,15 @@ namespace PcapDotNet.Packets.IpV6
{
public IpV6ExtensionHeaders(ReadOnlyCollection<IpV6ExtensionHeader> extensionHeaders)
{
for (int i = 0; i < extensionHeaders.Count; ++i)
{
if (extensionHeaders[i].Protocol == IpV4Protocol.EncapsulatingSecurityPayload && i != extensionHeaders.Count - 1)
{
throw new ArgumentException(
string.Format("EncapsulatingSecurityPayload can only be the last extension header. However it is the {0} out of {1}.", (i + 1),
extensionHeaders.Count), "extensionHeaders");
}
}
Headers = extensionHeaders;
IsValid = true;
}
......@@ -291,6 +300,16 @@ namespace PcapDotNet.Packets.IpV6
}
}
public IpV4Protocol? LastHeader
{
get
{
if (!Headers.Any())
return null;
return Headers[Headers.Count - 1].Protocol;
}
}
public IpV4Protocol? NextHeader
{
get
......
......@@ -268,9 +268,6 @@ namespace PcapDotNet.Packets.IpV6
}
Checksum = checksum;
MobilityOptions = mobilityOptions;
// TODO: Remove this.
if (Length % 8 != 0)
throw new InvalidOperationException("Must divide by 8");
}
/// <summary>
......@@ -746,8 +743,8 @@ namespace PcapDotNet.Packets.IpV6
return null;
ushort homeNonceIndex = messageData.ReadUShort(MessageDataOffset.HomeNonceIndex, Endianity.Big);
ushort homeInitCookie = messageData.ReadUShort(MessageDataOffset.HomeInitCookie, Endianity.Big);
ushort homeKeygenToken = messageData.ReadUShort(MessageDataOffset.HomeKeygenToken, Endianity.Big);
ulong homeInitCookie = messageData.ReadULong(MessageDataOffset.HomeInitCookie, Endianity.Big);
ulong homeKeygenToken = messageData.ReadULong(MessageDataOffset.HomeKeygenToken, Endianity.Big);
IpV6MobilityOptions options = new IpV6MobilityOptions(messageData.Subsegment(MessageDataOffset.Options, messageData.Length - MessageDataOffset.Options));
return new IpV6ExtensionHeaderMobilityHomeTest(nextHeader, checksum, homeNonceIndex, homeInitCookie, homeKeygenToken, options);
}
......@@ -1892,7 +1889,7 @@ namespace PcapDotNet.Packets.IpV6
}
/// <summary>
/// RFCs 5096.
/// RFC 5096.
/// <pre>
/// +-----+-------------+-------------------------+
/// | Bit | 0-7 | 8-15 |
......@@ -1913,8 +1910,8 @@ namespace PcapDotNet.Packets.IpV6
public IpV6ExtensionHeaderMobilityExperimental(IpV4Protocol nextHeader, ushort checksum, DataSegment messageData)
: base(nextHeader, checksum, IpV6MobilityOptions.None, null)
{
if (messageData.Length % 8 != 4)
throw new ArgumentException("Message data size must be an integral product of 8 bytes plus 4 bytes", "messageData");
if (messageData.Length % 8 != 2)
throw new ArgumentException("Message data size must be an integral product of 8 bytes plus 2 bytes", "messageData");
MessageData = messageData;
}
......
......@@ -80,14 +80,37 @@ namespace PcapDotNet.Packets.IpV6
}
CommonPrefixLengthForLastAddress = commonPrefixLengthForLastAddress;
if (addresses.Any())
{
if (commonPrefixLengthForNonLastAddresses != 0)
{
for (int i = 0; i != addresses.Length - 1; ++i)
ValidateCommonPrefixForAddress(addresses, i, commonPrefixLengthForNonLastAddresses);
}
if (commonPrefixLengthForLastAddress != 0)
ValidateCommonPrefixForAddress(addresses, addresses.Length - 1, commonPrefixLengthForLastAddress);
}
Addresses = addresses.AsReadOnly();
PadSize = (byte)((8 - Length % 8) % 8);
}
private static void ValidateCommonPrefixForAddress(IpV6Address[] addresses, int addressIndex, byte commonPrefixLength)
{
IpV6Address address = addresses[addressIndex];
if (address.ToValue() >> (8 * (IpV6Address.SizeOf - commonPrefixLength)) != 0)
{
throw new ArgumentOutOfRangeException("addresses", address,
string.Format("When an address has {0} common bytes, it should start with {0} zero bytes.",
commonPrefixLength));
}
}
public override IpV6RoutingType RoutingType
{
get { return IpV6RoutingType.SourceRoute; }
get { return IpV6RoutingType.RplSourceRouteHeader; }
}
/// <summary>
......@@ -129,7 +152,7 @@ namespace PcapDotNet.Packets.IpV6
byte commonPrefixLengthForNonLastAddresses =
(byte)((routingData[RoutingDataOffset.CommonPrefixLengthForNonLastAddresses] & RoutingDataMask.CommonPrefixLengthForNonLastAddresses) >>
RoutingDataShift.CommonPrefixLengthForNonLastAddresses);
if (commonPrefixLengthForNonLastAddresses >= MaxCommonPrefixLength)
if (commonPrefixLengthForNonLastAddresses > MaxCommonPrefixLength)
return null;
byte commonPrefixLengthForLastAddress =
......@@ -141,8 +164,11 @@ namespace PcapDotNet.Packets.IpV6
if (padSize > MaxPadSize)
return null;
int numAddresses = (routingData.Length - RoutingDataOffset.Addresses - padSize - (IpV6Address.SizeOf - commonPrefixLengthForLastAddress)) /
(IpV6Address.SizeOf - commonPrefixLengthForNonLastAddresses) + 1;
int addressesLength = routingData.Length - RoutingDataOffset.Addresses - padSize;
int numAddresses = addressesLength == 0
? 0
: (addressesLength - (IpV6Address.SizeOf - commonPrefixLengthForLastAddress)) /
(IpV6Address.SizeOf - commonPrefixLengthForNonLastAddresses) + 1;
if (numAddresses < 0)
return null;
......@@ -154,16 +180,16 @@ namespace PcapDotNet.Packets.IpV6
{
DataSegment addressSegment =
routingData.Subsegment(RoutingDataOffset.Addresses + i * (IpV6Address.SizeOf - commonPrefixLengthForNonLastAddresses),
commonPrefixLengthForNonLastAddresses);
addressSegment.Write(addressBytes, 0);
IpV6Address.SizeOf - commonPrefixLengthForNonLastAddresses);
addressSegment.Write(addressBytes, commonPrefixLengthForNonLastAddresses);
addresses[i] = addressBytes.ReadIpV6Address(0, Endianity.Big);
}
addressBytes = new byte[IpV6Address.SizeOf];
DataSegment lastAddressSegment =
routingData.Subsegment(RoutingDataOffset.Addresses + (numAddresses - 1) * (IpV6Address.SizeOf - commonPrefixLengthForNonLastAddresses),
commonPrefixLengthForLastAddress);
lastAddressSegment.Write(addressBytes, 0);
IpV6Address.SizeOf - commonPrefixLengthForLastAddress);
lastAddressSegment.Write(addressBytes, commonPrefixLengthForLastAddress);
addresses[numAddresses - 1] = addressBytes.ReadIpV6Address(0, Endianity.Big);
}
return new IpV6ExtensionHeaderRoutingRpl(nextHeader, segmentsLeft, commonPrefixLengthForNonLastAddresses, commonPrefixLengthForLastAddress,
......
......@@ -105,6 +105,9 @@ namespace PcapDotNet.Packets.IpV6
nextHeader = NextHeader.Value;
}
if (nextLayer != null && ExtensionHeaders.LastHeader == IpV4Protocol.EncapsulatingSecurityPayload)
throw new ArgumentException("Cannot have a layer after IpV6Layer with EncapsulatingSecurityPayload extension header.", "nextLayer");
IpV6Datagram.WriteHeader(buffer, offset,
TrafficClass, FlowLabel, (ushort)(payloadLength + ExtensionHeaders.Sum(header => header.Length)), nextHeader, HopLimit, Source, CurrentDestination, ExtensionHeaders);
}
......
......@@ -67,15 +67,20 @@ namespace PcapDotNet.Packets.IpV6
get { return base.Length + sizeof(byte) + DataLength; }
}
internal const int MaxDataLength = byte.MaxValue - sizeof(byte) - sizeof(byte);
internal abstract int DataLength { get; }
internal override sealed void Write(byte[] buffer, ref int offset)
{
base.Write(buffer, ref offset);
// TODO: Remove this check.
if (DataLength > byte.MaxValue)
throw new InvalidOperationException("DataLength is too big.");
buffer[offset++] = (byte)DataLength;
WriteData(buffer, ref offset);
}
internal abstract void WriteData(byte[] buffer, ref int offset);
}
}
\ No newline at end of file
}
using System;
namespace PcapDotNet.Packets.IpV6
{
/// <summary>
......@@ -28,6 +30,17 @@ namespace PcapDotNet.Packets.IpV6
public IpV6OptionSmfDpdDefault(DataSegment taggerId, DataSegment identifier)
: base(identifier)
{
if (taggerId.Length > TaggerIdMaxLength)
{
throw new ArgumentOutOfRangeException("taggerId", taggerId,
string.Format("Length is {0} but it must not be longer than {1} bytes.", taggerId.Length,
TaggerIdMaxLength));
}
if (taggerId.Length == 0)
{
throw new ArgumentOutOfRangeException("taggerId", taggerId,
string.Format("Length is {0} but it must be longer than 0 bytes.", taggerId.Length));
}
TaggerId = taggerId;
}
......
......@@ -26,6 +26,8 @@ namespace PcapDotNet.Packets.IpV6
/// </summary>
public abstract class IpV6OptionSmfDpdSequenceBased : IpV6OptionSmfDpd
{
internal const int TaggerIdMaxLength = 0xF + 1;
private static class Offset
{
public const int TaggerIdType = 0;
......@@ -138,7 +140,6 @@ namespace PcapDotNet.Packets.IpV6
{
return other != null &&
Identifier.Equals(other.Identifier) && TaggerIdType == other.TaggerIdType && EqualsTaggerId(other);
}
}
}
\ No newline at end of file
......@@ -158,7 +158,7 @@ namespace PcapDotNet.Packets.IpV6
public IpV6MobilityOptionBindingRefreshAdvice(ushort refreshInterval)
: base(IpV6MobilityOptionType.BindingRefreshAdvice)
{
refreshInterval = refreshInterval;
RefreshInterval = refreshInterval;
}
/// <summary>
......@@ -2634,7 +2634,7 @@ namespace PcapDotNet.Packets.IpV6
public const int RefreshTime = UdpEncapsulationRequired + sizeof(ushort);
}
public const int OptionDataLength = Offset.RefreshTime + sizeof(ushort);
public const int OptionDataLength = Offset.RefreshTime + sizeof(uint);
private static class Mask
{
......@@ -3602,7 +3602,7 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+-----------------------+
/// </pre>
/// </summary>
public class IpV6MobilityOptionContextRequestEntry
public sealed class IpV6MobilityOptionContextRequestEntry : IEquatable<IpV6MobilityOptionContextRequestEntry>
{
public IpV6MobilityOptionContextRequestEntry(byte requestType, DataSegment option)
{
......@@ -3644,6 +3644,16 @@ namespace PcapDotNet.Packets.IpV6
buffer.Write(ref offset, OptionLength);
Option.Write(buffer, ref offset);
}
public bool Equals(IpV6MobilityOptionContextRequestEntry other)
{
return (other != null && RequestType.Equals(other.RequestType) && Option.Equals(other.Option));
}
public override bool Equals(object obj)
{
return Equals(obj as IpV6MobilityOptionContextRequestEntry);
}
}
/// <summary>
......@@ -3679,6 +3689,8 @@ namespace PcapDotNet.Packets.IpV6
{
Requests = requests;
_dataLength = Requests.Sum(request => request.Length);
if (_dataLength > byte.MaxValue)
throw new ArgumentOutOfRangeException("requests", requests, string.Format("requests length is too large. Takes over {0}>{1} bytes.", _dataLength, byte.MaxValue));
}
/// <summary>
......@@ -4782,6 +4794,12 @@ namespace PcapDotNet.Packets.IpV6
IpV6FlowIdentificationSubOptions subOptions)
: base(IpV6MobilityOptionType.FlowIdentification)
{
if (Offset.SubOptions + subOptions.BytesLength > byte.MaxValue)
{
throw new ArgumentOutOfRangeException("subOptions", subOptions,
string.Format("Sub Options take {0} bytes, which is more than the maximum length of {1} bytes",
subOptions.BytesLength, (byte.MaxValue - Offset.SubOptions)));
}
FlowIdentifier = flowIdentifier;
Priority = priority;
Status = status;
......@@ -5116,10 +5134,10 @@ namespace PcapDotNet.Packets.IpV6
return null;
ushort priority = data.ReadUShort(Offset.Priority, Endianity.Big);
uint sessionsInUse = data.ReadUShort(Offset.SessionsInUse, Endianity.Big);
uint maximumSessions = data.ReadUShort(Offset.MaximumSessions, Endianity.Big);
uint usedCapacity = data.ReadUShort(Offset.UsedCapacity, Endianity.Big);
uint maximumCapacity = data.ReadUShort(Offset.MaximumCapacity, Endianity.Big);
uint sessionsInUse = data.ReadUInt(Offset.SessionsInUse, Endianity.Big);
uint maximumSessions = data.ReadUInt(Offset.MaximumSessions, Endianity.Big);
uint usedCapacity = data.ReadUInt(Offset.UsedCapacity, Endianity.Big);
uint maximumCapacity = data.ReadUInt(Offset.MaximumCapacity, Endianity.Big);
return new IpV6MobilityOptionLoadInformation(priority, sessionsInUse, maximumSessions, usedCapacity, maximumCapacity);
}
......@@ -5423,6 +5441,8 @@ namespace PcapDotNet.Packets.IpV6
public IpV6MobilityOptionAccessNetworkIdentifier(IpV6AccessNetworkIdentifierSubOptions subOptions)
: base(IpV6MobilityOptionType.AccessNetworkIdentifier)
{
if (subOptions.BytesLength > MaxDataLength)
throw new ArgumentOutOfRangeException("subOptions", subOptions, string.Format("SubOptions take more than {0} bytes", MaxDataLength));
SubOptions = subOptions;
}
......@@ -5650,6 +5670,9 @@ namespace PcapDotNet.Packets.IpV6
internal override void Write(byte[] buffer, ref int offset)
{
buffer[offset++] = (byte)OptionType;
// TODO: Remove this check.
if (DataLength > byte.MaxValue)
throw new InvalidOperationException("Option length is too long.");
buffer[offset++] = (byte)DataLength;
WriteData(buffer, ref offset);
}
......@@ -5701,6 +5724,11 @@ namespace PcapDotNet.Packets.IpV6
public IpV6AccessNetworkIdentifierSubOptionNetworkIdentifier(bool isNetworkNameUtf8, DataSegment networkName, DataSegment accessPointName)
: base(IpV6AccessNetworkIdentifierSubOptionType.NetworkIdentifier)
{
if (networkName.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("networkName", networkName, string.Format("Network Name cannot be longer than {0} bytes.", byte.MaxValue));
if (accessPointName.Length > byte.MaxValue)
throw new ArgumentOutOfRangeException("accessPointName", accessPointName, string.Format("Access Point Name cannot be longer than {0} bytes.", byte.MaxValue));
IsNetworkNameUtf8 = isNetworkNameUtf8;
NetworkName = networkName;
AccessPointName = accessPointName;
......@@ -5774,7 +5802,7 @@ namespace PcapDotNet.Packets.IpV6
if (IsNetworkNameUtf8)
buffer.Write(offset + Offset.IsNetworkNameUtf8, Mask.IsNetworkNameUtf8);
buffer.Write(offset + Offset.NetworkNameLength, (byte)NetworkName.Length);
NetworkName.Write(buffer, offset + Offset.NetworkNameLength);
NetworkName.Write(buffer, offset + Offset.NetworkName);
buffer.Write(offset + AccessPointNameLengthOffset, (byte)AccessPointName.Length);
AccessPointName.Write(buffer, offset + AccessPointNameOffset);
offset += DataLength;
......
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