Skip to content

Commit

Permalink
Fix payload length calculation
Browse files Browse the repository at this point in the history
The length was incorrect when options/extensions were present
  • Loading branch information
hirsivaja committed Jan 5, 2024
1 parent 7e88f43 commit 833e65d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/main/java/com/github/hirsivaja/ip/ipv4/Ipv4Header.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,14 @@ public EcnCodePoint getEcn() {
return ecn;
}

public int getDataLength() {
public int getTotalLength() {
return Short.toUnsignedInt(len);
}

public int getPayloadLength() {
return getTotalLength() - Ipv4Header.HEADER_LEN - options.length;
}

public short getIdentification() {
return identification;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
public interface Ipv4Payload extends IpPayload {
static IpPayload decode(ByteBuffer in) {
Ipv4Header header = Ipv4Header.decode(in);
byte[] payload = new byte[header.getDataLength() - Ipv4Header.HEADER_LEN];
byte[] payload = new byte[header.getPayloadLength()];
in.get(payload);
ByteBuffer payloadBuffer = ByteBuffer.wrap(payload);
switch (header.getProtocol()) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/github/hirsivaja/ip/ipv6/Ipv6Header.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,12 @@ public int getFlowLabel() {
return flowLabel;
}

public int getTotalLength() {
return Short.toUnsignedInt(payloadLength) + HEADER_LEN;
}

public int getPayloadLength() {
return Short.toUnsignedInt(payloadLength);
return Short.toUnsignedInt(payloadLength) - getExtensionsLength();
}

public IpProtocol getNextHeader() {
Expand Down
16 changes: 15 additions & 1 deletion src/test/java/com/github/hirsivaja/ip/ipv4/Ipv4PayloadTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void codecTest() {
Assert.assertEquals(60, ((EncapsulationPayload) payload).getEncapsulatedPayload().getLength());
Assert.assertEquals(0, header.getDscp());
Assert.assertEquals(0, header.getEcn().getType());
Assert.assertEquals((short) 0x0050, header.getDataLength());
Assert.assertEquals((short) 0x0050, header.getTotalLength());
Assert.assertEquals((short) 0x935A, header.getIdentification());
Assert.assertEquals(0, header.getFlags().toByte());
Assert.assertEquals(0, header.getFragmentOffset());
Expand All @@ -35,6 +35,20 @@ public void codecTest() {
Assert.assertArrayEquals(ipv4Bytes, TestUtils.toBytes(payload));
}

@Test
public void optionsTest() {
byte[] ipv4Bytes = TestUtils.parseHexBinary("46000028000040000102D0FBC0A8071AE0000016940400002200F9020000000104000000E00000FB");
Assert.assertTrue(Ipv4Payload.isIpv4Payload(ByteBuffer.wrap(ipv4Bytes)));

IpPayload payload = Ipv4Payload.decode(ByteBuffer.wrap(ipv4Bytes));
Ipv4Header header = (Ipv4Header) payload.getHeader();

Assert.assertEquals(4, header.getOptions().length);
Assert.assertEquals(0x28, payload.getLength());

Assert.assertArrayEquals(ipv4Bytes, TestUtils.toBytes(payload));
}

@Test
public void tcpPayloadTest() {
byte[] ipv4Bytes = TestUtils.parseHexBinary("4500031F1D2540008006C8C5C0A8C887C0A8C8151EC407D06AF09F2E6F9B26E0501804027C66000020496E7465726E6574205374616E64617264732070726F63657373206D7573742062650A202020666F6C6C6F7765642C206F7220617320726571756972656420746F207472616E736C61746520697420696E746F206C616E677561676573206F74686572207468616E0A202020456E676C6973682E0A0A202020546865206C696D69746564207065726D697373696F6E73206772616E7465642061626F7665206172652070657270657475616C20616E642077696C6C206E6F742062650A2020207265766F6B65642062792074686520496E7465726E657420536F6369657479206F722069747320737563636573736F7273206F722061737369676E732E0A0A2020205468697320646F63756D656E7420616E642074686520696E666F726D6174696F6E20636F6E7461696E65642068657265696E2069732070726F7669646564206F6E20616E0A2020202241532049532220626173697320616E642054484520494E5445524E455420534F434945545920414E442054484520494E5445524E455420454E47494E454552494E470A2020205441534B20464F52434520444953434C41494D5320414C4C2057415252414E544945532C2045585052455353204F5220494D504C4945442C20494E434C5544494E470A202020425554204E4F54204C494D4954454420544F20414E592057415252414E545920544841542054484520555345204F462054484520494E464F524D4154494F4E0A20202048455245494E2057494C4C204E4F5420494E4652494E474520414E5920524947485453204F5220414E5920494D504C4945442057415252414E54494553204F460A2020204D45524348414E544142494C495459204F52204649544E45535320464F52204120504152544943554C415220505552504F53452E0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A576169747A6D616E202020202020202020202020202020202020202020204578706572696D656E74616C202020202020202020202020202020202020202020205B5061676520365D0A0C0A");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public void codecTest() {
Assert.assertEquals((byte) 0x00, header.getEcn().getType());
Assert.assertEquals(0x00, header.getFlowLabel());
Assert.assertEquals(0x0014, header.getPayloadLength());
Assert.assertEquals(0x003C, header.getTotalLength());
Assert.assertEquals(0x11, header.getNextHeader().getType());
Assert.assertEquals((byte) 0x04, header.getHopLimit());
Assert.assertEquals(0, header.getExtensionHeaders().size());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
package com.github.hirsivaja.ip.ipv6.extension;

import com.github.hirsivaja.ip.IpPayload;
import com.github.hirsivaja.ip.IpProtocol;
import com.github.hirsivaja.ip.TestUtils;
import com.github.hirsivaja.ip.ipv6.Ipv6Header;
import com.github.hirsivaja.ip.ipv6.Ipv6Payload;
import org.junit.Assert;
import org.junit.Test;

import java.nio.ByteBuffer;

public class ExtensionHeaderTest {
@Test
public void codecTest() {
byte[] ipv6Bytes = TestUtils.parseHexBinary("6E00000000240001FE80000000000000021562FFFE6AFEF0FF0200000000000000000000000000163A000502000001008F000D990000000104000000FF020000000000000000000000000002");
IpPayload payload = Ipv6Payload.decode(ByteBuffer.wrap(ipv6Bytes));

Assert.assertEquals(1, ((Ipv6Header) payload.getHeader()).getExtensionHeaders().size());
Assert.assertTrue(Ipv6Payload.isIpv6Payload(ByteBuffer.wrap(ipv6Bytes)));
Assert.assertArrayEquals(ipv6Bytes, TestUtils.toBytes(payload));
}

@Test
public void fragmentationTest() {
byte[] fragmentationBytes = TestUtils.parseHexBinary("3B00111112345678");
Expand Down

0 comments on commit 833e65d

Please sign in to comment.