zeek/scripts/base/protocols/redis/main.zeek
Evan Typanski 97d26a689d spicy-redis: Add synchronization and pipeline support
Also adds some command support
2025-05-27 09:28:12 -04:00

108 lines
2.8 KiB
Text

@load base/protocols/conn/removal-hooks
module RESP;
export {
## Log stream identifier.
redef enum Log::ID += { LOG };
## The ports to register RESP for.
const ports = {
6379/tcp,
} &redef;
type SetCommand: record {
key: string &log;
value: string &log;
nx: bool;
xx: bool;
get: bool;
ex: count &optional;
px: count &optional;
exat: count &optional;
pxat: count &optional;
keep_ttl: bool;
};
type GetCommand: record {
key: string &log;
};
type Command: record {
## The raw command, exactly as parsed
raw: vector of string &log;
## The key, if this command is known to have a key
key: string &log &optional;
## The value, if this command is known to have a value
value: string &log &optional;
};
## Record type containing the column fields of the RESP log.
type Info: record {
## Timestamp for when the activity happened.
ts: time &log;
## Unique ID for the connection.
uid: string &log;
## The connection's 4-tuple of endpoint addresses/ports.
id: conn_id &log;
## The Redis command
cmd: Command &log;
};
## A default logging policy hook for the stream.
global log_policy: Log::PolicyHook;
## Default hook into RESP logging.
global log_resp: event(rec: Info);
}
redef record connection += {
redis_resp: Info &optional;
};
redef likely_server_ports += { ports };
# TODO: If you're going to send file data into the file analysis framework, you
# need to provide a file handle function. This is a simple example that's
# sufficient if the protocol only transfers a single, complete file at a time.
#
# function get_file_handle(c: connection, is_orig: bool): string
# {
# return cat(Analyzer::ANALYZER_SPICY_RESP, c$start_time, c$id, is_orig);
# }
event zeek_init() &priority=5
{
Log::create_stream(RESP::LOG, [$columns=Info, $ev=log_resp, $path="resp", $policy=log_policy]);
Analyzer::register_for_ports(Analyzer::ANALYZER_SPICY_RESP, ports);
# TODO: To activate the file handle function above, uncomment this.
# Files::register_protocol(Analyzer::ANALYZER_SPICY_RESP, [$get_file_handle=RESP::get_file_handle ]);
}
# Initialize logging state.
hook set_session(c: connection, cmd: Command)
{
if ( c?$redis_resp )
return;
c$redis_resp = Info($ts=network_time(), $uid=c$uid, $id=c$id, $cmd=cmd);
}
function emit_log(c: connection)
{
if ( ! c?$redis_resp )
return;
Log::write(RESP::LOG, c$redis_resp);
delete c$redis_resp;
}
event RESP::command(c: connection, is_orig: bool, command: Command)
{
hook set_session(c, command);
local info = c$redis_resp;
emit_log(c);
}