Why Spicy?
Historically extending Zeek with new parsers required interacting with Zeek's C++ API which was a significant barrier to entry for domain experts.
Spicy is a domain-specific language for developing parsers for network protocols or file formats which integrates well with Zeek.
Flexible multi-paradigm language
With Spicy parsers can be
expressed in declaratively in a format close to specifications, e.g., the
following TFTP ERROR
message
# 2 bytes 2 bytes string 1 byte
# -----------------------------------------
# | Opcode | ErrorCode | ErrMsg | 0 |
# -----------------------------------------
can be expressed in Spicy as
type Error = unit {
op_code: uint16;
error_code: uint16;
msg: bytes &until=b"\x00";
};
Spicy supports procedural code which can be hooked into parsing to support more complex parsing scenarios.
function sum(a: uint64, b: uint64): uint64 { return a + b; }
type Fold = unit {
a: uint8;
b: uint8 &convert=sum(self.a, $$);
c: uint8 &convert=sum(self.b, $$);
};
Incremental parsing
The parsers generated by Spicy automatically support incremental parsing. Data can be fed as it arrives without blocking until all data is available. Hooks allow reacting to parse results.
Built-in safety
Spicy code is executed safely so many common errors are rejected, e.g.,
- integer under- or overflows
- incorrect use of iterators
- unhandled switch cases
Integration into Zeek
Spicy parsers can trigger events in Zeek. Parse results can transparently be made available to Zeek script code.