FrameAssembly
[!WARNING] Experimental Prototype This project is currently in the prototype stage. Many features are missing, APIs are unstable, and there will likely be breaking changes. Please do not use or show this in front of customers, coworkers or middle management (I already failed at that).
FrameAssembly is a Domain-Specific Language (DSL) for writing network traffic that gets compiled into a .pcap file. It is meant to be used for network security research, education, and testing.
Features
- Production-Grade Pipeline: Uses
logosfor zero-copy lexing andwinnowfor robust combinator parsing into a flat Abstract Syntax Tree (AST). - Rich Diagnostics: Employs
mietteto provide beautiful,rustc-style terminal error reporting pointing exactly to syntax errors. - Packet Field Abstraction: You can set TCP/IP, UDP, and SNMP packet fields like
SEQ,WIN,PAYLOAD,OID, andWAITusing space-separated keyword values. - Reliable Packet Crafting: Uses
etherparsefor correct zero-allocation L2-L4 encapsulation and checksumming. - Deterministic Output: Generates reproducible
.pcapfiles with nanosecond precision usingpcap-file(PcapNgWriter) based on the defined flow and mock epoch timestamps. - Comments: Supports inline comments using
//.
Getting Started
Prerequisites
You need Rust and Cargo installed.
Installation
Primary Method (via Cargo):
Alternative Method (from source): Clone the repository and enter the directory:
Editor Support (VS Code)
A VS Code extension providing syntax highlighting for .fasm files is included in the repository.
To install it manually, you can use the command line:
Alternatively, in VS Code, open the Extensions view, click the ... menu, and select Install from VSIX... to install the file from the frameassembly-vscode directory.
Syntax Guide
1. Hosts
Hosts are defined using the HOST keyword. They act as network endpoints.
HOST name { IP 1.2.3.4 MAC 00:11:22:33:44:55 }
IPis mandatory.MACis optional (defaults to00:00:00:00:00:00if not provided).
2. Flows
Flows (similar to functions) encapsulate sequences of packet transmissions between endpoints. They are defined using the FLOW keyword and take arguments for the source and destination endpoints.
FLOW tcp_handshake(client, server) {
client -> server TCP SYN PAYLOAD "Hello"
client <- server TCP SYN ACK PAYLOAD "World"
client -> server TCP ACK PAYLOAD "!"
}
Directionality
The arrow dictates the packet's source and destination:
A -> B:Ais the source,Bis the destination.A <- B:Bis the source,Ais the destination.
Supported Protocols
TCPUDPSNMP1,SNMP2,SNMP3(First-class support for SNMP Traps)
Port Definitions
SRCPORT <port>: Defines the source port. (Optional: auto-calculated)DSTPORT <port>: Defines the destination port. (Optional: auto-calculated)
TCP Flags
Only available when the protocol is TCP. You can chain flags separated by spaces.
SYNACKFINRSTPSHURGECECWR
SNMP Flags
Only available when the protocol is SNMP1, SNMP2, or SNMP3.
TRAP: Identifies the packet as an SNMP trap.
Packet Properties
These properties follow the protocol and flag definitions. They are defined using space-separated key-value pairs.
SEQ <number>: Sets the TCP sequence number. (Optional: auto-calculated)ACKNUM <number>: Sets the TCP acknowledgment number. (Optional: auto-calculated)WIN <number>: Sets the TCP window size. (Optional)PAYLOAD "<string>": Appends a string payload to the packet.COMMUNITY "<string>": Sets the community string forSNMP1andSNMP2traps.USER "<string>": Sets the USM authentication user name forSNMP3traps.SYSUPTIME <number>: Sets the time stamp (SysUpTime) for SNMP traps.OID <string> | "<string>": Sets the primary Object Identifier for the SNMP trap. Quotes are optional; raw OIDs (e.g.,1.3.6.1.4.1) and IPv4-formatted strings are natively supported.WAIT <number><suffix>: Introduces an artificial delay before sending the next packet. (Optional: defaults to 10ms)- Supported suffixes:
ms(milliseconds),s(seconds),m(minutes).
- Supported suffixes:
3. Compile Block
The COMPILE block serves as the main entry point to execute flows. You can invoke previously defined FLOWs, passing HOSTs as arguments. You can also use LOOP to repeat a sequence of flows.
COMPILE {
LOOP 100 {
snmp_trap(switch_agent, example_nms)
tcp_handshake(example_client, google_dns)
}
}
Note: Infinite loops (a LOOP without a specified count) are illegal.
Usage
Define your networking scenario in a text file (e.g., demo.fasm):
// Written vertically -> Intuitive for programmers
HOST example_server {
IP 10.0.10.5
MAC aa:bb:cc:dd:ee:ff
}
// Written horizontally -> Intuitive for network engineers
HOST example_nms { IP 10.0.10.100 }
FLOW tcp_handshake(client, server) {
client -> server TCP SYN PAYLOAD "Hello"
client <- server TCP SYN ACK PAYLOAD "World"
client -> server TCP ACK PAYLOAD "!"
}
FLOW snmp_v1_trap(agent, nms) {
agent -> nms SNMP1 TRAP COMMUNITY "public" OID "1.3.6.1.6.3.1.1.5.3"
}
FLOW snmp_v2_trap(agent, nms) {
agent -> nms SNMP2 TRAP COMMUNITY "public" OID "1.3.6.1.6.3.1.1.5.3"
}
FLOW snmp_v3_trap(agent, nms) {
agent -> nms SNMP3 TRAP USER "admin" OID "1.3.6.1.6.3.1.1.5.3"
}
COMPILE {
tcp_handshake(example_server, example_nms)
snmp_v1_trap(example_server, example_nms)
snmp_v2_trap(example_server, example_nms)
snmp_v3_trap(example_server, example_nms)
}
To compile your script into a PCAP file, run the globally installed binary:
Or, if you are running from the source repository:
This generates an output.pcap file in the root directory via the help of tcpreplay or similar you can simulate written traffic.
License
MIT License. See the LICENSE file.