Skip to content

Commit

Permalink
WinDivertPacket增加ApplyLengthToIPHeader()方法
Browse files Browse the repository at this point in the history
  • Loading branch information
xljiulang committed Oct 19, 2022
1 parent 3cb9a81 commit b5c72ca
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 14 deletions.
112 changes: 112 additions & 0 deletions WindivertDotnet.Test/WinDivertPacketTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Net;
using System.Net.Sockets;
using Xunit;

namespace WindivertDotnet.Test
{
public class WinDivertPacketTest
{
[Fact]
public void CtorTest()
{
using var packet = new WinDivertPacket(10);
Assert.Equal(10, packet.Capacity);
Assert.Equal(0, packet.Length);
Assert.Equal(0, packet.Span.Length);
}

[Fact]
public void LengthTest()
{
using var packet = new WinDivertPacket(10);
packet.Length = 5;
Assert.Equal(10, packet.Capacity);
Assert.Equal(5, packet.Length);
Assert.Equal(5, packet.Span.Length);

Assert.Throws<ArgumentOutOfRangeException>(() => packet.Length = 12);
}

[Fact]
public void GetSpanTest()
{
using var packet = new WinDivertPacket(10);
packet.Length = 1;
Assert.Equal(0, packet.GetSpan(0, 10)[0]);
Assert.Throws<ArgumentOutOfRangeException>(() => packet.GetSpan(1, 10));
}

[Fact]
public unsafe void CalcNetworkIfIdxTest()
{
var router = new WinDivertRouter(IPAddress.Loopback);
using var addr = new WinDivertAddress();

using var packet = new WinDivertPacket();
var ipv4Header = CreateIPV4Header(router);
packet.GetWriter().Write(ipv4Header);

packet.CalcNetworkIfIdx(addr);
Assert.Equal(router.InterfaceIndex, addr.Network->IfIdx);
}

[Fact]
public void CalcLoopbackFlagTest()
{
var router = new WinDivertRouter(IPAddress.Loopback);
using var addr = new WinDivertAddress();

using var packet = new WinDivertPacket();
var ipv4Header = CreateIPV4Header(router);
packet.GetWriter().Write(ipv4Header);

packet.CalcLoopbackFlag(addr);
Assert.Equal(router.IsLoopback, addr.Flags.HasFlag(WinDivertAddressFlag.Loopback));
}


[Fact]
public void CalcOutboundFlagTest()
{
var router = new WinDivertRouter(IPAddress.Loopback);
using var addr = new WinDivertAddress();

using var packet = new WinDivertPacket();
var ipv4Header = CreateIPV4Header(router);
packet.GetWriter().Write(ipv4Header);

packet.CalcOutboundFlag(addr);
Assert.Equal(router.IsOutbound, addr.Flags.HasFlag(WinDivertAddressFlag.Outbound));
}

[Fact]
public unsafe void ApplyLengthToIPHeaderTest()
{
var router = new WinDivertRouter(IPAddress.Loopback);
using var packet = new WinDivertPacket();

var ipv4Header = CreateIPV4Header(router);
ipv4Header.Length = 0;
packet.GetWriter().Write(ipv4Header);

packet.ApplyLengthToIPHeader();
var result = packet.GetParseResult();

Assert.Equal(sizeof(IPV4Header), result.IPV4Header->Length);
}

private static IPV4Header CreateIPV4Header(WinDivertRouter router)
{
return new IPV4Header
{
Version = 4,
HdrLength = 5,
Length = 20,
Protocol = ProtocolType.IP,
SrcAddr = router.SrcAddress,
DstAddr = router.DstAddress
};
}
}
}
59 changes: 45 additions & 14 deletions WindivertDotnet/WinDivertPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

Expand Down Expand Up @@ -83,17 +84,6 @@ public void Clear()
this.Span.Clear();
}

/// <summary>
/// 获取缓冲区的Writer对象
/// 该对象在写入数据后自动影响Length属性
/// </summary>
/// <param name="offset">偏移量</param>
/// <returns></returns>
public WindivertBufferWriter GetWriter(int offset = 0)
{
return new WindivertBufferWriter(this, offset);
}

/// <summary>
/// 获取缓冲区的Span
/// </summary>
Expand Down Expand Up @@ -211,18 +201,20 @@ private unsafe bool TryParseIPAddress(
{
if (this.length > 1)
{
var version = this.Span[0] >> 4;
var ptr = this.handle.ToPointer();
var version = Unsafe.Read<byte>(ptr) >> 4;

if (version == 4 && this.length >= sizeof(IPV4Header))
{
var header = (IPV4Header*)this.handle.ToPointer();
var header = (IPV4Header*)ptr;
srcAddr = header->SrcAddr;
dstAddr = header->DstAddr;
return true;
}

if (version == 6 && this.length >= sizeof(IPV6Header))
{
var header = (IPV6Header*)this.handle.ToPointer();
var header = (IPV6Header*)ptr;
srcAddr = header->SrcAddr;
dstAddr = header->DstAddr;
return true;
Expand All @@ -234,6 +226,34 @@ private unsafe bool TryParseIPAddress(
return false;
}

/// <summary>
/// 将属性Length值应用到IPHeader
/// 当包的负载数据长度变化后使用此方法很方便
/// </summary>
/// <returns></returns>
public unsafe bool ApplyLengthToIPHeader()
{
if (this.length > 1)
{
var ptr = this.handle.ToPointer();
var version = Unsafe.Read<byte>(ptr) >> 4;

if (version == 4 && this.length >= sizeof(IPV4Header))
{
((IPV4Header*)ptr)->Length = (ushort)this.length;
return true;
}

if (version == 6 && this.length >= sizeof(IPV6Header))
{
((IPV6Header*)ptr)->Length = (ushort)(this.length - sizeof(IPV6Header));
return true;
}
}

return false;
}

/// <summary>
/// ttl减1
/// </summary>
Expand Down Expand Up @@ -265,6 +285,17 @@ public int GetHashCode(long seed)
return WinDivertNative.WinDivertHelperHashPacket(this, this.length, seed);
}

/// <summary>
/// 获取缓冲区的Writer对象
/// 该对象在写入数据后自动影响Length属性
/// </summary>
/// <param name="offset">偏移量</param>
/// <returns></returns>
public WindivertBufferWriter GetWriter(int offset = 0)
{
return new WindivertBufferWriter(this, offset);
}

/// <summary>
/// 获取包的解析结果
/// </summary>
Expand Down

0 comments on commit b5c72ca

Please sign in to comment.