Move the SIP analyzer to uint64 sequences, and a number of other small SIP fixes.

This commit is contained in:
Vlad Grigorescu 2014-08-26 22:26:42 -04:00
parent f93f2af748
commit 214e6b3ea9
6 changed files with 102 additions and 49 deletions

View file

@ -68,8 +68,8 @@ export {
}; };
## A list of SIP methods. Other methods will generate a weird. Note ## A list of SIP methods. Other methods will generate a weird. Note
## that the SIP analyzer will only accept methods consisting solely ## that the SIP analyzer will only accept methods consisting solely
## of letters ``[A-Za-z]``. ## of letters ``[A-Za-z]``.
const sip_methods: set[string] = { const sip_methods: set[string] = {
"REGISTER", "INVITE", "ACK", "CANCEL", "BYE", "OPTIONS" "REGISTER", "INVITE", "ACK", "CANCEL", "BYE", "OPTIONS"
} &redef; } &redef;
@ -86,6 +86,7 @@ redef record connection += {
}; };
const ports = { 5060/udp }; const ports = { 5060/udp };
redef likely_server_ports += { ports };
event bro_init() &priority=5 event bro_init() &priority=5
{ {
@ -186,12 +187,12 @@ event sip_header(c: connection, is_request: bool, name: string, value: string) &
} }
} }
event sip_message_done(c: connection, is_request: bool) &priority = 5 event sip_end_entity(c: connection, is_request: bool) &priority = 5
{ {
set_state(c, is_request); set_state(c, is_request);
} }
event sip_message_done(c: connection, is_request: bool) &priority = -5 event sip_end_entity(c: connection, is_request: bool) &priority = -5
{ {
# The reply body is done so we're ready to log. # The reply body is done so we're ready to log.
if ( ! is_request ) if ( ! is_request )

View file

@ -5,7 +5,7 @@
using namespace analyzer::sip; using namespace analyzer::sip;
SIP_Analyzer::SIP_Analyzer(Connection* c) SIP_Analyzer::SIP_Analyzer(Connection* c)
: analyzer::Analyzer("SIP", c) : Analyzer("SIP", c)
{ {
interp = new binpac::SIP::SIP_Conn(this); interp = new binpac::SIP::SIP_Conn(this);
} }
@ -20,8 +20,8 @@ void SIP_Analyzer::Done()
Analyzer::Done(); Analyzer::Done();
} }
void SIP_Analyzer::DeliverPacket(int len, const u_char* data, void SIP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
bool orig, int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
bool real_orig = true; bool real_orig = true;
if ( len > 6 && data[0] == 'S' && data[1] == 'I' && data[2] == 'P' && data[3] == '/' ) if ( len > 6 && data[0] == 'S' && data[1] == 'I' && data[2] == 'P' && data[3] == '/' )

View file

@ -17,13 +17,14 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new SIP_Analyzer(conn); } { return new SIP_Analyzer(conn); }
static bool Available() static bool Available()
{ return sip_request; } { return sip_request || sip_reply || sip_header ||
sip_all_headers || sip_begin_entity || sip_end_entity; }
protected: protected:
binpac::SIP::SIP_Conn* interp; binpac::SIP::SIP_Conn* interp;

View file

@ -12,13 +12,68 @@
## original_URI: The unprocessed URI as specified in the request. ## original_URI: The unprocessed URI as specified in the request.
## ##
## version: The version number specified in the request (e.g., ``2.0``). ## version: The version number specified in the request (e.g., ``2.0``).
##
event sip_request%(c: connection, method: string, original_URI: string, version: string%); event sip_request%(c: connection, method: string, original_URI: string, version: string%);
## Generated for SIP replies, used in Voice over IP (VoIP).
##
## This event is generated as soon as a reply's initial line has been parsed.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Session_Initiation_Protocol>`__
## for more information about the SIP protocol.
##
## c: The connection.
##
## version: The SIP version in use.
##
## code: The response code.
##
## reason: Textual details for the response code.
event sip_reply%(c: connection, version: string, code: count, reason: string%); event sip_reply%(c: connection, version: string, code: count, reason: string%);
## Generated for each SIP header.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Session_Initiation_Protocol>`__
## for more information about the SIP protocol.
##
## c: The connection.
##
## is_orig: Whether the header came from the originator.
##
## name: Header name.
##
## value: Header value.
event sip_header%(c: connection, is_orig: bool, name: string, value: string%); event sip_header%(c: connection, is_orig: bool, name: string, value: string%);
## Generated once for all SIP headers from the originator or responder.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Session_Initiation_Protocol>`__
## for more information about the SIP protocol.
##
## c: The connection.
##
## is_orig: Whether the headers came from the originator.
##
## hlist: All the headers, and their values
event sip_all_headers%(c: connection, is_orig: bool, hlist: mime_header_list%); event sip_all_headers%(c: connection, is_orig: bool, hlist: mime_header_list%);
## Generated at the beginning of a SIP message.
##
## This event is generated as soon as a message's initial line has been parsed.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Session_Initiation_Protocol>`__
## for more information about the SIP protocol.
##
## c: The connection.
##
## is_orig: Whether the message came from the originator.
event sip_begin_entity%(c: connection, is_orig: bool%); event sip_begin_entity%(c: connection, is_orig: bool%);
## Generated at the end of a SIP message.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Session_Initiation_Protocol>`__
## for more information about the SIP protocol.
##
## c: The connection.
##
## is_orig: Whether the message came from the originator.
event sip_end_entity%(c: connection, is_orig: bool%); event sip_end_entity%(c: connection, is_orig: bool%);
event sip_entity_data%(c: connection, is_orig: bool, length: count, data: string%);
event sip_message_done%(c: connection, is_orig: bool%);

