Skip to content

Instantly share code, notes, and snippets.

@grigorescu
Created December 10, 2015 18:06
Show Gist options
  • Save grigorescu/6fdee68a660f2b05ea6b to your computer and use it in GitHub Desktop.
Save grigorescu/6fdee68a660f2b05ea6b to your computer and use it in GitHub Desktop.
local msg_types = {
[0] = "None",
[1] = "Version",
[2] = "Serial",
[3] = "Close",
[4] = "Close all",
[5] = "Error",
[6] = "Connect to",
[7] = "Connected",
[8] = "Request events",
[9] = "Listen",
[10] = "Listen stop",
[11] = "Stats",
[12] = "Capture filter",
[13] = "Request sync",
[14] = "Phase done",
[15] = "Ping",
[16] = "Pong",
[17] = "Caps",
[18] = "Compress",
[19] = "Log",
[20] = "Sync point",
[21] = "Terminate",
[22] = "Debug dump",
[23] = "Remote print",
[24] = "Log create writer",
[25] = "Log write",
[26] = "Request logs"
}
p_bro = Proto("bro", "Bro communication protocol")
local f_msg = ProtoField.string("bro.msg_header", "Message header")
local f_msg_type = ProtoField.uint8("bro.msg_type", "Message type")
local f_msg_peer_id = ProtoField.uint32("bro.msg_peer_id", "Message peer ID")
local f_msg_arg_length = ProtoField.uint32("bro.msg_arg_len", "Message arguments length")
local f_ver_version = ProtoField.uint32("bro.version.version", "Protocol version")
local f_ver_cache_size = ProtoField.uint32("bro.version.cache_size", "Protocol cache size")
local f_ver_data_format_version = ProtoField.uint32("bro.version.data_format_version", "Protocol data format version")
local f_ver_runtime = ProtoField.uint32("bro.version.runtime", "Runtime of peer")
local f_ver_peer_class = ProtoField.uint32("bro.version.peer_class", "Class of peer")
p_bro.fields = {f_msg, f_msg_type, f_msg_peer_id, f_msg_arg_length, f_ver_version, f_ver_cache_size, f_ver_data_format_version, f_ver_runtime, f_ver_peer_class}
parse_msg_type = function(pos, buf, tree)
local msg = buf:range(pos,1):uint()
tree:set_text("Bro "..msg_types[msg].." message")
local header = tree:add(f_msg, buf:range(pos, 8)):set_text("Header")
header:add(f_msg_type, buf:range(pos, 1))
header:add_le(f_msg_peer_id, buf:range(pos+4, 4))
return msg
end
parse_msg_args = function(msgtype, pos, buf, tree)
if msgtype == 1 then --version
tree:add(f_ver_version, buf:range(pos,4):uint())
tree:add(f_ver_cache_size, buf:range(pos+4,4):uint())
tree:add(f_ver_data_format_version, buf:range(pos+8,4):uint())
tree:add(f_ver_runtime, buf:range(pos+12,4):uint())
if buf:len() == pos+20 then
tree:add(f_ver_class, buf:range(pos+16,4):uint())
end
end
end
parse_msg = function(pos, buf, pkt, tree, root)
local msgtype = parse_msg_type(pos, buf, tree)
if not (msgtype == 3 or msgtype == 4 or msgtype == 10 or msgtype == 14 or msgtype == 21 or msgtype == 22 or msgtype == 32) then
-- we have to parse arguments
local arg_len = buf:range(pos+8,4):uint()
tree:add(f_msg_arg_length, buf:range(pos+8,4):uint())
local arg_tree = tree:add(p_bro, buf:range(pos+12, arg_len)):set_text("Arguments")
parse_msg_args(msgtype, pos+12, buf, arg_tree)
tree:set_len(12+arg_len)
return 12 + arg_len
end
return 8
end
function p_bro.dissector(buf, pkt, root)
pkt.cols.protocol = p_bro.name
local pktlen = buf:reported_length_remaining()
local pktlen_remaining = pktlen
local pos = 0
while pktlen_remaining > 0 do
if pktlen_remaining < 4 then
pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
return
end
local chunk_len = buf:range(pos,4):uint()
pos = pos + 4
if pktlen_remaining < 4 + chunk_len then
pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
return
end
local tree = root:add(p_bro, buf:range(pos,chunk_len))
pos = pos + parse_msg(pos, buf, pkt, tree, root)
pktlen_remaining = pktlen - pos
end -- end of while loop
end
-- Initialization routine
function p_bro.init()
end
local tcp_dissector_table = DissectorTable.get("tcp.port")
dissector = tcp_dissector_table:get_dissector(47761)
tcp_dissector_table:add(47761, p_bro)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment