Skip to content

Commit 9d014ae

Browse files
authored
Merge pull request #1898 from c65722/strip_tcp_header
Add Strip TCP header operation
2 parents 7ecc235 + 156de53 commit 9d014ae

File tree

4 files changed

+188
-0
lines changed

4 files changed

+188
-0
lines changed

Diff for: src/core/config/Categories.json

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@
236236
"Parse IPv6 address",
237237
"Parse IPv4 header",
238238
"Parse TCP",
239+
"Strip TCP header",
239240
"Parse TLS record",
240241
"Parse UDP",
241242
"Strip UDP header",

Diff for: src/core/operations/StripTCPHeader.mjs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @author c65722 []
3+
* @copyright Crown Copyright 2024
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import Stream from "../lib/Stream.mjs";
10+
11+
/**
12+
* Strip TCP header operation
13+
*/
14+
class StripTCPHeader extends Operation {
15+
16+
/**
17+
* StripTCPHeader constructor
18+
*/
19+
constructor() {
20+
super();
21+
22+
this.name = "Strip TCP header";
23+
this.module = "Default";
24+
this.description = "Strips the TCP header from a TCP segment, outputting the payload.";
25+
this.infoURL = "https://wikipedia.org/wiki/Transmission_Control_Protocol";
26+
this.inputType = "ArrayBuffer";
27+
this.outputType = "ArrayBuffer";
28+
this.args = [];
29+
}
30+
31+
/**
32+
* @param {ArrayBuffer} input
33+
* @param {Object[]} args
34+
* @returns {ArrayBuffer}
35+
*/
36+
run(input, args) {
37+
const MIN_HEADER_LEN = 20;
38+
const DATA_OFFSET_OFFSET = 12;
39+
const DATA_OFFSET_LEN_BITS = 4;
40+
41+
const s = new Stream(new Uint8Array(input));
42+
if (s.length < MIN_HEADER_LEN) {
43+
throw new OperationError("Need at least 20 bytes for a TCP Header");
44+
}
45+
46+
s.moveTo(DATA_OFFSET_OFFSET);
47+
const dataOffsetWords = s.readBits(DATA_OFFSET_LEN_BITS);
48+
const dataOffsetBytes = dataOffsetWords * 4;
49+
if (s.length < dataOffsetBytes) {
50+
throw new OperationError("Input length is less than data offset");
51+
}
52+
53+
s.moveTo(dataOffsetBytes);
54+
55+
return s.getBytes().buffer;
56+
}
57+
58+
}
59+
60+
export default StripTCPHeader;

Diff for: tests/operations/index.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ import "./tests/SIGABA.mjs";
143143
import "./tests/SM4.mjs";
144144
// import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet
145145
import "./tests/StrUtils.mjs";
146+
import "./tests/StripTCPHeader.mjs";
146147
import "./tests/StripUDPHeader.mjs";
147148
import "./tests/Subsection.mjs";
148149
import "./tests/SwapCase.mjs";

Diff for: tests/operations/tests/StripTCPHeader.mjs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* Strip TCP header tests.
3+
*
4+
* @author c65722 []
5+
* @copyright Crown Copyright 2024
6+
* @license Apache-2.0
7+
*/
8+
9+
import TestRegister from "../../lib/TestRegister.mjs";
10+
11+
TestRegister.addTests([
12+
{
13+
name: "Strip TCP header: No options, No payload",
14+
input: "7f900050000fa4b2000cb2a45010bff100000000",
15+
expectedOutput: "",
16+
recipeConfig: [
17+
{
18+
op: "From Hex",
19+
args: ["None"]
20+
},
21+
{
22+
op: "Strip TCP header",
23+
args: [],
24+
},
25+
{
26+
op: "To Hex",
27+
args: ["None", 0]
28+
}
29+
]
30+
},
31+
{
32+
name: "Strip TCP header: No options, Payload",
33+
input: "7f900050000fa4b2000cb2a45010bff100000000ffffffffffffffff",
34+
expectedOutput: "ffffffffffffffff",
35+
recipeConfig: [
36+
{
37+
op: "From Hex",
38+
args: ["None"]
39+
},
40+
{
41+
op: "Strip TCP header",
42+
args: [],
43+
},
44+
{
45+
op: "To Hex",
46+
args: ["None", 0]
47+
}
48+
]
49+
},
50+
{
51+
name: "Strip TCP header: Options, No payload",
52+
input: "7f900050000fa4b2000cb2a47010bff100000000020405b404020000",
53+
expectedOutput: "",
54+
recipeConfig: [
55+
{
56+
op: "From Hex",
57+
args: ["None"]
58+
},
59+
{
60+
op: "Strip TCP header",
61+
args: [],
62+
},
63+
{
64+
op: "To Hex",
65+
args: ["None", 0]
66+
}
67+
]
68+
},
69+
{
70+
name: "Strip TCP header: Options, Payload",
71+
input: "7f900050000fa4b2000cb2a47010bff100000000020405b404020000ffffffffffffffff",
72+
expectedOutput: "ffffffffffffffff",
73+
recipeConfig: [
74+
{
75+
op: "From Hex",
76+
args: ["None"]
77+
},
78+
{
79+
op: "Strip TCP header",
80+
args: [],
81+
},
82+
{
83+
op: "To Hex",
84+
args: ["None", 0]
85+
}
86+
]
87+
},
88+
{
89+
name: "Strip TCP header: Input length less than minimum header length",
90+
input: "7f900050000fa4b2000cb2a45010bff1000000",
91+
expectedOutput: "Need at least 20 bytes for a TCP Header",
92+
recipeConfig: [
93+
{
94+
op: "From Hex",
95+
args: ["None"]
96+
},
97+
{
98+
op: "Strip TCP header",
99+
args: [],
100+
},
101+
{
102+
op: "To Hex",
103+
args: ["None", 0]
104+
}
105+
]
106+
},
107+
{
108+
name: "Strip TCP header: Input length less than data offset",
109+
input: "7f900050000fa4b2000cb2a47010bff100000000",
110+
expectedOutput: "Input length is less than data offset",
111+
recipeConfig: [
112+
{
113+
op: "From Hex",
114+
args: ["None"]
115+
},
116+
{
117+
op: "Strip TCP header",
118+
args: [],
119+
},
120+
{
121+
op: "To Hex",
122+
args: ["None", 0]
123+
}
124+
]
125+
}
126+
]);

0 commit comments

Comments
 (0)