From 7f4f90e4f3c46180cfdf6d124040bb9f1d228337 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 08:44:28 +0000 Subject: [PATCH 1/8] chore (deps): bump core-js from 3.48.0 to 3.49.0 (#2261) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4035b7ff..67f2ef00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,7 +126,7 @@ "colors": "^1.4.0", "compression-webpack-plugin": "^11.1.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.48.0", + "core-js": "^3.49.0", "cspell": "^8.19.4", "css-loader": "7.1.4", "eslint": "^9.39.4", @@ -6813,9 +6813,9 @@ } }, "node_modules/core-js": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", - "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "dev": true, "hasInstallScript": true, "license": "MIT", diff --git a/package.json b/package.json index 868389b7..0c7b2160 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "colors": "^1.4.0", "compression-webpack-plugin": "^11.1.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.48.0", + "core-js": "^3.49.0", "cspell": "^8.19.4", "css-loader": "7.1.4", "eslint": "^9.39.4", From 290f824e18f16db2efab1b533c0914ee730b77bd Mon Sep 17 00:00:00 2001 From: Roman Karwacik <108284286+rtpt-romankarwacik@users.noreply.github.com> Date: Fri, 20 Mar 2026 10:26:39 +0100 Subject: [PATCH 2/8] feat: add Raw option for Jq operation (#2237) --- src/core/operations/Jq.mjs | 16 ++++++++++++---- tests/operations/tests/Jq.mjs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 tests/operations/tests/Jq.mjs diff --git a/src/core/operations/Jq.mjs b/src/core/operations/Jq.mjs index c1e02b34..bc502957 100644 --- a/src/core/operations/Jq.mjs +++ b/src/core/operations/Jq.mjs @@ -30,7 +30,12 @@ class Jq extends Operation { name: "Query", type: "string", value: "" - } + }, + { + name: "Raw", + type: "boolean", + value: false + }, ]; } @@ -40,7 +45,7 @@ class Jq extends Operation { * @returns {string} */ run(input, args) { - const [query] = args; + const [query, raw] = args; let result; try { @@ -48,8 +53,11 @@ class Jq extends Operation { } catch (err) { throw new OperationError(`Invalid jq expression: ${err.message}`); } - - return JSON.stringify(result); + if (raw && typeof result === "string") { + return result; + } else { + return JSON.stringify(result); + } } } diff --git a/tests/operations/tests/Jq.mjs b/tests/operations/tests/Jq.mjs new file mode 100644 index 00000000..a2435450 --- /dev/null +++ b/tests/operations/tests/Jq.mjs @@ -0,0 +1,32 @@ +/** + * Jq tests. + * + * @author rtpt-romankarwacik [roman.karwacik@redteam-pentesting.de] + * + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Get raw JSON Property", + input: '{"data": "testString\\u0000"}', + expectedOutput: "testString\u0000", + recipeConfig: [ + { + op: "Jq", + args: [".data", true], + }, + ], + }, + { + name: "Get JSON Property", + input: '{"data": "testString\\u0000"}', + expectedOutput: "\"testString\\u0000\"", + recipeConfig: [ + { + op: "Jq", + args: [".data", false], + }, + ], + }, +]); From 32ff3cd55ebbc9fd0ed2bce9887debd59c71f7fe Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:00:53 +0000 Subject: [PATCH 3/8] Bump flatted from 3.3.2 to 3.4.2 (#2266) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 67f2ef00..b03ab1f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9627,9 +9627,9 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, From a1f9208221a6f7df9eff08dfc612a3ff37997dfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:32:50 +0000 Subject: [PATCH 4/8] chore (deps): bump @codemirror/view from 6.39.17 to 6.40.0 (#2262) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index b03ab1f1..62705eb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -117,7 +117,7 @@ "@codemirror/language": "^6.12.2", "@codemirror/search": "^6.6.0", "@codemirror/state": "^6.5.4", - "@codemirror/view": "^6.39.17", + "@codemirror/view": "^6.40.0", "autoprefixer": "^10.4.27", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", @@ -1890,13 +1890,13 @@ } }, "node_modules/@codemirror/view": { - "version": "6.39.17", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.39.17.tgz", - "integrity": "sha512-Aim4lFqhbijnchl83RLfABWueSGs1oUCSv0mru91QdhpXQeNKprIdRO9LWA4cYkJvuYTKGJN7++9MXx8XW43ag==", + "version": "6.40.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.40.0.tgz", + "integrity": "sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg==", "dev": true, "license": "MIT", "dependencies": { - "@codemirror/state": "^6.5.0", + "@codemirror/state": "^6.6.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" diff --git a/package.json b/package.json index 0c7b2160..46464298 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@codemirror/language": "^6.12.2", "@codemirror/search": "^6.6.0", "@codemirror/state": "^6.5.4", - "@codemirror/view": "^6.39.17", + "@codemirror/view": "^6.40.0", "autoprefixer": "^10.4.27", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", From 8c4a55b2b18cc13205e03420e1f0bd4c0545c745 Mon Sep 17 00:00:00 2001 From: Cherry <35111165+Lamby777@users.noreply.github.com> Date: Fri, 20 Mar 2026 13:03:45 -0400 Subject: [PATCH 5/8] Add more helpful error for when numerical ingredient is left empty (#1540) Co-authored-by: GCHQ Developer C85297 <95289555+C85297@users.noreply.github.com> --- src/core/Chef.mjs | 9 ++++++++- src/core/Ingredient.mjs | 7 +++++-- src/core/Operation.mjs | 7 ++++++- src/core/Recipe.mjs | 14 +++++++++----- 4 files changed, 28 insertions(+), 9 deletions(-) mode change 100755 => 100644 src/core/Ingredient.mjs diff --git a/src/core/Chef.mjs b/src/core/Chef.mjs index ab8f83de..5be10868 100755 --- a/src/core/Chef.mjs +++ b/src/core/Chef.mjs @@ -55,8 +55,15 @@ class Chef { progress = await recipe.execute(this.dish, progress); } catch (err) { log.error(err); + + let displayStr; + if ("displayStr" in err) { + displayStr = err.displayStr; + } else { + displayStr = err.toString(); + } error = { - displayStr: err.displayStr, + displayStr: displayStr, }; progress = err.progress; } diff --git a/src/core/Ingredient.mjs b/src/core/Ingredient.mjs old mode 100755 new mode 100644 index 319dfb15..0dd31707 --- a/src/core/Ingredient.mjs +++ b/src/core/Ingredient.mjs @@ -5,7 +5,8 @@ */ import Utils from "./Utils.mjs"; -import {fromHex} from "./lib/Hex.mjs"; +import { fromHex } from "./lib/Hex.mjs"; +import OperationError from "./errors/OperationError.mjs"; /** * The arguments to operations. @@ -119,7 +120,9 @@ class Ingredient { number = parseFloat(data); if (isNaN(number)) { const sample = Utils.truncate(data.toString(), 10); - throw "Invalid ingredient value. Not a number: " + sample; + throw new OperationError( + "Invalid ingredient value. Not a number: " + sample, + ); } return number; default: diff --git a/src/core/Operation.mjs b/src/core/Operation.mjs index 24739d3f..09058766 100755 --- a/src/core/Operation.mjs +++ b/src/core/Operation.mjs @@ -5,6 +5,7 @@ */ import Dish from "./Dish.mjs"; +import OperationError from "./errors/OperationError.mjs"; import Ingredient from "./Ingredient.mjs"; /** @@ -223,7 +224,11 @@ class Operation { */ set ingValues(ingValues) { ingValues.forEach((val, i) => { - this._ingList[i].value = val; + try { + this._ingList[i].value = val; + } catch (err) { + throw new OperationError(`Failed to set value of ingredient '${this._ingList[i].name}': ${err}`); + } }); } diff --git a/src/core/Recipe.mjs b/src/core/Recipe.mjs index 7824d1e8..b4a10e03 100755 --- a/src/core/Recipe.mjs +++ b/src/core/Recipe.mjs @@ -70,11 +70,15 @@ class Recipe { if (o instanceof Operation) { return o; } else { - const op = new modules[o.module][o.name](); - op.ingValues = o.ingValues; - op.breakpoint = o.breakpoint; - op.disabled = o.disabled; - return op; + try { + const op = new modules[o.module][o.name](); + op.ingValues = o.ingValues; + op.breakpoint = o.breakpoint; + op.disabled = o.disabled; + return op; + } catch (err) { + throw new Error(`Failed to hydrate operation '${o.name}': ${err}`); + } } }); } From 38a0adaf33194644575af7b719c135d15f84a819 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:23:42 +0000 Subject: [PATCH 6/8] chore (deps): bump @babel/runtime from 7.28.6 to 7.29.2 (#2263) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62705eb7..607aeca3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -112,7 +112,7 @@ "@babel/plugin-syntax-import-assertions": "^7.28.6", "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.2", - "@babel/runtime": "^7.28.6", + "@babel/runtime": "^7.29.2", "@codemirror/commands": "^6.10.3", "@codemirror/language": "^6.12.2", "@codemirror/search": "^6.6.0", @@ -1754,9 +1754,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 46464298..4c188560 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@babel/plugin-syntax-import-assertions": "^7.28.6", "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.2", - "@babel/runtime": "^7.28.6", + "@babel/runtime": "^7.29.2", "@codemirror/commands": "^6.10.3", "@codemirror/language": "^6.12.2", "@codemirror/search": "^6.6.0", From 2b370b9616f14eacee5db15096dd69445ed0ef84 Mon Sep 17 00:00:00 2001 From: j264415 <128609898+j264415@users.noreply.github.com> Date: Sat, 21 Mar 2026 17:49:13 +0000 Subject: [PATCH 7/8] Selection and Deselection of autobake checkbox using keyboard (#1727) --- src/web/Manager.mjs | 1 + src/web/waiters/ControlsWaiter.mjs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index ae972a59..7cde638d 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -130,6 +130,7 @@ class Manager { // Controls document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls)); document.getElementById("auto-bake").addEventListener("change", this.controls.autoBakeChange.bind(this.controls)); + document.getElementById("auto-bake").addEventListener("keydown", this.controls.autoBakeKeyboardHandler.bind(this.controls)); document.getElementById("step").addEventListener("click", this.controls.stepClick.bind(this.controls)); document.getElementById("clr-recipe").addEventListener("click", this.controls.clearRecipeClick.bind(this.controls)); document.getElementById("save").addEventListener("click", this.controls.saveClick.bind(this.controls)); diff --git a/src/web/waiters/ControlsWaiter.mjs b/src/web/waiters/ControlsWaiter.mjs index b57940a3..d281fb89 100755 --- a/src/web/waiters/ControlsWaiter.mjs +++ b/src/web/waiters/ControlsWaiter.mjs @@ -57,6 +57,18 @@ class ControlsWaiter { } } + /** + * Checks or unchecks the Auto Bake checkbox with "Enter" + * @param {Event} ev + */ + autoBakeKeyboardHandler(ev) { + const checkBox = document.getElementById("auto-bake"); + ev.preventDefault(); + if (ev.key === "Enter" || ev.key === " ") { + checkBox.checked = !checkBox.checked; + } + } + /** * Handler to trigger baking. From 78d40eab60a46066e1d6bf5e50e7afa9432c162d Mon Sep 17 00:00:00 2001 From: Ted Kruijff Date: Sat, 21 Mar 2026 19:15:29 +0100 Subject: [PATCH 8/8] Add Parse Ethernet frame Operation, allow Parse IPv4 Header to cascade (#1722) --- src/core/config/Categories.json | 1 + src/core/operations/ParseEthernetFrame.mjs | 115 ++++++++++++++++++ src/core/operations/ParseIPv4Header.mjs | 29 ++++- tests/browser/02_ops.js | 2 +- tests/operations/index.mjs | 1 + tests/operations/tests/ParseEthernetFrame.mjs | 45 +++++++ 6 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 src/core/operations/ParseEthernetFrame.mjs create mode 100644 tests/operations/tests/ParseEthernetFrame.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 88cb6dc1..a2bd2d08 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -249,6 +249,7 @@ "DNS over HTTPS", "Strip HTTP headers", "Dechunk HTTP response", + "Parse Ethernet frame", "Parse User Agent", "Parse IP range", "Parse IPv6 address", diff --git a/src/core/operations/ParseEthernetFrame.mjs b/src/core/operations/ParseEthernetFrame.mjs new file mode 100644 index 00000000..9dac5d57 --- /dev/null +++ b/src/core/operations/ParseEthernetFrame.mjs @@ -0,0 +1,115 @@ +/** + * @author tedk [tedk@ted.do] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import Utils from "../Utils.mjs"; +import {fromHex, toHex} from "../lib/Hex.mjs"; + +/** + * Parse Ethernet frame operation + */ +class ParseEthernetFrame extends Operation { + + /** + * ParseEthernetFrame constructor + */ + constructor() { + super(); + + this.name = "Parse Ethernet frame"; + this.module = "Default"; + this.description = "Parses an Ethernet frame and either shows the deduced values (Source and destination MAC, VLANs) or returns the packet data.

Good for use in conjunction with the Parse IPv4, and Parse TCP/UDP recipes."; + this.infoURL = "https://en.wikipedia.org/wiki/Ethernet_frame#Frame_%E2%80%93_data_link_layer"; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + name: "Input type", + type: "option", + value: [ + "Raw", "Hex" + ], + defaultIndex: 0, + }, + { + name: "Return type", + type: "option", + value: [ + "Text output", "Packet data", "Packet data (hex)", + ], + defaultIndex: 0, + } + ]; + } + + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const format = args[0]; + const outputFormat = args[1]; + + if (format === "Hex") { + input = fromHex(input); + } else if (format === "Raw") { + input = new Uint8Array(Utils.strToArrayBuffer(input)); + } else { + throw new OperationError("Invalid input format selected."); + } + + const destinationMac = input.slice(0, 6); + const sourceMac = input.slice(6, 12); + + let offset = 12; + const vlans = []; + + while (offset < input.length) { + const ethType = Utils.byteArrayToChars(input.slice(offset, offset+2)); + offset += 2; + + + if (ethType === "\x08\x00") { + break; + } else if (ethType === "\x81\x00" || ethType === "\x88\xA8") { + // Parse the VLAN tag: + // [0000] 0000 0000 0000 + // ^^^ PRIO - Ignored + // ^ DEI - Ignored + // ^^^^ ^^^^ ^^^^ VLAN ID + const vlanTag = input.slice(offset+2, offset+4); + vlans.push((vlanTag[0] & 0b00001111) << 4 | vlanTag[1]); + + offset += 2; + } else { + break; + } + } + + const packetData = input.slice(offset); + + if (outputFormat === "Packet data") { + return Utils.byteArrayToChars(packetData); + } else if (outputFormat === "Packet data (hex)") { + return toHex(packetData); + } else if (outputFormat === "Text output") { + let retval = `Source MAC: ${toHex(sourceMac, ":")}\nDestination MAC: ${toHex(destinationMac, ":")}\n`; + if (vlans.length > 0) { + retval += `VLAN: ${vlans.join(", ")}\n`; + } + retval += `Data:\n${toHex(packetData)}`; + return retval; + } + + } + + +} + +export default ParseEthernetFrame; diff --git a/src/core/operations/ParseIPv4Header.mjs b/src/core/operations/ParseIPv4Header.mjs index 84351cdc..4eed5d46 100644 --- a/src/core/operations/ParseIPv4Header.mjs +++ b/src/core/operations/ParseIPv4Header.mjs @@ -33,6 +33,12 @@ class ParseIPv4Header extends Operation { "name": "Input format", "type": "option", "value": ["Hex", "Raw"] + }, + { + "name": "Output format", + "type": "option", + "value": ["Table", "Data (hex)", "Data (raw)"], + defaultIndex: 0, } ]; } @@ -44,6 +50,8 @@ class ParseIPv4Header extends Operation { */ run(input, args) { const format = args[0]; + const outputFormat = args[1]; + let output; if (format === "Hex") { @@ -98,7 +106,10 @@ class ParseIPv4Header extends Operation { checksumResult = givenChecksum + " (incorrect, should be " + correctChecksum + ")"; } - output = ` + const data = input.slice(ihl * 4); + + if (outputFormat === "Table") { + output = `
FieldValue
@@ -116,13 +127,19 @@ class ParseIPv4Header extends Operation { -`; + +`; - if (ihl > 5) { - output += ``; + if (ihl > 5) { + output += ``; + } + + return output + "
FieldValue
Version${version}
Internet Header Length (IHL)${ihl} (${ihl * 4} bytes)
Differentiated Services Code Point (DSCP)${dscp}
Protocol${protocol}, ${protocolInfo.protocol} (${protocolInfo.keyword})
Header checksum${checksumResult}
Source IP address${ipv4ToStr(srcIP)}
Destination IP address${ipv4ToStr(dstIP)}
Destination IP address${ipv4ToStr(dstIP)}
Data (hex)${toHex(data)}
Options${toHex(options)}
Options${toHex(options)}
"; + } else if (outputFormat === "Data (hex)") { + return toHex(data); + } else if (outputFormat === "Data (raw)") { + return Utils.byteArrayToChars(data); } - - return output + ""; } } diff --git a/tests/browser/02_ops.js b/tests/browser/02_ops.js index dde84f68..5ab55451 100644 --- a/tests/browser/02_ops.js +++ b/tests/browser/02_ops.js @@ -268,7 +268,7 @@ module.exports = { testOpHtml(browser, "Parse colour code", "#000", ".colorpicker-preview", "rgb(0, 0, 0)"); testOpHtml(browser, "Parse DateTime", "01/12/2000 13:00:00", "", /Date: Friday 1st December 2000/); // testOp(browser, "Parse IP range", "test input", "test_output"); - testOpHtml(browser, "Parse IPv4 header", "45 c0 00 c4 02 89 00 00 ff 11 1e 8c c0 a8 0c 01 c0 a8 0c 02", "tr:last-child td:last-child", "192.168.12.2"); + testOpHtml(browser, "Parse IPv4 header", "45 c0 00 c4 02 89 00 00 ff 11 1e 8c c0 a8 0c 01 c0 a8 0c 02", "tr:nth-last-child(2) td:last-child", "192.168.12.2"); // testOp(browser, "Parse IPv6 address", "test input", "test_output"); // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); // testOp(browser, "Parse QR Code", "test input", "test_output"); diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 2134cdd9..f030349d 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -122,6 +122,7 @@ import "./tests/NetBIOS.mjs"; import "./tests/NormaliseUnicode.mjs"; import "./tests/NTLM.mjs"; import "./tests/OTP.mjs"; +import "./tests/ParseEthernetFrame.mjs"; import "./tests/ParseIPRange.mjs"; import "./tests/ParseObjectIDTimestamp.mjs"; import "./tests/ParseQRCode.mjs"; diff --git a/tests/operations/tests/ParseEthernetFrame.mjs b/tests/operations/tests/ParseEthernetFrame.mjs new file mode 100644 index 00000000..c849e207 --- /dev/null +++ b/tests/operations/tests/ParseEthernetFrame.mjs @@ -0,0 +1,45 @@ +/** + * Parse Ethernet frame tests. + * + * @author tedk [tedk@ted.do] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Parse plain Ethernet frame", + input: "000000000000ffffffffffff08004500", + expectedOutput: "Source MAC: ff:ff:ff:ff:ff:ff\nDestination MAC: 00:00:00:00:00:00\nData:\n45 00", + recipeConfig: [ + { + "op": "Parse Ethernet frame", + "args": ["Hex", "Text output"] + } + ] + }, + // Example PCAP data from: https://packetlife.net/captures/protocol/vlan/ + { + name: "Parse Ethernet frame with one VLAN tag (802.1q)", + input: "01000ccdcdd00013c3dfae188100a0760165aaaa", + expectedOutput: "Source MAC: 00:13:c3:df:ae:18\nDestination MAC: 01:00:0c:cd:cd:d0\nVLAN: 117\nData:\naa aa", + recipeConfig: [ + { + "op": "Parse Ethernet frame", + "args": ["Hex", "Text output"] + } + ] + }, + { + name: "Parse Ethernet frame with two VLAN tags (802.1ad)", + input: "0019aa7de688002155c8f13c810000d18100001408004500", + expectedOutput: "Source MAC: 00:21:55:c8:f1:3c\nDestination MAC: 00:19:aa:7d:e6:88\nVLAN: 16, 128\nData:\n45 00", + recipeConfig: [ + { + "op": "Parse Ethernet frame", + "args": ["Hex", "Text output"] + } + ] + } +]);