Commit 07075fab authored by Brickner_cp's avatar Brickner_cp

VLanTaggedFrame

parent 9452bc0f
...@@ -8,7 +8,7 @@ using PcapDotNet.Packets.Transport; ...@@ -8,7 +8,7 @@ using PcapDotNet.Packets.Transport;
namespace PcapDotNet.Packets.Test namespace PcapDotNet.Packets.Test
{ {
/// <summary> /// <summary>
/// Summary description for EthernetTests /// Summary description for EthernetTests.
/// </summary> /// </summary>
[TestClass] [TestClass]
public class EthernetTests public class EthernetTests
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
<Compile Include="IpV4AddressTests.cs" /> <Compile Include="IpV4AddressTests.cs" />
<Compile Include="TcpTests.cs" /> <Compile Include="TcpTests.cs" />
<Compile Include="UdpTests.cs" /> <Compile Include="UdpTests.cs" />
<Compile Include="VLanTaggedFrameTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj"> <ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj">
......
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.TestUtils;
using PcapDotNet.Packets.Transport;
using PcapDotNet.Packets.VLanTaggedFrame;
namespace PcapDotNet.Packets.Test
{
/// <summary>
/// Summary description for VLanTaggedFrameTests.
/// </summary>
[TestClass]
public class VLanTaggedFrameTests
{
/// <summary>
/// Gets or sets the test context which provides
/// information about and functionality for the current test run.
/// </summary>
public TestContext TestContext { get; set; }
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void RandomVLanTaggedFrameTest()
{
Random random = new Random();
for (int i = 0; i != 1000; ++i)
{
EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
VLanTaggedFrameLayer vLanTaggedFrameLayer = random.NextVLanTaggedFrameLayer();
int payloadLength = random.Next(1500);
PayloadLayer payloadLayer = new PayloadLayer
{
Data = random.NextDatagram(payloadLength),
};
Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, vLanTaggedFrameLayer, payloadLayer);
ethernetLayer.EtherType = EthernetType.VLanTaggedFrame;
// Test equality.
Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer());
Assert.AreEqual(vLanTaggedFrameLayer, packet.Ethernet.VLanTaggedFrame.ExtractLayer());
Assert.AreEqual(payloadLayer.Data, packet.Ethernet.VLanTaggedFrame.Payload);
}
}
[TestMethod]
public void AutoSetEtherTypeTest()
{
Random random = new Random();
EthernetLayer ethernetLayer = random.NextEthernetLayer(EthernetType.None);
VLanTaggedFrameLayer vLanTaggedFrameLayer = random.NextVLanTaggedFrameLayer(EthernetType.None);
IpV4Layer ipV4Layer = random.NextIpV4Layer();
Packet packet = PacketBuilder.Build(DateTime.Now, ethernetLayer, vLanTaggedFrameLayer, ipV4Layer);
ethernetLayer.EtherType = EthernetType.VLanTaggedFrame;
vLanTaggedFrameLayer.EtherType = EthernetType.IpV4;
// Test equality.
Assert.AreEqual(ethernetLayer, packet.Ethernet.ExtractLayer());
Assert.AreEqual(EthernetType.IpV4, packet.Ethernet.VLanTaggedFrame.EtherType);
Assert.AreEqual(vLanTaggedFrameLayer, packet.Ethernet.VLanTaggedFrame.ExtractLayer());
Assert.AreEqual(ipV4Layer, packet.Ethernet.VLanTaggedFrame.IpV4.ExtractLayer());
}
}
}
\ No newline at end of file
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RandomTcpExtensions.cs" /> <Compile Include="RandomTcpExtensions.cs" />
<Compile Include="RandomUdpExtensions.cs" /> <Compile Include="RandomUdpExtensions.cs" />
<Compile Include="RandomVLanTaggedFrameExtensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj"> <ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj">
......
using System;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.VLanTaggedFrame;
using PcapDotNet.TestUtils;
namespace PcapDotNet.Packets.TestUtils
{
public static class RandomVLanTaggedFrameExtensions
{
public static VLanTaggedFrameLayer NextVLanTaggedFrameLayer(this Random random, EthernetType etherType)
{
return new VLanTaggedFrameLayer
{
PriorityCodePoint = random.NextEnum<ClassOfService>(),
CanonicalFormatIndicator = random.NextBool(),
VLanIdentifier = random.NextUShort(VLanTaggedFrameDatagram.MaxVLanIdentifier + 1),
EtherType = etherType,
};
}
public static VLanTaggedFrameLayer NextVLanTaggedFrameLayer(this Random random)
{
return random.NextVLanTaggedFrameLayer(random.NextEnum(EthernetType.None));
}
}
}
\ No newline at end of file
using PcapDotNet.Packets.Arp; using PcapDotNet.Packets.Arp;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.VLanTaggedFrame;
namespace PcapDotNet.Packets.Ethernet namespace PcapDotNet.Packets.Ethernet
{ {
...@@ -63,6 +64,11 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -63,6 +64,11 @@ namespace PcapDotNet.Packets.Ethernet
} }
} }
public VLanTaggedFrameDatagram VLanTaggedFrame
{
get { return PayloadDatagrams.VLanTaggedFrame; }
}
/// <summary> /// <summary>
/// The Ethernet payload as an IPv4 datagram. /// The Ethernet payload as an IPv4 datagram.
/// </summary> /// </summary>
......
...@@ -53,25 +53,17 @@ namespace PcapDotNet.Packets.Ethernet ...@@ -53,25 +53,17 @@ namespace PcapDotNet.Packets.Ethernet
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param> /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
EthernetType etherType = EtherType; EthernetType etherType = GetEthernetType(EtherType, nextLayer);
MacAddress destination = Destination; MacAddress destination = Destination;
IEthernetNextLayer ethernetNextLayer = nextLayer as IEthernetNextLayer; IEthernetNextLayer ethernetNextLayer = nextLayer as IEthernetNextLayer;
if (etherType == EthernetType.None)
{
if (nextLayer == null)
throw new ArgumentException("Can't determine ether type automatically from next layer because there is not next layer");
if (ethernetNextLayer == null)
throw new ArgumentException("Can't determine ether type automatically from next layer (" + nextLayer.GetType() + ")");
etherType = ethernetNextLayer.PreviousLayerEtherType;
}
if (destination == MacAddress.Zero) if (destination == MacAddress.Zero)
{ {
if (ethernetNextLayer != null && ethernetNextLayer.PreviousLayerDefaultDestination != null) if (ethernetNextLayer != null && ethernetNextLayer.PreviousLayerDefaultDestination != null)
destination = ethernetNextLayer.PreviousLayerDefaultDestination.Value; destination = ethernetNextLayer.PreviousLayerDefaultDestination.Value;
} }
EthernetDatagram.WriteHeader(buffer, 0, Source, destination, etherType); EthernetDatagram.WriteHeader(buffer, offset, Source, destination, etherType);
} }
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets
{ {
...@@ -69,5 +70,19 @@ namespace PcapDotNet.Packets ...@@ -69,5 +70,19 @@ namespace PcapDotNet.Packets
{ {
return Length.GetHashCode() ^ DataLink.GetHashCode(); return Length.GetHashCode() ^ DataLink.GetHashCode();
} }
internal static EthernetType GetEthernetType(EthernetType ethernetType, ILayer nextLayer)
{
if (ethernetType != EthernetType.None)
return ethernetType;
if (nextLayer == null)
throw new ArgumentException("Can't determine ether type automatically from next layer because there is not next layer");
IEthernetNextLayer ethernetNextLayer = nextLayer as IEthernetNextLayer;
if (ethernetNextLayer == null)
throw new ArgumentException("Can't determine ether type automatically from next layer (" + nextLayer.GetType() + ")");
return ethernetNextLayer.PreviousLayerEtherType;
}
} }
} }
\ No newline at end of file
...@@ -396,6 +396,7 @@ ...@@ -396,6 +396,7 @@
<Compile Include="Transport\UdpLayer.cs" /> <Compile Include="Transport\UdpLayer.cs" />
<Compile Include="VLanTaggedFrame\ClassOfService.cs" /> <Compile Include="VLanTaggedFrame\ClassOfService.cs" />
<Compile Include="VLanTaggedFrame\VLanTaggedFrameDatagram.cs" /> <Compile Include="VLanTaggedFrame\VLanTaggedFrameDatagram.cs" />
<Compile Include="VLanTaggedFrame\VLanTaggedFrameLayer.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\PcapDotNet.snk" /> <None Include="..\PcapDotNet.snk" />
......
using System; using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets.VLanTaggedFrame namespace PcapDotNet.Packets.VLanTaggedFrame
...@@ -99,6 +99,11 @@ namespace PcapDotNet.Packets.VLanTaggedFrame ...@@ -99,6 +99,11 @@ namespace PcapDotNet.Packets.VLanTaggedFrame
get { return (ushort)(ReadUShort(Offset.VLanIdentifier, Endianity.Big) & Mask.VLanIdentifier); } get { return (ushort)(ReadUShort(Offset.VLanIdentifier, Endianity.Big) & Mask.VLanIdentifier); }
} }
public ushort TagControlInformation
{
get { return CalculateTagControlInformation(PriorityCodePoint, CanonicalFormatIndicator, VLanIdentifier); }
}
/// <summary> /// <summary>
/// Ethernet type (next protocol). /// Ethernet type (next protocol).
/// </summary> /// </summary>
...@@ -115,10 +120,13 @@ namespace PcapDotNet.Packets.VLanTaggedFrame ...@@ -115,10 +120,13 @@ namespace PcapDotNet.Packets.VLanTaggedFrame
/// </summary> /// </summary>
public override ILayer ExtractLayer() public override ILayer ExtractLayer()
{ {
return null; return new VLanTaggedFrameLayer
// return new VLanTaggedFrameLayer() {
// { PriorityCodePoint = PriorityCodePoint,
// }; CanonicalFormatIndicator = CanonicalFormatIndicator,
VLanIdentifier = VLanIdentifier,
EtherType = EtherType,
};
} }
/// <summary> /// <summary>
...@@ -138,22 +146,18 @@ namespace PcapDotNet.Packets.VLanTaggedFrame ...@@ -138,22 +146,18 @@ namespace PcapDotNet.Packets.VLanTaggedFrame
{ {
} }
/* internal static void WriteHeader(byte[] buffer, int offset, ClassOfService priorityCodePoint, bool canonicalFormatIndicator, ushort vLanIdentifier, EthernetType etherType)
internal static void WriteHeader(byte[] buffer, int offset, {
ArpHardwareType hardwareType, EthernetType protocolType, ArpOperation operation, ushort tagControlInformation = CalculateTagControlInformation(priorityCodePoint, canonicalFormatIndicator, vLanIdentifier);
IList<byte> senderHardwareAddress, IList<byte> senderProtocolAddress, buffer.Write(offset + Offset.PriorityCodePoint, tagControlInformation, Endianity.Big);
IList<byte> targetHardwareAddress, IList<byte> targetProtocolAddress) buffer.Write(offset + Offset.EtherTypeLength, (ushort)etherType, Endianity.Big);
}
internal static ushort CalculateTagControlInformation(ClassOfService priorityCodePoint, bool canonicalFormatIndicator, ushort vLanIdentifier)
{ {
buffer.Write(ref offset, (ushort)hardwareType, Endianity.Big); return (ushort)(((((((byte)priorityCodePoint) << Shift.PriorityCodePoint) & Mask.PriorityCodePoint) |
buffer.Write(ref offset, (ushort)protocolType, Endianity.Big); (canonicalFormatIndicator ? Mask.CanonicalFormatIndicator : 0x00)) << 8) |
buffer.Write(ref offset, (byte)senderHardwareAddress.Count); (vLanIdentifier & Mask.VLanIdentifier));
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);
} }
*/
} }
} }
\ No newline at end of file
using System;
using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet;
namespace PcapDotNet.Packets.VLanTaggedFrame
{
public sealed class VLanTaggedFrameLayer : Layer, IEquatable<VLanTaggedFrameLayer>, IEthernetNextLayer
{
public VLanTaggedFrameLayer()
{
}
public ClassOfService PriorityCodePoint { get; set; }
public bool CanonicalFormatIndicator { get; set; }
public ushort VLanIdentifier { get; set; }
public ushort TagControlInformation
{
get { return VLanTaggedFrameDatagram.CalculateTagControlInformation(PriorityCodePoint, CanonicalFormatIndicator, VLanIdentifier); }
}
public EthernetType EtherType { get; set; }
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override int Length
{
get { return VLanTaggedFrameDatagram.HeaderLengthValue; }
}
/// <summary>
/// Writes the layer to the buffer.
/// </summary>
/// <param name="buffer">The buffer to write the layer to.</param>
/// <param name="offset">The offset in the buffer to start writing the layer at.</param>
/// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param>
/// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param>
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{
EthernetType etherType = GetEthernetType(EtherType, nextLayer);
VLanTaggedFrameDatagram.WriteHeader(buffer, offset, PriorityCodePoint, CanonicalFormatIndicator, VLanIdentifier, etherType);
}
public bool Equals(VLanTaggedFrameLayer other)
{
return other != null &&
PriorityCodePoint == other.PriorityCodePoint && CanonicalFormatIndicator == other.CanonicalFormatIndicator &&
VLanIdentifier == other.VLanIdentifier && EtherType == other.EtherType;
}
public override bool Equals(Layer other)
{
return Equals(other as VLanTaggedFrameLayer);
}
public override int GetHashCode()
{
return base.GetHashCode() ^
BitSequence.Merge(TagControlInformation, (ushort)EtherType).GetHashCode();
}
public EthernetType PreviousLayerEtherType
{
get { return EthernetType.VLanTaggedFrame; }
}
public MacAddress? PreviousLayerDefaultDestination
{
get { return null; }
}
}
}
\ 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