Skip to content

Commit

Permalink
Add a real event, but with bad types
Browse files Browse the repository at this point in the history
Not sure how to give the event all of the data properly - for example,
some of it has recursive types.
  • Loading branch information
evantypanski committed Sep 20, 2024
1 parent 99b3b06 commit 947ddd9
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 4 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Parses the [Redis serialization protocol](https://redis.io/docs/latest/develop/r
## Usage

1) Grab a PCAP (like [redis.pcap](https://github.com/macbre/data-flow-graph/blob/master/sources/pcap/redis.pcap))
2) Compile the code so Zeek can use it: `spicyz -o resp.hlto resp.spicy resp.evt`
3) See some output via Zeek: `zeek -C -r redis.pcap resp.hlto Spicy::enable_print=T`
2) Compile the code so Zeek can use it: `spicyz -o resp.hlto resp.spicy resp.evt zeek_analyzer.spicy`
3) See some output via Zeek: `zeek -C -r redis.pcap resp.hlto resp.zeek`

This will be updated as it's better :)
5 changes: 5 additions & 0 deletions resp.evt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
protocol analyzer spicy::RESP over TCP:
parse with RESP::Data,
port 56379/tcp;

import RESP;
import Zeek_RESP;

on RESP::Data -> event resp::data($conn, Zeek_RESP::create_data(self));
4 changes: 2 additions & 2 deletions resp.spicy
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module RESP;

import spicy;

public type Data = unit {
ty: uint8 &convert=DataType($$);
switch ( self.ty ) {
Expand All @@ -23,8 +25,6 @@ public type Data = unit {
# first byte" - TODO: can probably make it more obvious, though
DataType::PUSH -> push: Array;
};

on %done { print self; }
};

type DataType = enum {
Expand Down
18 changes: 18 additions & 0 deletions resp.zeek
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
type RESPData: record {
simple_string: string &optional;
simple_error: string &optional;
i: int &optional;
bulk_string: string &optional;
#array:
is_null: bool;
boolean: bool &optional;
#double_: double &optional;
big_num: string &optional;
bulk_error: string &optional;
verbatim_string: string &optional;
};

event resp::data(c: connection, data: RESPData)
{
print "RESP data", c$id, data;
}
70 changes: 70 additions & 0 deletions zeek_analyzer.spicy
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
module Zeek_RESP;

import RESP;
import spicy;
import zeek;

on RESP::Data::%done {
print self;
zeek::confirm_protocol();
}

on RESP::Data::%error {
zeek::reject_protocol("error while parsing RESP data");
}

type ZeekData = tuple<
optional<bytes>,
optional<bytes>,
optional<int64>,
optional<bytes>,
#optional<vector<ZeekData>>, # TODO: This segfaults because recursive type :(
bool,
optional<bool>,
#optional<real>, # TODO: How to convert real to zeek double?
optional<string>,
optional<bytes>,
optional<bytes>,
>;

public function create_data(data: RESP::Data): ZeekData {
local simple_string: optional<bytes>;
local simple_error: optional<bytes>;
local i: optional<int64>;
local bulk_string: optional<bytes>;
#local array: optional<vector<ZeekData>>;
local null: bool;
local boolean: optional<bool>;
local double: optional<real>;
local big_num: optional<string>;
local bulk_error: optional<bytes>;
local verbatim_string: optional<bytes>;
if (data?.simple_string)
simple_string = data.simple_string.content;
if (data?.simple_error)
simple_error = data.simple_error.content;
if (data?.integer)
i = data.integer.int;
if (data?.bulk_string)
bulk_string = data.bulk_string.content;
#if (data?.array) {
# for ( data in data.array.elements ) {
# array.push_back(data);
# }
#}
if (data?.null)
null = True;
else
null = False;
if (data?.boolean)
boolean = data.boolean.val;
if (data?.double)
double = data.double.val;
if (data?.big_num)
big_num = data.big_num.val;
if (data?.bulk_error)
bulk_error = data.bulk_error.content;
if (data?.verbatim_string)
verbatim_string = data.verbatim_string.content;
return (simple_string, simple_error, i, bulk_string, null, boolean, big_num, bulk_error, verbatim_string);
}

0 comments on commit 947ddd9

Please sign in to comment.