View file

@ -133,10 +133,6 @@ refine flow SIP_Flow += {
{ {
BifEvent::generate_sip_end_entity(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), is_orig()); BifEvent::generate_sip_end_entity(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), is_orig());
} }
if ( sip_message_done )
{
BifEvent::generate_sip_message_done(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), is_orig());
}
return true; return true;
%} %}

View file

@ -1,7 +1,7 @@
enum ExpectBody { enum ExpectBody {
BODY_EXPECTED, BODY_EXPECTED,
BODY_NOT_EXPECTED, BODY_NOT_EXPECTED,
BODY_MAYBE, BODY_MAYBE,
}; };
type SIP_TOKEN = RE/[^()<>@,;:\\"\/\[\]?={} \t]+/; type SIP_TOKEN = RE/[^()<>@,;:\\"\/\[\]?={} \t]+/;
@ -12,67 +12,67 @@ type SIP_EOL = RE/(\r\n){1,2}/;
type SIP_URI = RE/[[:alnum:]@[:punct:]]+/; type SIP_URI = RE/[[:alnum:]@[:punct:]]+/;
type SIP_PDU(is_orig: bool) = case is_orig of { type SIP_PDU(is_orig: bool) = case is_orig of {
true -> request: SIP_Request; true -> request: SIP_Request;
false -> reply: SIP_Reply; false -> reply: SIP_Reply;
}; };
type SIP_Request = record { type SIP_Request = record {
request: SIP_RequestLine; request: SIP_RequestLine;
newline: padding[2]; newline: padding[2];
msg: SIP_Message; msg: SIP_Message;
}; };
type SIP_Reply = record { type SIP_Reply = record {
reply: SIP_ReplyLine; reply: SIP_ReplyLine;
newline: padding[2]; newline: padding[2];
msg: SIP_Message; msg: SIP_Message;
}; };
type SIP_RequestLine = record { type SIP_RequestLine = record {
method: SIP_TOKEN; method: SIP_TOKEN;
: SIP_WS; : SIP_WS;
uri: SIP_URI; uri: SIP_URI;
: SIP_WS; : SIP_WS;
version: SIP_Version; version: SIP_Version;
} &oneline; } &oneline;
type SIP_ReplyLine = record { type SIP_ReplyLine = record {
version: SIP_Version; version: SIP_Version;
: SIP_WS; : SIP_WS;
status: SIP_Status; status: SIP_Status;
: SIP_WS; : SIP_WS;
reason: SIP_TO_EOL; reason: SIP_TO_EOL;
} &oneline; } &oneline;
type SIP_Status = record { type SIP_Status = record {
stat_str: RE/[0-9]{3}/; stat_str: RE/[0-9]{3}/;
} &let { } &let {
stat_num: int = bytestring_to_int(stat_str, 10); stat_num: int = bytestring_to_int(stat_str, 10);
}; };
type SIP_Version = record { type SIP_Version = record {
: "SIP/"; : "SIP/";
vers_str: RE/[0-9]+\.[0-9]+/; vers_str: RE/[0-9]+\.[0-9]+/;
} &let { } &let {
vers_num: double = bytestring_to_double(vers_str); vers_num: double = bytestring_to_double(vers_str);
}; };
type SIP_Headers = SIP_Header[] &until($input.length() == 0); type SIP_Headers = SIP_Header[] &until($input.length() == 0);
type SIP_Message = record { type SIP_Message = record {
headers: SIP_Headers; headers: SIP_Headers;
body: SIP_Body; body: SIP_Body;
}; };
type SIP_HEADER_NAME = RE/[^: \t]+/; type SIP_HEADER_NAME = RE/[^: \t]+/;
type SIP_Header = record { type SIP_Header = record {
name: SIP_HEADER_NAME; name: SIP_HEADER_NAME;
: SIP_COLON; : SIP_COLON;
: SIP_WS; : SIP_WS;
value: SIP_TO_EOL; value: SIP_TO_EOL;
: SIP_EOL; : SIP_EOL;
} &oneline &byteorder=bigendian; } &oneline &byteorder=bigendian;
type SIP_Body = record { type SIP_Body = record {
body: bytestring &length = $context.flow.get_content_length(); body: bytestring &length = $context.flow.get_content_length();
}; };