diff --git a/scripts/base/protocols/sip/main.bro b/scripts/base/protocols/sip/main.bro index bae2a1cf10..7d93fcf529 100644 --- a/scripts/base/protocols/sip/main.bro +++ b/scripts/base/protocols/sip/main.bro @@ -68,8 +68,8 @@ export { }; ## A list of SIP methods. Other methods will generate a weird. Note - ## that the SIP analyzer will only accept methods consisting solely - ## of letters ``[A-Za-z]``. + ## that the SIP analyzer will only accept methods consisting solely + ## of letters ``[A-Za-z]``. const sip_methods: set[string] = { "REGISTER", "INVITE", "ACK", "CANCEL", "BYE", "OPTIONS" } &redef; @@ -86,6 +86,7 @@ redef record connection += { }; const ports = { 5060/udp }; +redef likely_server_ports += { ports }; 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); } -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. if ( ! is_request ) diff --git a/src/analyzer/protocol/sip/SIP.cc b/src/analyzer/protocol/sip/SIP.cc index 00f8274327..e45757b721 100644 --- a/src/analyzer/protocol/sip/SIP.cc +++ b/src/analyzer/protocol/sip/SIP.cc @@ -5,7 +5,7 @@ using namespace analyzer::sip; SIP_Analyzer::SIP_Analyzer(Connection* c) -: analyzer::Analyzer("SIP", c) + : Analyzer("SIP", c) { interp = new binpac::SIP::SIP_Conn(this); } @@ -20,8 +20,8 @@ void SIP_Analyzer::Done() Analyzer::Done(); } -void SIP_Analyzer::DeliverPacket(int len, const u_char* data, - bool orig, int seq, const IP_Hdr* ip, int caplen) +void SIP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, + uint64 seq, const IP_Hdr* ip, int caplen) { bool real_orig = true; if ( len > 6 && data[0] == 'S' && data[1] == 'I' && data[2] == 'P' && data[3] == '/' ) diff --git a/src/analyzer/protocol/sip/SIP.h b/src/analyzer/protocol/sip/SIP.h index 8493a29aaa..52004d96d1 100644 --- a/src/analyzer/protocol/sip/SIP.h +++ b/src/analyzer/protocol/sip/SIP.h @@ -17,13 +17,14 @@ public: virtual void Done(); 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) { return new SIP_Analyzer(conn); } static bool Available() - { return sip_request; } + { return sip_request || sip_reply || sip_header || + sip_all_headers || sip_begin_entity || sip_end_entity; } protected: binpac::SIP::SIP_Conn* interp; diff --git a/src/analyzer/protocol/sip/events.bif b/src/analyzer/protocol/sip/events.bif index f62a8986f2..66ae7b5034 100644 --- a/src/analyzer/protocol/sip/events.bif +++ b/src/analyzer/protocol/sip/events.bif @@ -12,13 +12,68 @@ ## original_URI: The unprocessed URI as specified in the request. ## ## version: The version number specified in the request (e.g., ``2.0``). -## 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 `__ +## 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%); + +## Generated for each SIP header. +## +## See `Wikipedia `__ +## 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%); + +## Generated once for all SIP headers from the originator or responder. +## +## See `Wikipedia `__ +## 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%); + +## 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 `__ +## 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%); + +## Generated at the end of a SIP message. +## +## See `Wikipedia `__ +## 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_entity_data%(c: connection, is_orig: bool, length: count, data: string%); -event sip_message_done%(c: connection, is_orig: bool%); diff --git a/src/analyzer/protocol/sip/sip-analyzer.pac b/src/analyzer/protocol/sip/sip-analyzer.pac index 47fa8ffda2..0a54c87115 100644 --- a/src/analyzer/protocol/sip/sip-analyzer.pac +++ b/src/analyzer/protocol/sip/sip-analyzer.pac @@ -133,10 +133,6 @@ refine flow SIP_Flow += { { 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; %} diff --git a/src/analyzer/protocol/sip/sip-protocol.pac b/src/analyzer/protocol/sip/sip-protocol.pac index 958e3921cd..55329303f7 100644 --- a/src/analyzer/protocol/sip/sip-protocol.pac +++ b/src/analyzer/protocol/sip/sip-protocol.pac @@ -1,7 +1,7 @@ enum ExpectBody { - BODY_EXPECTED, + BODY_EXPECTED, BODY_NOT_EXPECTED, - BODY_MAYBE, + BODY_MAYBE, }; 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_PDU(is_orig: bool) = case is_orig of { - true -> request: SIP_Request; - false -> reply: SIP_Reply; + true -> request: SIP_Request; + false -> reply: SIP_Reply; }; type SIP_Request = record { - request: SIP_RequestLine; - newline: padding[2]; - msg: SIP_Message; + request: SIP_RequestLine; + newline: padding[2]; + msg: SIP_Message; }; type SIP_Reply = record { - reply: SIP_ReplyLine; - newline: padding[2]; - msg: SIP_Message; + reply: SIP_ReplyLine; + newline: padding[2]; + msg: SIP_Message; }; type SIP_RequestLine = record { - method: SIP_TOKEN; - : SIP_WS; - uri: SIP_URI; - : SIP_WS; - version: SIP_Version; + method: SIP_TOKEN; + : SIP_WS; + uri: SIP_URI; + : SIP_WS; + version: SIP_Version; } &oneline; type SIP_ReplyLine = record { - version: SIP_Version; - : SIP_WS; - status: SIP_Status; - : SIP_WS; - reason: SIP_TO_EOL; + version: SIP_Version; + : SIP_WS; + status: SIP_Status; + : SIP_WS; + reason: SIP_TO_EOL; } &oneline; type SIP_Status = record { - stat_str: RE/[0-9]{3}/; + stat_str: RE/[0-9]{3}/; } &let { - stat_num: int = bytestring_to_int(stat_str, 10); + stat_num: int = bytestring_to_int(stat_str, 10); }; type SIP_Version = record { - : "SIP/"; - vers_str: RE/[0-9]+\.[0-9]+/; + : "SIP/"; + vers_str: RE/[0-9]+\.[0-9]+/; } &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_Message = record { - headers: SIP_Headers; - body: SIP_Body; + headers: SIP_Headers; + body: SIP_Body; }; type SIP_HEADER_NAME = RE/[^: \t]+/; type SIP_Header = record { - name: SIP_HEADER_NAME; - : SIP_COLON; - : SIP_WS; - value: SIP_TO_EOL; - : SIP_EOL; + name: SIP_HEADER_NAME; + : SIP_COLON; + : SIP_WS; + value: SIP_TO_EOL; + : SIP_EOL; } &oneline &byteorder=bigendian; type SIP_Body = record { - body: bytestring &length = $context.flow.get_content_length(); + body: bytestring &length = $context.flow.get_content_length(); };