frameassembly-wasm 1.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -26
- package/frameassembly_wasm.d.ts +16 -3
- package/frameassembly_wasm.js +23 -4
- package/frameassembly_wasm_bg.wasm +0 -0
- package/package.json +19 -4
package/README.md
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
# FrameAssembly WebAssembly Compiler (`frameassembly-wasm`
|
|
1
|
+
# FrameAssembly WebAssembly Compiler (`frameassembly-wasm` v2.0.0)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://frameassembly.ai.studio/)
|
|
4
|
+
[](https://www.npmjs.com/package/frameassembly-wasm)
|
|
5
|
+
[](https://github.com/SteveWinschel/FrameAssembly/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
[**Try in Browser (`frameassembly.ai.studio`)**](https://frameassembly.ai.studio/) • [**Installation**](#installation) • [**Vite, React & Next.js**](#initialization-vite-react-nextjs--google-ai-studio) • [**API Reference**](#api-reference)
|
|
8
|
+
|
|
9
|
+
WebAssembly compiler, `.pcap`/`.pcapng`-to-`.fasm` decompiler, packet ladder inspector, and UTF-16 IDE diagnostics for **FrameAssembly (`.fasm` v2.0.0)** — compiling `.fasm` code into `.pcapng` packet captures and decompiling existing captures back into `.fasm` code across 81 L2–L7 protocols in browser applications, VS Code Desktop & Web extensions, web cyber ranges, and Node.js test suites. Powers the official FrameAssembly interactive browser playground at [**frameassembly.ai.studio**](https://frameassembly.ai.studio/) and the official VS Code extension (`SteveWinschel.frameassembly-vscode`). *(Note: FrameAssembly is a network packet specification compiler, not x86 Flat Assembler).*
|
|
4
10
|
|
|
5
11
|
---
|
|
6
12
|
|
|
7
13
|
## Client-Side `.fasm` to `.pcapng` Compilation & PCAP Decompilation in the Browser & Node.js
|
|
8
14
|
|
|
9
|
-
`frameassembly-wasm` compiles the FrameAssembly Rust engine to WebAssembly, turning `.fasm` code into `.pcapng` byte streams, decompiling binary `.pcap` and `.pcapng` captures into `.fasm` code via `reversePcap(pcapBytes)`, and emitting real-time Monaco
|
|
15
|
+
`frameassembly-wasm` compiles the FrameAssembly Rust engine to WebAssembly, turning `.fasm` code into `.pcapng` byte streams, decompiling binary `.pcap` and `.pcapng` captures into strict-lowercase `.fasm` code via `reverse_pcap(pcapBytes)` / `reversePcap(pcapBytes)`, and emitting real-time Monaco, CodeMirror, and VS Code diagnostics directly in the browser or Node.js without a backend server:
|
|
10
16
|
|
|
11
17
|
```frameassembly
|
|
12
18
|
host client { ip 192.168.1.10 mac 00:11:22:33:44:55 }
|
|
13
19
|
host server { ip 8.8.8.8 mac aa:bb:cc:dd:ee:ff }
|
|
14
20
|
|
|
15
21
|
flow dns_query(c, s) {
|
|
16
|
-
c -> s dns query txid 0x1234 qname "example.com" qtype "
|
|
17
|
-
c <- s dns response txid 0x1234 qname "example.com" qtype "
|
|
22
|
+
c -> s dns query txid 0x1234 qname "example.com" qtype "a" wait 1ms
|
|
23
|
+
c <- s dns response txid 0x1234 qname "example.com" qtype "a" rdata 93.184.216.34 wait 1ms
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
compile {
|
|
@@ -37,27 +43,27 @@ const source = `host client { ip 192.168.1.10 mac 00:11:22:33:44:55 }
|
|
|
37
43
|
host server { ip 8.8.8.8 mac aa:bb:cc:dd:ee:ff }
|
|
38
44
|
|
|
39
45
|
flow dns_query(c, s) {
|
|
40
|
-
c -> s dns query txid 0x1234 qname "example.com" qtype "
|
|
41
|
-
c <- s dns response txid 0x1234 qname "example.com" qtype "
|
|
46
|
+
c -> s dns query txid 0x1234 qname "example.com" qtype "a" wait 1ms
|
|
47
|
+
c <- s dns response txid 0x1234 qname "example.com" qtype "a" rdata 93.184.216.34 wait 1ms
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
compile {
|
|
45
51
|
dns_query(client, server)
|
|
46
52
|
}`;
|
|
47
53
|
|
|
48
|
-
// 1. Validate syntax & semantics for Monaco / CodeMirror editor markers
|
|
54
|
+
// 1. Validate syntax & semantics for Monaco / CodeMirror / VS Code editor markers
|
|
49
55
|
const diagnostics = validate_fasm(source);
|
|
50
56
|
if (diagnostics.length === 0) {
|
|
51
|
-
// 2. Inspect individual packet
|
|
57
|
+
// 2. Inspect individual packet ladder rows, protocol labels, summaries, and hex payloads
|
|
52
58
|
const previews = inspect_fasm(source);
|
|
53
|
-
console.log(`Synthesized ${previews.length} frames.`);
|
|
59
|
+
console.log(`Synthesized ${previews.length} frames (${previews[0].protocol}: ${previews[0].summary}).`);
|
|
54
60
|
|
|
55
61
|
// 3. Compile to binary PCAPNG Uint8Array
|
|
56
62
|
const pcapngBytes = compile_fasm_to_pcapng(source);
|
|
57
63
|
const blob = new Blob([pcapngBytes], { type: "application/vnd.tcpdump.pcap" });
|
|
58
64
|
console.log(`Generated PCAPNG: ${blob.size} bytes`);
|
|
59
65
|
|
|
60
|
-
// 4. Decompile binary PCAP/PCAPNG bytes back into
|
|
66
|
+
// 4. Decompile binary PCAP/PCAPNG bytes back into strict-lowercase .fasm code
|
|
61
67
|
const reversed = reversePcap(pcapngBytes);
|
|
62
68
|
console.log(`Reversed ${reversed.packetCount} frames across ${reversed.hostCount} hosts:\n${reversed.fasm}`);
|
|
63
69
|
}
|
|
@@ -84,10 +90,10 @@ npm install frameassembly-wasm
|
|
|
84
90
|
inspect_fasm,
|
|
85
91
|
compile_fasm_to_pcapng,
|
|
86
92
|
reversePcap,
|
|
87
|
-
} from "https://cdn.jsdelivr.net/npm/frameassembly-wasm@
|
|
93
|
+
} from "https://cdn.jsdelivr.net/npm/frameassembly-wasm@2.0.0/frameassembly_wasm.js";
|
|
88
94
|
|
|
89
95
|
await init();
|
|
90
|
-
console.log("FrameAssembly WebAssembly engine
|
|
96
|
+
console.log("FrameAssembly WebAssembly engine v2.0.0 loaded successfully.");
|
|
91
97
|
</script>
|
|
92
98
|
```
|
|
93
99
|
|
|
@@ -118,7 +124,7 @@ await init({ module_or_path: wasmUrl });
|
|
|
118
124
|
## API Reference
|
|
119
125
|
|
|
120
126
|
### `validate_fasm(source: string): IdeDiagnostic[]` / `validateFasm(source: string): IdeDiagnostic[]`
|
|
121
|
-
Parses and
|
|
127
|
+
Parses, validates, and test-compiles `.fasm` source code, returning zero-based UTF-16 line and column spans ready for Monaco Editor, CodeMirror 6, or VS Code diagnostic markers (including v2.0.0 strict-lowercase quick-fix remediation hints in `help`). Returns an empty array `[]` when the source compiles cleanly.
|
|
122
128
|
|
|
123
129
|
```ts
|
|
124
130
|
interface IdeDiagnostic {
|
|
@@ -127,12 +133,12 @@ interface IdeDiagnostic {
|
|
|
127
133
|
end_line: number; // 0-based UTF-16 line index
|
|
128
134
|
end_col: number; // 0-based UTF-16 character column
|
|
129
135
|
message: string; // Human-readable diagnostic message
|
|
130
|
-
help?: string; // Actionable
|
|
136
|
+
help?: string; // Actionable remediation or 1-click quick-fix hint
|
|
131
137
|
}
|
|
132
138
|
```
|
|
133
139
|
|
|
134
140
|
### `inspect_fasm(source: string): PacketPreview[]`
|
|
135
|
-
Compiles `.fasm` source code into an array of packet inspection
|
|
141
|
+
Compiles `.fasm` source code into an array of packet ladder inspection entries, including relative millisecond timestamps, endpoint pairs (`source_dest`), protocol labels (`protocol`), decoded Ethernet/VLAN/QinQ/MPLS/L3/L4/L7 summaries (`summary`), frame lengths, and lowercase space-delimited hex byte dumps. Throws a JavaScript `Error` if compilation fails.
|
|
136
142
|
|
|
137
143
|
```ts
|
|
138
144
|
interface PacketPreview {
|
|
@@ -140,21 +146,24 @@ interface PacketPreview {
|
|
|
140
146
|
timestamp_ms: number; // Relative timestamp in milliseconds
|
|
141
147
|
length: number; // Total packet length in bytes
|
|
142
148
|
hex: string; // Space-separated lowercase hex byte dump
|
|
149
|
+
source_dest: string; // Formatted "src -> dst" IPv4, IPv6, or MAC pair
|
|
150
|
+
protocol: string; // Highest-layer protocol label (e.g. "DNS", "SNMP", "MODBUS")
|
|
151
|
+
summary: string; // Decoded L2/L3/L4/L7 frame summary string
|
|
143
152
|
}
|
|
144
153
|
```
|
|
145
154
|
|
|
146
155
|
### `compile_fasm_to_pcapng(source: string): Uint8Array` / `compileFasm(source: string): Uint8Array`
|
|
147
|
-
Compiles `.fasm` source code into a binary `Uint8Array` containing a valid, standards-compliant PCAPNG byte stream with nanosecond timestamp precision (`IfTsResol = 9`). Throws a JavaScript `Error` with
|
|
156
|
+
Compiles `.fasm` source code into a binary `Uint8Array` containing a valid, standards-compliant PCAPNG byte stream with nanosecond timestamp precision (`IfTsResol = 9`). Throws a JavaScript `Error` with diagnostic context if compilation fails.
|
|
148
157
|
|
|
149
|
-
### `reversePcap(pcap_bytes: Uint8Array): ReverseJsResult`
|
|
150
|
-
Decompiles an in-memory `.pcap` or `.pcapng` byte array (`Uint8Array`) across all 81 native Layer 2 through Layer 7 protocols into
|
|
158
|
+
### `reverse_pcap(pcap_bytes: Uint8Array): ReverseJsResult` / `reversePcap(pcap_bytes: Uint8Array): ReverseJsResult`
|
|
159
|
+
Decompiles an in-memory `.pcap` or `.pcapng` byte array (`Uint8Array`) across all 81 native Layer 2 through Layer 7 protocols into strict-lowercase `.fasm` code (`host1`, `host2`, ... declarations and an inline `compile` block), returning summary statistics (`packetCount`, `hostCount`). Throws a structured error object (`{ success: false, error, message }`) if `pcap_bytes` is not a valid packet capture.
|
|
151
160
|
|
|
152
161
|
```ts
|
|
153
162
|
interface ReversePcapResult {
|
|
154
163
|
success: boolean; // true when decompilation succeeds
|
|
155
|
-
fasm: string; //
|
|
164
|
+
fasm: string; // Strict-lowercase .fasm source code
|
|
156
165
|
packetCount: number; // Total number of reversed packets
|
|
157
|
-
hostCount: number; // Total number of
|
|
166
|
+
hostCount: number; // Total number of host1, host2, ... declarations emitted
|
|
158
167
|
}
|
|
159
168
|
|
|
160
169
|
type ReverseJsResult = ReversePcapResult;
|
|
@@ -200,15 +209,15 @@ export async function importCaptureFile(file: File): Promise<string> {
|
|
|
200
209
|
|
|
201
210
|
## Features & Engine Capabilities
|
|
202
211
|
|
|
203
|
-
- **Zero Server Dependencies**: Executes 100% locally in WebAssembly inside Chrome, Firefox, Safari, Edge, Web Workers, and Node.js.
|
|
204
|
-
- **81 Native Protocols (Forward & Reverse)**: Complete compilation and `.pcap`/`.pcapng` decompilation coverage across L2–L7 (Ethernet, 802.1Q VLAN, QinQ, MPLS, ARP, IPv4/IPv6, ICMP, TCP, UDP, SCTP, SNMPv1/v2c/v3 USM, DNS, DHCP, HTTP, TLS, Modbus, DNP3, and more), including pure Layer-2 MAC-only switch topologies and inline `compile` statements.
|
|
212
|
+
- **Zero Server Dependencies**: Executes 100% locally in WebAssembly inside Chrome, Firefox, Safari, Edge, Web Workers, VS Code Desktop/Web, and Node.js.
|
|
213
|
+
- **81 Native Protocols (Forward & Reverse)**: Complete compilation and `.pcap`/`.pcapng` decompilation coverage across L2–L7 (Ethernet, 802.1Q VLAN, QinQ, MPLS, ARP, IPv4/IPv6, ICMP, TCP, UDP, SCTP, SNMPv1/v2c/v3 USM, DNS, DHCP, HTTP, TLS, QUIC, Modbus, DNP3, and more), including pure Layer-2 MAC-only switch topologies and inline `compile` statements.
|
|
205
214
|
- **Nanosecond Fidelity**: Compiles and reverses deterministic PCAP/PCAPNG captures with nanosecond-resolution Section and Interface Description Blocks (`IfTsResol(9)`).
|
|
206
|
-
- **Sub-Millisecond Compilation**: Small to medium captures compile and decompile in `< 5ms`, making real-time live typing diagnostics and drag-and-drop PCAP import instantaneous in web editors.
|
|
215
|
+
- **Sub-Millisecond Compilation**: Small to medium captures compile and decompile in `< 5ms`, making real-time live typing diagnostics, packet ladder previews, and drag-and-drop PCAP import instantaneous in web and IDE editors.
|
|
207
216
|
|
|
208
217
|
---
|
|
209
218
|
|
|
210
219
|
## Disambiguation: FrameAssembly vs. Flat Assembler
|
|
211
220
|
|
|
212
|
-
**FrameAssembly** (`.fasm`, media type `text/vnd.frameassembly`) is a
|
|
221
|
+
**FrameAssembly** (`.fasm`, media type `text/vnd.frameassembly`) is a network packet specification compiler for generating and decompiling `.pcap` and `.pcapng` packet captures. It is completely unrelated to x86 Flat Assembler (`fasm.net`) and SymbiFlow / F4PGA FPGA bitstream FASM tools.
|
|
213
222
|
|
|
214
|
-
Full documentation, grammar specifications, and 2,611 verified examples: https://github.com/SteveWinschel/FrameAssembly
|
|
223
|
+
Full documentation, interactive browser playground ([https://frameassembly.ai.studio/](https://frameassembly.ai.studio/)), grammar specifications, and 2,611 verified examples: https://github.com/SteveWinschel/FrameAssembly
|
package/frameassembly_wasm.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export interface PacketPreview {
|
|
|
15
15
|
timestamp_ms: number;
|
|
16
16
|
length: number;
|
|
17
17
|
hex: string;
|
|
18
|
+
source_dest: string;
|
|
19
|
+
protocol: string;
|
|
20
|
+
summary: string;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export interface ReversePcapResult {
|
|
@@ -45,10 +48,19 @@ export function compileFasm(source: string): Uint8Array;
|
|
|
45
48
|
export function compile_fasm_to_pcapng(source: string): Uint8Array;
|
|
46
49
|
|
|
47
50
|
/**
|
|
48
|
-
* Returns decoded frame metadata and hex strings for
|
|
51
|
+
* Returns decoded frame metadata, endpoint/protocol summaries, and hex strings for packet ladder inspectors.
|
|
49
52
|
*/
|
|
50
53
|
export function inspect_fasm(source: string): PacketPreview[];
|
|
51
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Decompiles an in-memory `.pcap` or `.pcapng` capture (`reversePcap` camelCase alias).
|
|
57
|
+
*
|
|
58
|
+
* # Errors
|
|
59
|
+
* Returns a structured `JsValue` error object (`{ success: false, error, message }`) if
|
|
60
|
+
* `pcap_bytes` is not a valid `.pcap` or `.pcapng` capture.
|
|
61
|
+
*/
|
|
62
|
+
export function reversePcap(pcap_bytes: Uint8Array | number[]): ReversePcapResult;
|
|
63
|
+
|
|
52
64
|
/**
|
|
53
65
|
* Decompiles an in-memory `.pcap` or `.pcapng` capture (`Uint8Array`) into canonical `.fasm`
|
|
54
66
|
* source code and summary counts (`{ success: true, fasm, packetCount, hostCount }`).
|
|
@@ -57,7 +69,7 @@ export function inspect_fasm(source: string): PacketPreview[];
|
|
|
57
69
|
* Returns a structured `JsValue` error object (`{ success: false, error, message }`) if
|
|
58
70
|
* `pcap_bytes` is not a valid `.pcap` or `.pcapng` capture.
|
|
59
71
|
*/
|
|
60
|
-
export function
|
|
72
|
+
export function reverse_pcap(pcap_bytes: Uint8Array | number[]): ReversePcapResult;
|
|
61
73
|
|
|
62
74
|
/**
|
|
63
75
|
* Validates `.fasm` source and returns UTF-16 line/column diagnostics (`validateFasm` alias).
|
|
@@ -65,7 +77,7 @@ export function reversePcap(pcap_bytes: Uint8Array | number[]): ReversePcapResul
|
|
|
65
77
|
export function validateFasm(source: string): IdeDiagnostic[];
|
|
66
78
|
|
|
67
79
|
/**
|
|
68
|
-
* Validates `.fasm` source and returns UTF-16 line/column diagnostics for Monaco
|
|
80
|
+
* Validates `.fasm` source and returns UTF-16 line/column diagnostics for Monaco, CodeMirror, and VS Code.
|
|
69
81
|
*/
|
|
70
82
|
export function validate_fasm(source: string): IdeDiagnostic[];
|
|
71
83
|
|
|
@@ -77,6 +89,7 @@ export interface InitOutput {
|
|
|
77
89
|
readonly compile_fasm_to_pcapng: (a: number, b: number) => [number, number, number, number];
|
|
78
90
|
readonly inspect_fasm: (a: number, b: number) => [number, number, number];
|
|
79
91
|
readonly reversePcap: (a: number, b: number) => [number, number, number];
|
|
92
|
+
readonly reverse_pcap: (a: number, b: number) => [number, number, number];
|
|
80
93
|
readonly validateFasm: (a: number, b: number) => [number, number, number];
|
|
81
94
|
readonly validate_fasm: (a: number, b: number) => [number, number, number];
|
|
82
95
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
package/frameassembly_wasm.js
CHANGED
|
@@ -35,7 +35,7 @@ export function compile_fasm_to_pcapng(source) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* Returns decoded frame metadata and hex strings for
|
|
38
|
+
* Returns decoded frame metadata, endpoint/protocol summaries, and hex strings for packet ladder inspectors.
|
|
39
39
|
* @param {string} source
|
|
40
40
|
* @returns {PacketPreview[]}
|
|
41
41
|
*/
|
|
@@ -50,8 +50,7 @@ export function inspect_fasm(source) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* Decompiles an in-memory `.pcap` or `.pcapng` capture (`
|
|
54
|
-
* source code and summary counts (`{ success: true, fasm, packetCount, hostCount }`).
|
|
53
|
+
* Decompiles an in-memory `.pcap` or `.pcapng` capture (`reversePcap` camelCase alias).
|
|
55
54
|
*
|
|
56
55
|
* # Errors
|
|
57
56
|
* Returns a structured `JsValue` error object (`{ success: false, error, message }`) if
|
|
@@ -69,6 +68,26 @@ export function reversePcap(pcap_bytes) {
|
|
|
69
68
|
return takeFromExternrefTable0(ret[0]);
|
|
70
69
|
}
|
|
71
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Decompiles an in-memory `.pcap` or `.pcapng` capture (`Uint8Array`) into canonical `.fasm`
|
|
73
|
+
* source code and summary counts (`{ success: true, fasm, packetCount, hostCount }`).
|
|
74
|
+
*
|
|
75
|
+
* # Errors
|
|
76
|
+
* Returns a structured `JsValue` error object (`{ success: false, error, message }`) if
|
|
77
|
+
* `pcap_bytes` is not a valid `.pcap` or `.pcapng` capture.
|
|
78
|
+
* @param {Uint8Array | number[]} pcap_bytes
|
|
79
|
+
* @returns {ReversePcapResult}
|
|
80
|
+
*/
|
|
81
|
+
export function reverse_pcap(pcap_bytes) {
|
|
82
|
+
const ptr0 = passArray8ToWasm0(pcap_bytes, wasm.__wbindgen_malloc);
|
|
83
|
+
const len0 = WASM_VECTOR_LEN;
|
|
84
|
+
const ret = wasm.reverse_pcap(ptr0, len0);
|
|
85
|
+
if (ret[2]) {
|
|
86
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
87
|
+
}
|
|
88
|
+
return takeFromExternrefTable0(ret[0]);
|
|
89
|
+
}
|
|
90
|
+
|
|
72
91
|
/**
|
|
73
92
|
* Validates `.fasm` source and returns UTF-16 line/column diagnostics (`validateFasm` alias).
|
|
74
93
|
* @param {string} source
|
|
@@ -85,7 +104,7 @@ export function validateFasm(source) {
|
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
/**
|
|
88
|
-
* Validates `.fasm` source and returns UTF-16 line/column diagnostics for Monaco
|
|
107
|
+
* Validates `.fasm` source and returns UTF-16 line/column diagnostics for Monaco, CodeMirror, and VS Code.
|
|
89
108
|
* @param {string} source
|
|
90
109
|
* @returns {IdeDiagnostic[]}
|
|
91
110
|
*/
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"collaborators": [
|
|
5
5
|
"Steve Winschel"
|
|
6
6
|
],
|
|
7
|
-
"description": "
|
|
8
|
-
"version": "
|
|
7
|
+
"description": "Compile .fasm network traffic code to .pcapng and decompile .pcap/.pcapng packet captures in WebAssembly across 81 L2-L7 protocols with live IDE diagnostics and frame inspection.",
|
|
8
|
+
"version": "2.0.0",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -17,16 +17,31 @@
|
|
|
17
17
|
"frameassembly_wasm.d.ts"
|
|
18
18
|
],
|
|
19
19
|
"main": "frameassembly_wasm.js",
|
|
20
|
-
"homepage": "https://
|
|
20
|
+
"homepage": "https://frameassembly.ai.studio/",
|
|
21
21
|
"types": "frameassembly_wasm.d.ts",
|
|
22
22
|
"sideEffects": [
|
|
23
23
|
"./snippets/*"
|
|
24
24
|
],
|
|
25
25
|
"keywords": [
|
|
26
26
|
"frameassembly",
|
|
27
|
+
"fasm",
|
|
27
28
|
"pcap",
|
|
28
29
|
"pcapng",
|
|
30
|
+
"wasm",
|
|
31
|
+
"webassembly",
|
|
29
32
|
"wireshark",
|
|
30
|
-
"
|
|
33
|
+
"packet-generator",
|
|
34
|
+
"pcap-decompiler",
|
|
35
|
+
"pcap-parser",
|
|
36
|
+
"tcpreplay",
|
|
37
|
+
"suricata",
|
|
38
|
+
"zeek",
|
|
39
|
+
"snmpv3",
|
|
40
|
+
"firewall-testing",
|
|
41
|
+
"network-testing",
|
|
42
|
+
"cybersecurity",
|
|
43
|
+
"pentesting",
|
|
44
|
+
"packets-as-code",
|
|
45
|
+
"modbus"
|
|
31
46
|
]
|
|
32
47
|
}
|