Commit 433ea023 authored by Brickner_cp's avatar Brickner_cp

VLanTaggedFrame

parent a9c94048
......@@ -62,7 +62,7 @@ namespace PcapDotNet.Packets.Test
Assert.IsTrue(packet.IsValid, "IsValid");
// Ethernet
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(ethernetSource, packet.Ethernet.Source, "Ethernet Source");
Assert.AreEqual(EthernetDatagram.BroadcastAddress, packet.Ethernet.Destination, "Ethernet Destination");
......
......@@ -1068,7 +1068,7 @@ namespace PcapDotNet.Packets.Test
byte[] buffer = new byte[packet.Length];
buffer.Write(0, packet.Ethernet);
const int dataLengthOffset =
EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + UdpDatagram.HeaderLength + DnsDatagram.HeaderLength + 5 + 4;
EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + UdpDatagram.HeaderLength + DnsDatagram.HeaderLength + 5 + 4;
ushort oldDataLength = buffer.ReadUShort(dataLengthOffset, Endianity.Big);
ushort newDataLength = (ushort)(oldDataLength + dataLengthDiff);
buffer.Write(dataLengthOffset, newDataLength, Endianity.Big);
......
......@@ -59,7 +59,7 @@ namespace PcapDotNet.Packets.Test
// Ethernet
Assert.IsTrue(new[] {EthernetType.IpV4, EthernetType.Arp}.Contains(packet.Ethernet.EtherType) ||
packet.IsValid, "IsValid - EtherType = " + packet.Ethernet.EtherType);
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer(), "Ethernet Layer");
Assert.AreEqual(ethernetLayer.GetHashCode(), packet.Ethernet.ExtractLayer().GetHashCode(), "Ethernet Layer Hash Code");
Assert.AreNotEqual(random.NextEthernetLayer().GetHashCode(), packet.Ethernet.ExtractLayer().GetHashCode(), "Ethernet Layer Hash Code");
......
......@@ -257,8 +257,8 @@ namespace PcapDotNet.Packets.Test
Assert.IsTrue(queryVersion3.IsValid, "IsValid");
buffer = new byte[queryVersion3.Length + 2];
queryVersion3.Buffer.BlockCopy(0, buffer, 0, queryVersion3.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
buffer[EthernetDatagram.HeaderLengthValue + 3] += 2;
buffer[EthernetDatagram.HeaderLengthValue + 11] -= 2;
Packet bigQueryVersion3 = new Packet(buffer, queryVersion3.Timestamp, queryVersion3.DataLink);
Assert.IsTrue(bigQueryVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigQueryVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect, "IpV4.IsHeaderChecksumCorrect");
......@@ -269,8 +269,8 @@ namespace PcapDotNet.Packets.Test
buffer = new byte[reportVersion1.Length + 2];
reportVersion1.Buffer.BlockCopy(0, buffer, 0, reportVersion1.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
buffer[EthernetDatagram.HeaderLengthValue + 3] += 2;
buffer[EthernetDatagram.HeaderLengthValue + 11] -= 2;
Packet bigReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink);
Assert.IsTrue(bigReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion1.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -279,8 +279,8 @@ namespace PcapDotNet.Packets.Test
// Non zero max response code for report version 1
buffer = new byte[reportVersion1.Length];
reportVersion1.Buffer.BlockCopy(0, buffer, 0, buffer.Length);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xedfe, Endianity.Big);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xedfe, Endianity.Big);
Packet nonZeroMaxResponseCodeReportVersion1 = new Packet(buffer, reportVersion1.Timestamp, reportVersion1.DataLink);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion1.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion1.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -295,8 +295,8 @@ namespace PcapDotNet.Packets.Test
buffer = new byte[reportVersion2.Length + 2];
reportVersion2.Buffer.BlockCopy(0, buffer, 0, reportVersion2.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
buffer[EthernetDatagram.HeaderLengthValue + 3] += 2;
buffer[EthernetDatagram.HeaderLengthValue + 11] -= 2;
Packet bigReportVersion2 = new Packet(buffer, reportVersion2.Timestamp, reportVersion2.DataLink);
Assert.IsTrue(bigReportVersion2.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion2.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -316,8 +316,8 @@ namespace PcapDotNet.Packets.Test
buffer = new byte[reportVersion3.Length];
reportVersion3.Buffer.BlockCopy(0, buffer, 0, buffer.Length);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
Packet nonZeroMaxResponseCodeReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(nonZeroMaxResponseCodeReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -326,8 +326,8 @@ namespace PcapDotNet.Packets.Test
// big report version 3
buffer = new byte[reportVersion3.Length + 2];
reportVersion3.Buffer.BlockCopy(0, buffer, 0, reportVersion3.Length);
buffer[EthernetDatagram.HeaderLength + 3] += 2;
buffer[EthernetDatagram.HeaderLength + 11] -= 2;
buffer[EthernetDatagram.HeaderLengthValue + 3] += 2;
buffer[EthernetDatagram.HeaderLengthValue + 11] -= 2;
Packet bigReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(bigReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(bigReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -336,8 +336,8 @@ namespace PcapDotNet.Packets.Test
// invalid group record report version 3
buffer = new byte[reportVersion3.Length];
reportVersion3.Buffer.BlockCopy(0, buffer, 0, reportVersion3.Length);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + IgmpDatagram.HeaderLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + IgmpDatagram.HeaderLength + 1, 1);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength + 2, (ushort)0xdbfd, Endianity.Big);
Packet invalidGroupRecordReportVersion3 = new Packet(buffer, reportVersion3.Timestamp, reportVersion3.DataLink);
Assert.IsTrue(invalidGroupRecordReportVersion3.Ethernet.IpV4.Igmp.IsChecksumCorrect);
Assert.IsTrue(invalidGroupRecordReportVersion3.Ethernet.IpV4.IsHeaderChecksumCorrect);
......@@ -355,7 +355,7 @@ namespace PcapDotNet.Packets.Test
byte[] buffer = new byte[packet.Length];
packet.Buffer.BlockCopy(0, buffer, 0, buffer.Length);
buffer.Write(EthernetDatagram.HeaderLength + IpV4Datagram.HeaderMinimumLength, 0);
buffer.Write(EthernetDatagram.HeaderLengthValue + IpV4Datagram.HeaderMinimumLength, 0);
Packet illegalPacket = new Packet(buffer, packet.Timestamp, packet.DataLink);
Assert.IsFalse(illegalPacket.IsValid);
Assert.IsNull(illegalPacket.Ethernet.IpV4.Igmp.Version);
......
......@@ -57,14 +57,14 @@ namespace PcapDotNet.Packets.Test
Assert.IsTrue(packet.IsValid);
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(new MacAddress("00:00:01:00:00:00"), packet.Ethernet.Source, "Ethernet Source");
Assert.AreEqual(new MacAddress("fe:ff:20:00:01:00"), packet.Ethernet.Destination, "Ethernet Destination");
Assert.AreEqual(EthernetType.IpV4, packet.Ethernet.EtherType, "Ethernet Type");
Assert.AreEqual(IpV4Datagram.HeaderMinimumLength, packet.Ethernet.IpV4.HeaderLength, "IP HeaderLength");
Assert.AreEqual(0, packet.Ethernet.IpV4.TypeOfService, "IP TypeOfService");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.IpV4.TotalLength, "IP TotalLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.IpV4.TotalLength, "IP TotalLength");
Assert.AreEqual(new IpV4Fragmentation(IpV4FragmentationOptions.DoNotFragment, 0), packet.Ethernet.IpV4.Fragmentation, "IP Fragmentation");
Assert.AreEqual(128, packet.Ethernet.IpV4.Ttl, "IP Ttl");
Assert.AreEqual(IpV4Protocol.Tcp, packet.Ethernet.IpV4.Protocol, "IP Protocol");
......@@ -108,7 +108,7 @@ namespace PcapDotNet.Packets.Test
packet.IsValid, "IsValid (" + ipV4Layer.Protocol + ")");
// Ethernet
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.PayloadLength, "PayloadLength");
Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer(), "Ethernet Layer");
// IpV4
......@@ -118,7 +118,7 @@ namespace PcapDotNet.Packets.Test
Assert.AreNotEqual(ipV4Layer, new PayloadLayer());
Assert.IsNotNull(ipV4Layer.ToString());
Assert.AreEqual(IpV4Datagram.HeaderMinimumLength + ipV4Layer.Options.BytesLength, packet.Ethernet.IpV4.HeaderLength, "IP HeaderLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.IpV4.TotalLength, "IP TotalLength");
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLengthValue, packet.Ethernet.IpV4.TotalLength, "IP TotalLength");
Assert.AreNotEqual(2, packet.Ethernet.IpV4.Fragmentation, "IP Fragmentation");
Assert.IsTrue(ipV4Layer.Fragmentation == packet.Ethernet.IpV4.Fragmentation, "IP Fragmentation");
Assert.IsFalse(ipV4Layer.Fragmentation != packet.Ethernet.IpV4.Fragmentation, "IP Fragmentation");
......
......@@ -33,8 +33,9 @@ namespace PcapDotNet.Packets.TestUtils
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, MacAddress ethernetSource, MacAddress ethernetDestination)
{
if (packetSize < EthernetDatagram.HeaderLength)
throw new ArgumentOutOfRangeException("packetSize", packetSize, "Must be at least the ethernet header length (" + EthernetDatagram.HeaderLength + ")");
if (packetSize < EthernetDatagram.HeaderLengthValue)
throw new ArgumentOutOfRangeException("packetSize", packetSize,
"Must be at least the ethernet header length (" + EthernetDatagram.HeaderLengthValue + ")");
return PacketBuilder.Build(timestamp,
new EthernetLayer
......@@ -43,7 +44,7 @@ namespace PcapDotNet.Packets.TestUtils
Destination = ethernetDestination,
EtherType = random.NextEthernetType()
},
random.NextPayloadLayer(packetSize - EthernetDatagram.HeaderLength));
random.NextPayloadLayer(packetSize - EthernetDatagram.HeaderLengthValue));
}
public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, string ethernetSource, string ethernetDestination)
......
using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Ethernet
{
public abstract class EthernetBaseDatagram : Datagram
{
/// <summary>
/// Ethernet type (next protocol).
/// </summary>
public abstract EthernetType EtherType { get; }
/// <summary>
/// Header length in bytes.
/// </summary>
public abstract int HeaderLength { get; }
/// <summary>
/// The Ethernet payload.
/// </summary>
public Datagram Payload
{
get { return PayloadDatagrams.Payload; }
}
/// <summary>
/// The bytes padding the Ethernet packet beyond the actual Ethernet payload.
/// This assumes we know how to calculate the actual payload length (For example, by using the Total Length of the IPv4 payload).
/// If we don't know how to calculate the actual payload length <see langword="null"/> will be returned.
/// The trailer doesn't include the <see cref="FrameCheckSequence"/> if it exists.
/// </summary>
public Datagram Trailer
{
get
{
Datagram payloadByEtherType = PayloadByEtherType;
if (payloadByEtherType == null)
return null;
int payloadLength = PayloadByEtherType.Length;
Datagram fcs = FrameCheckSequence;
return new Datagram(Buffer, HeaderLength + payloadLength, Length - HeaderLength - payloadLength - (fcs == null ? 0 : fcs.Length));
}
}
/// <summary>
/// The 4 bytes of the France Check Sequence (FCS).
/// Usually, these bytes won't be available because the device remvoed them after checking their validity.
/// We assume they exist when we see that the Ethernet padding pads to 68 bytes or more.
/// If the padding isn't that long or we don't know how to calculate the real payload length, <see langword="null"/> will be returned.
/// </summary>
public Datagram FrameCheckSequence
{
get
{
Datagram payloadByEtherType = PayloadByEtherType;
if (payloadByEtherType == null)
return null;
if (Length - HeaderLength - payloadByEtherType.Length >= 4 && Length >= 68)
return new Datagram(Buffer, Length - 4, 4);
return null;
}
}
/// <summary>
/// The Ethernet payload as an IPv4 datagram.
/// </summary>
public IpV4Datagram IpV4
{
get { return PayloadDatagrams.IpV4; }
}
/// <summary>
/// The Ethernet payload as an ARP datagram.
/// </summary>
public ArpDatagram Arp
{
get { return PayloadDatagrams.Arp; }
}
internal Datagram PayloadByEtherType
{
get { return PayloadDatagrams.Get(EtherType); }
}
internal EthernetBaseDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private EthernetPayloadDatagrams PayloadDatagrams
{
get
{
return _payloadDatagrams ?? (_payloadDatagrams = new EthernetPayloadDatagrams(Length >= HeaderLength
? new Datagram(Buffer, StartOffset + HeaderLength,
Length - HeaderLength)
: null));
}
}
private EthernetPayloadDatagrams _payloadDatagrams;
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Ethernet
{
......@@ -17,19 +15,24 @@ namespace PcapDotNet.Packets.Ethernet
/// +------+-------------------------------------------------+
/// </pre>
/// </summary>
public sealed class EthernetDatagram : Datagram
public sealed class EthernetDatagram : EthernetBaseDatagram
{
private static class Offset
{
public const int Destination = 0;
public const int Source = 6;
public const int EtherTypeLength = 12;
public const int Source = Destination + MacAddress.SizeOf;
public const int EtherTypeLength = Source + MacAddress.SizeOf;
}
/// <summary>
/// Ethernet header length in bytes.
/// </summary>
public const int HeaderLength = 14;
public const int HeaderLengthValue = Offset.EtherTypeLength + sizeof(ushort);
public override int HeaderLength
{
get { return HeaderLengthValue; }
}
/// <summary>
/// The broadcast MAC address (FF:FF:FF:FF:FF:FF).
......@@ -66,7 +69,7 @@ namespace PcapDotNet.Packets.Ethernet
/// <summary>
/// Ethernet type (next protocol).
/// </summary>
public EthernetType EtherType
public override EthernetType EtherType
{
get
{
......@@ -87,70 +90,6 @@ namespace PcapDotNet.Packets.Ethernet
};
}
/// <summary>
/// The Ethernet payload.
/// </summary>
public Datagram Payload
{
get { return PayloadDatagrams.Payload; }
}
/// <summary>
/// The bytes padding the Ethernet packet beyond the actual Ethernet payload.
/// This assumes we know how to calculate the actual payload length (For example, by using the Total Length of the IPv4 payload).
/// If we don't know how to calculate the actual payload length <see langword="null"/> will be returned.
/// The trailer doesn't include the <see cref="FrameCheckSequence"/> if it exists.
/// </summary>
public Datagram Trailer
{
get
{
Datagram payloadByEtherType = PayloadByEtherType;
if (payloadByEtherType == null)
return null;
int payloadLength = PayloadByEtherType.Length;
Datagram fcs = FrameCheckSequence;
return new Datagram(Buffer, HeaderLength + payloadLength, Length - HeaderLength - payloadLength - (fcs == null ? 0 : fcs.Length));
}
}
/// <summary>
/// The 4 bytes of the France Check Sequence (FCS).
/// Usually, these bytes won't be available because the device remvoed them after checking their validity.
/// We assume they exist when we see that the Ethernet padding pads to 68 bytes or more.
/// If the padding isn't that long or we don't know how to calculate the real payload length, <see langword="null"/> will be returned.
/// </summary>
public Datagram FrameCheckSequence
{
get
{
Datagram payloadByEtherType = PayloadByEtherType;
if (payloadByEtherType == null)
return null;
if (Length - HeaderLength - payloadByEtherType.Length >= 4 && Length >= 68)
return new Datagram(Buffer, Length - 4, 4);
return null;
}
}
/// <summary>
/// The Ethernet payload as an IPv4 datagram.
/// </summary>
public IpV4Datagram IpV4
{
get { return PayloadDatagrams.IpV4; }
}
/// <summary>
/// The Ethernet payload as an ARP datagram.
/// </summary>
public ArpDatagram Arp
{
get { return PayloadDatagrams.Arp; }
}
internal EthernetDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
......@@ -175,23 +114,6 @@ namespace PcapDotNet.Packets.Ethernet
return payloadByEtherType == null ? true : payloadByEtherType.IsValid;
}
private EthernetPayloadDatagrams PayloadDatagrams
{
get
{
return _payloadDatagrams ?? (_payloadDatagrams = new EthernetPayloadDatagrams(Length >= HeaderLength
? new Datagram(Buffer, StartOffset + HeaderLength,
Length - HeaderLength)
: null));
}
}
private Datagram PayloadByEtherType
{
get { return PayloadDatagrams.Get(EtherType); }
}
private static readonly MacAddress _broadcastAddress = new MacAddress("FF:FF:FF:FF:FF:FF");
private EthernetPayloadDatagrams _payloadDatagrams;
}
}
\ No newline at end of file
......@@ -40,7 +40,7 @@ namespace PcapDotNet.Packets.Ethernet
/// </summary>
public override int Length
{
get { return EthernetDatagram.HeaderLength; }
get { return EthernetDatagram.HeaderLengthValue; }
}
/// <summary>
......
......@@ -199,6 +199,7 @@
<Compile Include="Dns\ResourceData\DnsTypeBitmaps.cs" />
<Compile Include="Dns\ResourceData\DnsTypeRegistrationAttribute.cs" />
<Compile Include="Endianity.cs" />
<Compile Include="Ethernet\EthernetBaseDatagram.cs" />
<Compile Include="Ethernet\EthernetLayer.cs" />
<Compile Include="Ethernet\EthernetDatagram.cs" />
<Compile Include="Ethernet\EthernetPayloadDatagrams.cs" />
......@@ -393,6 +394,8 @@
<Compile Include="Transport\TransportDatagram.cs" />
<Compile Include="Transport\UdpDatagram.cs" />
<Compile Include="Transport\UdpLayer.cs" />
<Compile Include="VLanTaggedFrame\ClassOfService.cs" />
<Compile Include="VLanTaggedFrame\VLanTaggedFrameDatagram.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\PcapDotNet.snk" />
......
namespace PcapDotNet.Packets.VLanTaggedFrame
{
/// <summary>
/// IEEE P802.1p.
/// Eight different classes of service are available as expressed through the 3-bit PCP field in an IEEE 802.1Q header added to the frame.
/// The way traffic is treated when assigned to any particular class is undefined and left to the implementation.
/// </summary>
public enum ClassOfService : byte
{
/// <summary>
/// BE.
/// Best Effort.
/// </summary>
BestEffort = 0,
/// <summary>
/// BK.
/// Background.
/// Lowest.
/// </summary>
Background = 1,
/// <summary>
/// EE.
/// Excellent Effort.
/// </summary>
ExcellentEffort = 2,
/// <summary>
/// CA.
/// Critical Applications.
/// </summary>
CriticalApplications = 3,
/// <summary>
/// VI.
/// Video
/// Under 100 ms latency.
/// </summary>
Video = 4,
/// <summary>
/// VO.
/// Voice.
/// Under 10 ms latency.
/// </summary>
Voice = 5,
/// <summary>
/// IC.
/// Internetwork Control.
/// </summary>
InternetworkControl = 6,
/// <summary>
/// NC.
/// Network Control.
/// Highest.
/// </summary>
NetworkControl = 7,
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets.VLanTaggedFrame
{
/// <summary>
/// IEEE 802.1Q.
/// <pre>
/// +-----+-----+-----+------+------------------+
/// | bit | 0-2 | 3 | 4-15 | 16-31 |
/// +-----+-----+-----+------+------------------+
/// | 0 | TCI | EtherType/Length |
/// +-----+-----+-----+------+------------------+
/// | 0 | PCP | CFI | VID | EtherType/Length |
/// +-----+-----+-----+------+------------------+
/// </pre>
/// </summary>
public sealed class VLanTaggedFrameDatagram : EthernetBaseDatagram
{
private static class Offset
{
public const int PriorityCodePoint = 0;
public const int CanonicalFormatIndicator = PriorityCodePoint;
public const int VLanIdentifier = CanonicalFormatIndicator;
public const int EtherTypeLength = VLanIdentifier + sizeof(ushort);
}
/// <summary>
/// The number of bytes in the header takes.
/// </summary>
public const int HeaderLengthValue = Offset.EtherTypeLength + sizeof(ushort);
private static class Mask
{
public const byte PriorityCodePoint = 0xE0;
public const byte CanonicalFormatIndicator = 0x10;
public const ushort VLanIdentifier = 0x0FFF;
}
private static class Shift
{
public const int PriorityCodePoint = 5;
}
/// <summary>
/// The null VLAN ID.
/// Indicates that the tag header contains only priority information; no VLAN identifier is present in the frame.
/// This VID value shall not be configured as a PVID or a member of a VID Set, or configured in any Filtering Database entry,
/// or used in any Management operation.
/// </summary>
public const ushort NullVLanIdentifier = 0x000;
/// <summary>
/// The default PVID value used for classifying frames on ingress through a Bridge Port.
/// The PVID value of a Port can be changed by management.
/// </summary>
public const ushort DefaultPortVLanIdentifier = 0x001;
/// <summary>
/// Reserved for implementation use.
/// This VID value shall not be configured as a PVID or a member of a VID Set, or transmitted in a tag header.
/// This VID value may be used to indicate a wildcard match for the VID in management operations or Filtering Database entries.
/// </summary>
public const ushort MaxVLanIdentifier = 0xFFF;
/// <summary>
/// Header length in bytes.
/// </summary>
public override int HeaderLength
{
get { return HeaderLengthValue; }
}
/// <summary>
/// Indicates the frame priority level.
/// Values are from 0 (best effort) to 7 (highest); 1 represents the lowest priority.
/// These values can be used to prioritize different classes of traffic (voice, video, data, etc.).
/// </summary>
public ClassOfService PriorityCodePoint
{
get { return (ClassOfService)((this[Offset.PriorityCodePoint] & Mask.PriorityCodePoint) >> Shift.PriorityCodePoint); }
}
/// <summary>
/// If reset, all MAC Address information that may be present in the MSDU is in Canonical format and the tag comprises solely the TPID and TCI fields,
/// i.e., the tag does not contain an Embedded Routing Information Field (E-RIF).
/// </summary>
public bool CanonicalFormatIndicator
{
get { return ReadBool(Offset.CanonicalFormatIndicator, Mask.CanonicalFormatIndicator); }
}
/// <summary>
/// A VLAN-aware Bridge may not support the full range of VID values but shall support the use of all VID values in the range 0 through a maximum N,
/// less than or equal to 4094 and specified for that implementation.
/// </summary>
public ushort VLanIdentifier
{
get { return (ushort)(ReadUShort(Offset.VLanIdentifier, Endianity.Big) & Mask.VLanIdentifier); }
}
/// <summary>
/// Ethernet type (next protocol).
/// </summary>
public override EthernetType EtherType
{
get
{
return (EthernetType)ReadUShort(Offset.EtherTypeLength, Endianity.Big);
}
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
public override ILayer ExtractLayer()
{
return null;
// return new VLanTaggedFrameLayer()
// {
// };
}
/// <summary>
/// The datagram is valid if the length is correct according to the header.
/// </summary>
protected override bool CalculateIsValid()
{
return Length >= HeaderLength;
}
/*
internal static void WriteHeader(byte[] buffer, int offset,
ArpHardwareType hardwareType, EthernetType protocolType, ArpOperation operation,
IList<byte> senderHardwareAddress, IList<byte> senderProtocolAddress,
IList<byte> targetHardwareAddress, IList<byte> targetProtocolAddress)
{
buffer.Write(ref offset, (ushort)hardwareType, Endianity.Big);
buffer.Write(ref offset, (ushort)protocolType, Endianity.Big);
buffer.Write(ref offset, (byte)senderHardwareAddress.Count);
buffer.Write(ref offset, (byte)senderProtocolAddress.Count);
buffer.Write(ref offset, (ushort)operation, Endianity.Big);
buffer.Write(ref offset, senderHardwareAddress);
buffer.Write(ref offset, senderProtocolAddress);
buffer.Write(ref offset, targetHardwareAddress);
buffer.Write(ref offset, targetProtocolAddress);
}
*/
private VLanTaggedFrameDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ 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