Skip to content

Commit

Permalink
Merge pull request #12 from enclave-networks/develop
Browse files Browse the repository at this point in the history
Fix alignment of IPv4 fragmentation flags
  • Loading branch information
enclave-marc-barry authored Jan 24, 2025
2 parents 331a7b7 + 7e39fff commit 14df059
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
19 changes: 12 additions & 7 deletions src/Enclave.FastPacket/Ipv4.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,26 @@ namespace Enclave.FastPacket;
/// </summary>
[Flags]
public enum FragmentFlags
{
{
/// <summary>
/// None

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period

Check warning on line 15 in src/Enclave.FastPacket/Ipv4.cs

View workflow job for this annotation

GitHub Actions / build

Documentation text should end with a period
/// </summary>
None = 0, // When bit shifted, gives [000][0 0000 0000 0000] in binary

/// <summary>
/// Reserved, do not use.
/// More fragments (MF).
/// </summary>
Reserved = 0x01,

MoreFragments = 1, // When bit shifted, gives [001][0 0000 0000 0000] in binary

/// <summary>
/// Don't fragment (DF).
/// </summary>
DontFragment = 0x02,
DontFragment = 2, // When bit shifted, gives [010][0 0000 0000 0000] in binary

/// <summary>
/// More framgents (MF).
/// Reserved, do not use.
/// </summary>
MoreFragments = 0x04,
Reserved = 4, // When bit shifted, gives [100][0 0000 0000 0000] in binary
}

internal ref struct Ipv4Definition
Expand Down
6 changes: 3 additions & 3 deletions src/Enclave.FastPacket/ValueIpAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,10 @@ public BigInteger ToBigInteger()
{
Span<byte> destSpan = stackalloc byte[16];

BinaryPrimitives.WriteUInt64BigEndian(destSpan, _addr2);
BinaryPrimitives.WriteUInt64BigEndian(destSpan.Slice(sizeof(ulong)), _addr1);
BinaryPrimitives.WriteUInt64LittleEndian(destSpan, _addr1);
BinaryPrimitives.WriteUInt64LittleEndian(destSpan.Slice(sizeof(ulong)), _addr2);

return new BigInteger(destSpan, isUnsigned: true, isBigEndian: true);
return new BigInteger(destSpan, isUnsigned: true, isBigEndian: false);
}
else
{
Expand Down
34 changes: 33 additions & 1 deletion tests/Enclave.FastPacket.Tests/Ipv4Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void CanReadIpv4PacketWithUdpPayload()
var destIp = IPAddress.Parse("127.0.0.2");

var packet = new PacketDotNet.IPv4Packet(sourceIp, destIp);
packet.FragmentFlags = (byte)FragmentFlags.MoreFragments;
packet.FragmentFlags = (ushort)FragmentFlags.MoreFragments;
packet.FragmentOffset = 56;
packet.Id = 10;
packet.HopLimit = 15;
Expand Down Expand Up @@ -110,5 +110,37 @@ public void CanReadIpv4PacketWithIcmpPayload()

// 3 is the code for port unreachable.
icmp.Code.Should().Be(3);
}

[Theory]
[InlineData(IpProtocol.Udp, FragmentFlags.DontFragment)]
[InlineData(IpProtocol.Icmp, FragmentFlags.MoreFragments)]
[InlineData(IpProtocol.Icmp, FragmentFlags.Reserved)]
[InlineData(IpProtocol.Tcp, FragmentFlags.None)]
public void CanReadIpv4FragmentedPacket(IpProtocol protocol, FragmentFlags fragmentFlags)
{
var random = new Random();
var fragmentOffset = (ushort)random.Next(0, 8191); // (13 bits available for offset)
var sourceIp = IPAddress.Parse("10.0.0.1");
var destIp = IPAddress.Parse("127.0.0.2");

var packet = new IPv4Packet(sourceIp, destIp)
{
Id = (ushort)random.Next(0, ushort.MaxValue),
Protocol = (ProtocolType)protocol,
FragmentFlags = (ushort)fragmentFlags,
FragmentOffset = fragmentOffset
};

var packetData = packet.Bytes;

// Parse the packet
var myIp = new ReadOnlyIpv4PacketSpan(packetData);

myIp.Protocol.Should().Be(protocol);
myIp.Source.ToIpAddress().Should().Be(sourceIp);
myIp.Destination.ToIpAddress().Should().Be(destIp);
myIp.FragmentFlags.Should().Be(fragmentFlags);
myIp.FragmentOffset.Should().Be(fragmentOffset);
}
}

0 comments on commit 14df059

Please sign in to comment.