diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index f75d543b..f8c674ca 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -238,6 +238,7 @@ "Parse TCP", "Parse TLS record", "Parse UDP", + "Strip UDP header", "Parse SSH Host Key", "Parse URI", "URL Encode", diff --git a/src/core/operations/StripUDPHeader.mjs b/src/core/operations/StripUDPHeader.mjs new file mode 100644 index 00000000..0847c58f --- /dev/null +++ b/src/core/operations/StripUDPHeader.mjs @@ -0,0 +1,51 @@ +/** + * @author c65722 [] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Stream from "../lib/Stream.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * Strip UDP header operation + */ +class StripUDPHeader extends Operation { + + /** + * StripUDPHeader constructor + */ + constructor() { + super(); + + this.name = "Strip UDP header"; + this.module = "Default"; + this.description = "Strips the UDP header from a UDP datagram, outputting the payload."; + this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + const HEADER_LEN = 8; + + const s = new Stream(new Uint8Array(input)); + if (s.length < HEADER_LEN) { + throw new OperationError("Need 8 bytes for a UDP Header"); + } + + s.moveTo(HEADER_LEN); + + return s.getBytes().buffer; + } + +} + +export default StripUDPHeader; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 40b510a0..3d3fcda1 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -143,6 +143,7 @@ import "./tests/SIGABA.mjs"; import "./tests/SM4.mjs"; // import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet import "./tests/StrUtils.mjs"; +import "./tests/StripUDPHeader.mjs"; import "./tests/Subsection.mjs"; import "./tests/SwapCase.mjs"; import "./tests/SymmetricDifference.mjs"; diff --git a/tests/operations/tests/StripUDPHeader.mjs b/tests/operations/tests/StripUDPHeader.mjs new file mode 100644 index 00000000..d753ec50 --- /dev/null +++ b/tests/operations/tests/StripUDPHeader.mjs @@ -0,0 +1,69 @@ +/** + * Strip UDP header tests. + * + * @author c65722 [] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Strip UDP header: No payload", + input: "8111003500000000", + expectedOutput: "", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip UDP header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip UDP header: Payload", + input: "8111003500080000ffffffffffffffff", + expectedOutput: "ffffffffffffffff", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip UDP header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip UDP header: Input length less than header length", + input: "81110035000000", + expectedOutput: "Need 8 bytes for a UDP Header", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip UDP header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + } +]);