From 9edbf3e53c849635de62042afc82c0c5d0e128fc Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 19 Oct 2012 14:02:35 -0500 Subject: [PATCH 01/27] Add GPRS Tunnelling Protocol (GTPv1) decapsulation. This currently supports automatic decapsulation of GTP-U packets on UDP port 2152. The GTPv1 headers for such tunnels can be inspected by handling the "gtpv1_g_pdu_packet" event, which has a parameter of type "gtpv1_hdr". Analyzer and test cases are derived from submissions by Carsten Langer. Addresses #690. --- scripts/base/frameworks/tunnels/main.bro | 5 +- scripts/base/init-bare.bro | 50 ++++++ src/Analyzer.cc | 4 + src/AnalyzerTags.h | 1 + src/CMakeLists.txt | 3 + src/GTPv1.cc | 24 +++ src/GTPv1.h | 29 ++++ src/NetVar.cc | 2 + src/NetVar.h | 1 + src/const.bif | 2 + src/event.bif | 15 +- src/gtpv1-analyzer.pac | 161 ++++++++++++++++++ src/gtpv1-protocol.pac | 27 +++ src/gtpv1.pac | 10 ++ src/types.bif | 1 + .../conn.log | 12 ++ .../http.log | 11 ++ .../tunnel.log | 13 ++ .../core.tunnels.gtp.false_gtp/conn.log | 10 ++ .../core.tunnels.gtp.false_gtp/dns.log | 10 ++ .../core.tunnels.gtp.inner_ipv6/conn.log | 12 ++ .../core.tunnels.gtp.inner_ipv6/tunnel.log | 11 ++ .../core.tunnels.gtp.inner_teredo/conn.log | 26 +++ .../core.tunnels.gtp.inner_teredo/tunnel.log | 27 +++ .../core.tunnels.gtp.non_recursive/out | 1 + .../conn.log | 11 ++ .../core.tunnels.gtp.opt_header/conn.log | 11 ++ .../Baseline/core.tunnels.gtp.opt_header/out | 31 ++++ .../core.tunnels.gtp.opt_header/tunnel.log | 11 ++ .../core.tunnels.gtp.outer_ip_frag/conn.log | 11 ++ .../core.tunnels.gtp.outer_ip_frag/http.log | 10 ++ .../core.tunnels.gtp.outer_ip_frag/tunnel.log | 11 ++ .../dpd.log | 10 ++ .../tunnel.log | 11 ++ .../Traces/tunnels/gtp/gtp10_not_0xff.pcap | Bin 0 -> 258 bytes .../gtp1_gn_normal_incl_fragmentation.pcap | Bin 0 -> 68590 bytes .../tunnels/gtp/gtp2_different_udp_port.pcap | Bin 0 -> 75398 bytes .../Traces/tunnels/gtp/gtp3_false_gtp.pcap | Bin 0 -> 122 bytes .../tunnels/gtp/gtp4_udp_2152_inside.pcap | Bin 0 -> 1020 bytes .../Traces/tunnels/gtp/gtp6_gtp_0x32.pcap | Bin 0 -> 5492 bytes .../btest/Traces/tunnels/gtp/gtp7_ipv6.pcap | Bin 0 -> 292 bytes .../btest/Traces/tunnels/gtp/gtp8_teredo.pcap | Bin 0 -> 1550 bytes .../gtp9_unknown_or_too_short_payload.pcap | Bin 0 -> 13195 bytes .../core/tunnels/gtp/different_dl_and_ul.test | 10 ++ testing/btest/core/tunnels/gtp/false_gtp.test | 8 + .../btest/core/tunnels/gtp/inner_ipv6.test | 6 + .../btest/core/tunnels/gtp/inner_teredo.test | 7 + .../btest/core/tunnels/gtp/non_recursive.test | 11 ++ .../core/tunnels/gtp/not_user_plane_data.test | 9 + .../btest/core/tunnels/gtp/opt_header.test | 12 ++ .../btest/core/tunnels/gtp/outer_ip_frag.test | 11 ++ .../tunnels/gtp/unknown_or_too_short.test | 13 ++ 52 files changed, 670 insertions(+), 2 deletions(-) create mode 100644 src/GTPv1.cc create mode 100644 src/GTPv1.h create mode 100644 src/gtpv1-analyzer.pac create mode 100644 src/gtpv1-protocol.pac create mode 100644 src/gtpv1.pac create mode 100644 testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/http.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/tunnel.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.false_gtp/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.false_gtp/dns.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/tunnel.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.inner_teredo/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.inner_teredo/tunnel.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.non_recursive/out create mode 100644 testing/btest/Baseline/core.tunnels.gtp.not_user_plane_data/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.opt_header/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.opt_header/out create mode 100644 testing/btest/Baseline/core.tunnels.gtp.opt_header/tunnel.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/http.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/tunnel.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/dpd.log create mode 100644 testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/tunnel.log create mode 100755 testing/btest/Traces/tunnels/gtp/gtp10_not_0xff.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp1_gn_normal_incl_fragmentation.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp2_different_udp_port.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp3_false_gtp.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp4_udp_2152_inside.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp6_gtp_0x32.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp7_ipv6.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp8_teredo.pcap create mode 100755 testing/btest/Traces/tunnels/gtp/gtp9_unknown_or_too_short_payload.pcap create mode 100644 testing/btest/core/tunnels/gtp/different_dl_and_ul.test create mode 100644 testing/btest/core/tunnels/gtp/false_gtp.test create mode 100644 testing/btest/core/tunnels/gtp/inner_ipv6.test create mode 100644 testing/btest/core/tunnels/gtp/inner_teredo.test create mode 100644 testing/btest/core/tunnels/gtp/non_recursive.test create mode 100644 testing/btest/core/tunnels/gtp/not_user_plane_data.test create mode 100644 testing/btest/core/tunnels/gtp/opt_header.test create mode 100644 testing/btest/core/tunnels/gtp/outer_ip_frag.test create mode 100644 testing/btest/core/tunnels/gtp/unknown_or_too_short.test diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 0861559558..a3db7061d3 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -88,7 +88,10 @@ redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] }; const teredo_ports = { 3544/udp }; redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] }; -redef likely_server_ports += { ayiya_ports, teredo_ports }; +const gtpv1u_ports = { 2152/udp }; +redef dpd_config += { [ANALYZER_GTPV1] = [$ports = gtpv1u_ports] }; + +redef likely_server_ports += { ayiya_ports, teredo_ports, gtpv1u_ports }; event bro_init() &priority=5 { diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 70026394e9..e8f60dfc64 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1450,6 +1450,44 @@ type teredo_hdr: record { hdr: pkt_hdr; ##< IPv6 and transport protocol headers. }; +## A GTPv1 (GPRS Tunneling Protocol) header. +type gtpv1_hdr: record { + ## The 3-bit version field, which for GTPv1 should be 1. + version: count; + ## Protocol Type value differentiates GTP (value 1) from GTP' (value 0). + pt_flag: bool; + ## Reserved field, should be 0. + rsv: bool; + ## Extension Header flag. When 0, the *next_type* field may or may not + ## be present, but shouldn't be meaningful. When 1, *next_type* is + ## present and meaningful. + e_flag: bool; + ## Sequence Number flag. When 0, the *seq* field may or may not + ## be present, but shouldn't be meaningful. When 1, *seq* is + ## present and meaningful. + s_flag: bool; + ## N-PDU flag. When 0, the *n_pdu* field may or may not + ## be present, but shouldn't be meaningful. When 1, *n_pdu* is + ## present and meaningful. + pn_flag: bool; + ## Message Type. A value of 255 indicates user-plane data is encapsulated. + msg_type: count; + ## Length of the GTP packet payload (the rest of the packet following the + ## mandatory 8-byte GTP header). + length: count; + ## Tunnel Endpoint Identifier. Unambiguously identifies a tunnel endpoint + ## in receiving GTP-U or GTP-C protocol entity. + teid: count; + ## Sequence Number. Set if any *e_flag*, *s_flag*, or *pn_flag* field is + ## set. + seq: count &optional; + ## N-PDU Number. Set if any *e_flag*, *s_flag*, or *pn_flag* field is set. + n_pdu: count &optional; + ## Next Extension Header Type. Set if any *e_flag*, *s_flag*, or *pn_flag* + ## field is set. + next_type: count &optional; +}; + ## Definition of "secondary filters". A secondary filter is a BPF filter given as ## index in this table. For each such filter, the corresponding event is raised for ## all matching packets. @@ -2776,6 +2814,9 @@ export { ## Toggle whether to do IPv6-in-Teredo decapsulation. const enable_teredo = T &redef; + ## Toggle whether to do GTPv1 decapsulation. + const enable_gtpv1 = T &redef; + ## With this option set, the Teredo analysis will first check to see if ## other protocol analyzers have confirmed that they think they're ## parsing the right protocol and only continue with Teredo tunnel @@ -2792,6 +2833,15 @@ export { ## :bro:see:`Tunnel::yielding_teredo_decapsulation`. const delay_teredo_confirmation = T &redef; + ## With this set, the GTP analyzer waits until the most-recent upflow + ## and downflow packets are a valid GTPv1 encapsulation before + ## issuing :bro:see:`protocol_confirmation`. If it's false, the + ## first occurence of a packet with valid GTPv1 encapsulation causes + ## confirmation. Since the same inner connection can be carried + ## differing outer upflow/downflow connections, setting to false + ## may work better. + const delay_gtp_confirmation = F &redef; + ## How often to cleanup internal state for inactive IP tunnels. const ip_tunnel_timeout = 24hrs &redef; } # end export diff --git a/src/Analyzer.cc b/src/Analyzer.cc index 8c5573f96b..570b877881 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -40,6 +40,7 @@ #include "Syslog-binpac.h" #include "Teredo.h" #include "ConnSizeAnalyzer.h" +#include "GTPv1.h" // Keep same order here as in AnalyzerTag definition! const Analyzer::Config Analyzer::analyzer_configs[] = { @@ -139,6 +140,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { { AnalyzerTag::Teredo, "TEREDO", Teredo_Analyzer::InstantiateAnalyzer, Teredo_Analyzer::Available, 0, false }, + { AnalyzerTag::GTPv1, "GTPV1", + GTPv1_Analyzer::InstantiateAnalyzer, + GTPv1_Analyzer::Available, 0, false }, { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer, File_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index 4301de8f71..21f50f3b52 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -37,6 +37,7 @@ namespace AnalyzerTag { AYIYA, SOCKS, Teredo, + GTPv1, // Other File, Backdoor, InterConn, SteppingStone, TCPStats, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b77863d107..fa30d9ff55 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -203,6 +203,8 @@ binpac_target(dns.pac dns-protocol.pac dns-analyzer.pac) binpac_target(dns_tcp.pac dns.pac) +binpac_target(gtpv1.pac + gtpv1-protocol.pac gtpv1-analyzer.pac) binpac_target(http.pac http-protocol.pac http-analyzer.pac) binpac_target(ncp.pac) @@ -330,6 +332,7 @@ set(bro_SRCS Frame.cc Func.cc Gnutella.cc + GTPv1.cc HTTP.cc HTTP-binpac.cc Hash.cc diff --git a/src/GTPv1.cc b/src/GTPv1.cc new file mode 100644 index 0000000000..b7a0fdc664 --- /dev/null +++ b/src/GTPv1.cc @@ -0,0 +1,24 @@ +#include "GTPv1.h" + +GTPv1_Analyzer::GTPv1_Analyzer(Connection* conn) +: Analyzer(AnalyzerTag::GTPv1, conn) + { + interp = new binpac::GTPv1::GTPv1_Conn(this); + } + +GTPv1_Analyzer::~GTPv1_Analyzer() + { + delete interp; + } + +void GTPv1_Analyzer::Done() + { + Analyzer::Done(); + Event(udp_session_done); + } + +void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + interp->NewData(orig, data, data + len); + } diff --git a/src/GTPv1.h b/src/GTPv1.h new file mode 100644 index 0000000000..e111158833 --- /dev/null +++ b/src/GTPv1.h @@ -0,0 +1,29 @@ +#ifndef GTPv1_h +#define GTPv1_h + +#include "gtpv1_pac.h" + +class GTPv1_Analyzer : public Analyzer { +public: + GTPv1_Analyzer(Connection* conn); + virtual ~GTPv1_Analyzer(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new GTPv1_Analyzer(conn); } + + static bool Available() + { return BifConst::Tunnel::enable_gtpv1 && + BifConst::Tunnel::max_depth > 0; } + +protected: + friend class AnalyzerTimer; + void ExpireTimer(double t); + + binpac::GTPv1::GTPv1_Conn* interp; +}; + +#endif diff --git a/src/NetVar.cc b/src/NetVar.cc index 248ae15e1a..1783130f34 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -5,6 +5,7 @@ #include "Var.h" #include "NetVar.h" +RecordType* gtpv1_hdr_type; RecordType* conn_id; RecordType* endpoint; RecordType* endpoint_stats; @@ -308,6 +309,7 @@ void init_net_var() #include "input.bif.netvar_init" #include "reporter.bif.netvar_init" + gtpv1_hdr_type = internal_type("gtpv1_hdr")->AsRecordType(); conn_id = internal_type("conn_id")->AsRecordType(); endpoint = internal_type("endpoint")->AsRecordType(); endpoint_stats = internal_type("endpoint_stats")->AsRecordType(); diff --git a/src/NetVar.h b/src/NetVar.h index 2561fa0ad9..4bb2d2a7f9 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -8,6 +8,7 @@ #include "EventRegistry.h" #include "Stats.h" +extern RecordType* gtpv1_hdr_type; extern RecordType* conn_id; extern RecordType* endpoint; extern RecordType* endpoint_stats; diff --git a/src/const.bif b/src/const.bif index 7373403c11..ea7dc03817 100644 --- a/src/const.bif +++ b/src/const.bif @@ -15,8 +15,10 @@ const Tunnel::max_depth: count; const Tunnel::enable_ip: bool; const Tunnel::enable_ayiya: bool; const Tunnel::enable_teredo: bool; +const Tunnel::enable_gtpv1: bool; const Tunnel::yielding_teredo_decapsulation: bool; const Tunnel::delay_teredo_confirmation: bool; +const Tunnel::delay_gtp_confirmation: bool; const Tunnel::ip_tunnel_timeout: interval; const Threading::heartbeat_interval: interval; diff --git a/src/event.bif b/src/event.bif index 0c79c6159d..03df6a9071 100644 --- a/src/event.bif +++ b/src/event.bif @@ -577,6 +577,19 @@ event teredo_origin_indication%(outer: connection, inner: teredo_hdr%); ## it may become particularly expensive for real-time analysis. event teredo_bubble%(outer: connection, inner: teredo_hdr%); +## Generated for GTPv1 G-PDU packets. That is, packets with a UDP payload +## that includes a GTP header followed by an IPv4 or IPv6 packet. +## +## outer: The GTP outer tunnel connection. +## +## inner_gtp: The GTP header. +## +## inner_ip: The inner IP and transport layer packet headers. +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particularly expensive for real-time analysis. +event gtpv1_g_pdu_packet%(outer: connection, inner_gtp: gtpv1_hdr, inner_ip: pkt_hdr%); + ## Generated for every packet that has a non-empty transport-layer payload. ## This is a very low-level and expensive event that should be avoided when ## at all possible. It's usually infeasible to handle when processing even @@ -858,7 +871,7 @@ event udp_contents%(u: connection, is_orig: bool, contents: string%); ## Generated when a UDP session for a supported protocol has finished. Some of ## Bro's application-layer UDP analyzers flag the end of a session by raising ## this event. Currently, the analyzers for DNS, NTP, Netbios, Syslog, AYIYA, -## and Teredo support this. +## Teredo, and GTPv1 support this. ## ## u: The connection record for the corresponding UDP flow. ## diff --git a/src/gtpv1-analyzer.pac b/src/gtpv1-analyzer.pac new file mode 100644 index 0000000000..08fbdef74a --- /dev/null +++ b/src/gtpv1-analyzer.pac @@ -0,0 +1,161 @@ + +connection GTPv1_Conn(bro_analyzer: BroAnalyzer) + { + upflow = GTPv1_Flow(true); + downflow = GTPv1_Flow(false); + + %member{ + bool valid_orig; + bool valid_resp; + %} + + %init{ + valid_orig = valid_resp = false; + %} + + function valid(orig: bool): bool + %{ + return orig ? valid_orig : valid_resp; + %} + + function set_valid(orig: bool, val: bool): void + %{ + if ( orig ) + valid_orig = val; + else + valid_resp = val; + %} + } + +%code{ +inline void violate(const char* r, const BroAnalyzer& a, const bytestring& p) + { + a->ProtocolViolation(r, (const char*) p.data(), p.length()); + } +%} + +flow GTPv1_Flow(is_orig: bool) + { + datagram = GTPv1_Header withcontext(connection, this); + + function process_gtpv1(pdu: GTPv1_Header): bool + %{ + BroAnalyzer a = connection()->bro_analyzer(); + Connection *c = a->Conn(); + const EncapsulationStack* e = c->GetEncapsulation(); + + connection()->set_valid(is_orig(), false); + + if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) + { + reporter->Weird(c, "tunnel_depth"); + return false; + } + + if ( e && e->LastType() == BifEnum::Tunnel::GTPv1 ) + { + // GTP is never tunneled in GTP so, this must be a regular packet + violate("GTP-in-GTP", a, ${pdu.packet}); + return false; + } + + if ( ${pdu.version} != 1 ) + { + // Only know of GTPv1 with Version == 1 + violate("GTPv1 bad Version", a, ${pdu.packet}); + return false; + } + + if ( ! ${pdu.pt_flag} ) + { + // Not interested in GTP' + return false; + } + + if ( ${pdu.e_flag} ) + { + // TODO: can't currently parse past extension headers + return false; + } + + if ( ${pdu.msg_type} != 0xff ) + { + // Only interested in decapsulating user plane data beyond here. + return false; + } + + if ( ${pdu.packet}.length() < (int)sizeof(struct ip) ) + { + violate("Truncated GTPv1", a, ${pdu.packet}); + return false; + } + + const struct ip* ip = (const struct ip*) ${pdu.packet}.data(); + + if ( ip->ip_v != 4 && ip->ip_v != 6 ) + { + violate("non-IP packet in GTPv1", a, ${pdu.packet}); + return false; + } + + IP_Hdr* inner = 0; + int result = sessions->ParseIPPacket(${pdu.packet}.length(), + ${pdu.packet}.data(), ip->ip_v == 6 ? IPPROTO_IPV6 : IPPROTO_IPV4, + inner); + + if ( result == 0 ) + { + connection()->set_valid(is_orig(), true); + + if ( (! BifConst::Tunnel::delay_gtp_confirmation) || + (connection()->valid(true) && connection()->valid(false)) ) + a->ProtocolConfirmation(); + } + + else if ( result < 0 ) + violate("Truncated GTPv1", a, ${pdu.packet}); + + else + violate("GTPv1 payload length", a, ${pdu.packet}); + + if ( result != 0 ) + { + delete inner; + return false; + } + + if ( ::gtpv1_g_pdu_packet ) + { + RecordVal* rv = new RecordVal(gtpv1_hdr_type); + + rv->Assign(0, new Val(${pdu.version}, TYPE_COUNT)); + rv->Assign(1, new Val(${pdu.pt_flag}, TYPE_BOOL)); + rv->Assign(2, new Val(${pdu.rsv}, TYPE_BOOL)); + rv->Assign(3, new Val(${pdu.e_flag}, TYPE_BOOL)); + rv->Assign(4, new Val(${pdu.s_flag}, TYPE_BOOL)); + rv->Assign(5, new Val(${pdu.pn_flag}, TYPE_BOOL)); + rv->Assign(6, new Val(${pdu.msg_type}, TYPE_COUNT)); + rv->Assign(7, new Val(ntohs(${pdu.length}), TYPE_COUNT)); + rv->Assign(8, new Val(ntohl(${pdu.teid}), TYPE_COUNT)); + + if ( ${pdu.has_opt} ) + { + rv->Assign(9, new Val(ntohs(${pdu.opt_hdr.seq}), TYPE_COUNT)); + rv->Assign(10, new Val(${pdu.opt_hdr.n_pdu}, TYPE_COUNT)); + rv->Assign(11, new Val(${pdu.opt_hdr.next_type}, TYPE_COUNT)); + } + + BifEvent::generate_gtpv1_g_pdu_packet(a, c, rv, + inner->BuildPktHdrVal()); + } + + EncapsulatingConn ec(c, BifEnum::Tunnel::GTPv1); + + sessions->DoNextInnerPacket(network_time(), 0, inner, e, ec); + + return (result == 0) ? true : false; + %} + + }; + +refine typeattr GTPv1_Header += &let { proc_gtpv1 = $context.flow.process_gtpv1(this); }; diff --git a/src/gtpv1-protocol.pac b/src/gtpv1-protocol.pac new file mode 100644 index 0000000000..5bf31a48ee --- /dev/null +++ b/src/gtpv1-protocol.pac @@ -0,0 +1,27 @@ + +type GTPv1_Header = record { + flags: uint8; + msg_type: uint8; + length: uint16; + teid: uint32; + opt: case has_opt of { + true -> opt_hdr: GTPv1_Opt_Header; + false -> no_opt: empty; + } &requires(has_opt); + packet: bytestring &restofdata; + +} &let { + version: uint8 = (flags & 0xE0) >> 5; + pt_flag: bool = flags & 0x10; + rsv: bool = flags & 0x08; + e_flag: bool = flags & 0x04; + s_flag: bool = flags & 0x02; + pn_flag: bool = flags & 0x01; + has_opt: bool = flags & 0x07; +} &byteorder = littleendian; + +type GTPv1_Opt_Header = record { + seq: uint16; + n_pdu: uint8; + next_type: uint8; +} diff --git a/src/gtpv1.pac b/src/gtpv1.pac new file mode 100644 index 0000000000..d155ecfd67 --- /dev/null +++ b/src/gtpv1.pac @@ -0,0 +1,10 @@ +%include binpac.pac +%include bro.pac + +analyzer GTPv1 withcontext { + connection: GTPv1_Conn; + flow: GTPv1_Flow; +}; + +%include gtpv1-protocol.pac +%include gtpv1-analyzer.pac diff --git a/src/types.bif b/src/types.bif index 92cc8db551..b25f75c29a 100644 --- a/src/types.bif +++ b/src/types.bif @@ -177,6 +177,7 @@ enum Type %{ AYIYA, TEREDO, SOCKS, + GTPv1, %} type EncapsulatingConn: record; diff --git a/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/conn.log b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/conn.log new file mode 100644 index 0000000000..e2861b4ae1 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-03-55 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458850.321642 arKYeMETxOg 10.131.17.170 51803 173.199.115.168 80 tcp http 0.257902 1138 63424 S3 - 0 ShADadf 29 2310 49 65396 UWkUyAuUGXf,k6kgXLOoSKl +1333458850.325787 k6kgXLOoSKl 207.233.125.40 2152 167.55.105.244 2152 udp gtpv1 0.251127 65788 0 S0 - 0 D 49 67160 0 0 (empty) +1333458850.321642 UWkUyAuUGXf 167.55.105.244 5906 207.233.125.40 2152 udp gtpv1 0.257902 2542 0 S0 - 0 D 29 3354 0 0 (empty) +#close 2012-10-19-17-03-55 diff --git a/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/http.log b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/http.log new file mode 100644 index 0000000000..66b17e1200 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/http.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open 2012-10-19-17-03-55 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1333458850.340368 arKYeMETxOg 10.131.17.170 51803 173.199.115.168 80 1 GET cdn.epicgameads.com /ads/flash/728x90_nx8com.swf?clickTAG=http://www.epicgameads.com/ads/bannerclickPage.php?id=e3ubwU6IF&pd=1&adid=0&icpc=1&axid=0&uctt=1&channel=4&cac=1&t=728x90&cb=1333458879 http://www.epicgameads.com/ads/banneriframe.php?id=e3ubwU6IF&t=728x90&channel=4&cb=1333458905296 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 0 31461 200 OK - - - (empty) - - - application/x-shockwave-flash - - +1333458850.399501 arKYeMETxOg 10.131.17.170 51803 173.199.115.168 80 2 GET cdn.epicgameads.com /ads/flash/728x90_nx8com.swf?clickTAG=http://www.epicgameads.com/ads/bannerclickPage.php?id=e3ubwU6IF&pd=1&adid=0&icpc=1&axid=0&uctt=1&channel=0&cac=1&t=728x90&cb=1333458881 http://www.epicgameads.com/ads/banneriframe.php?id=e3ubwU6IF&t=728x90&cb=1333458920207 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) 0 31461 200 OK - - - (empty) - - - application/x-shockwave-flash - - +#close 2012-10-19-17-03-55 diff --git a/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/tunnel.log new file mode 100644 index 0000000000..233ad1c850 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.different_dl_and_ul/tunnel.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-17-03-55 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458850.321642 UWkUyAuUGXf 167.55.105.244 5906 207.233.125.40 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.325787 k6kgXLOoSKl 207.233.125.40 2152 167.55.105.244 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.579544 k6kgXLOoSKl 207.233.125.40 2152 167.55.105.244 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.579544 UWkUyAuUGXf 167.55.105.244 5906 207.233.125.40 2152 Tunnel::GTPv1 Tunnel::CLOSE +#close 2012-10-19-17-03-55 diff --git a/testing/btest/Baseline/core.tunnels.gtp.false_gtp/conn.log b/testing/btest/Baseline/core.tunnels.gtp.false_gtp/conn.log new file mode 100644 index 0000000000..1234558195 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.false_gtp/conn.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-07-44 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458871.219794 UWkUyAuUGXf 10.131.24.6 2152 195.178.38.3 53 udp dns - - - S0 - 0 D 1 64 0 0 (empty) +#close 2012-10-19-17-07-44 diff --git a/testing/btest/Baseline/core.tunnels.gtp.false_gtp/dns.log b/testing/btest/Baseline/core.tunnels.gtp.false_gtp/dns.log new file mode 100644 index 0000000000..a293d6ff6a --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.false_gtp/dns.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#open 2012-10-19-17-07-44 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected +#types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool +1333458871.219794 UWkUyAuUGXf 10.131.24.6 2152 195.178.38.3 53 udp 27595 abcd.efg.hijklm.nm 1 C_INTERNET 1 A - - F F T F 0 - - F +#close 2012-10-19-17-07-44 diff --git a/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/conn.log b/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/conn.log new file mode 100644 index 0000000000..326205172a --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-21-27 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458851.770000 arKYeMETxOg fe80::224c:4fff:fe43:414c 1234 ff02::1:3 5355 udp dns - - - S0 - 0 D 1 80 0 0 UWkUyAuUGXf +1333458851.770000 UWkUyAuUGXf 118.92.124.41 2152 118.92.124.72 2152 udp gtpv1 0.199236 152 0 S0 - 0 D 2 208 0 0 (empty) +1333458851.969236 k6kgXLOoSKl fe80::224c:4fff:fe43:414c 133 ff02::2 134 icmp - - - - OTH - 0 - 1 56 0 0 UWkUyAuUGXf +#close 2012-10-19-17-21-27 diff --git a/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/tunnel.log new file mode 100644 index 0000000000..dfae2ba269 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.inner_ipv6/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-17-21-27 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458851.770000 UWkUyAuUGXf 118.92.124.41 2152 118.92.124.72 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458851.969236 UWkUyAuUGXf 118.92.124.41 2152 118.92.124.72 2152 Tunnel::GTPv1 Tunnel::CLOSE +#close 2012-10-19-17-21-27 diff --git a/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/conn.log b/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/conn.log new file mode 100644 index 0000000000..9c3e1f6f66 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/conn.log @@ -0,0 +1,26 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-34-25 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458850.037956 qCaWGmzFtM5 10.131.112.102 51403 94.245.121.253 3544 udp teredo - - - SHR - 0 d 0 0 1 84 GSxOnSLghOa +1333458850.040098 70MGiRM1Qf4 174.94.190.229 2152 190.104.181.57 2152 udp gtpv1 0.003698 192 0 S0 - 0 D 2 248 0 0 (empty) +1333458850.016620 nQcgTWjvg4c 172.24.16.121 61901 94.245.121.251 3544 udp teredo - - - S0 - 0 D 1 80 0 0 k6kgXLOoSKl +1333458850.029781 FrJExwHcSal 172.24.16.67 52298 94.245.121.253 3544 udp teredo - - - S0 - 0 D 1 88 0 0 TEfuqmmG4bh +1333458850.035456 VW0XPVINV8a 190.104.181.210 2152 190.104.181.125 2152 udp gtpv1 0.000004 194 0 S0 - 0 D 2 250 0 0 (empty) +1333458850.016620 k6kgXLOoSKl 174.94.190.229 2152 190.104.181.62 2152 udp gtpv1 0.016267 88 92 SF - 0 Dd 1 116 1 120 (empty) +1333458850.029781 TEfuqmmG4bh 190.104.181.254 2152 190.104.181.62 2152 udp gtpv1 0.000002 192 0 S0 - 0 D 2 248 0 0 (empty) +1333458850.035460 iE6yhOq3SF 172.27.159.9 63912 94.245.121.254 3544 udp teredo - - - S0 - 0 D 1 89 0 0 VW0XPVINV8a +1333458850.037956 GSxOnSLghOa 190.104.181.57 2152 190.104.181.222 2152 udp gtpv1 - - - S0 - 0 D 1 120 0 0 (empty) +1333458850.014199 UWkUyAuUGXf 174.94.190.213 2152 190.104.181.57 2152 udp gtpv1 - - - S0 - 0 D 1 124 0 0 (empty) +1333458850.040098 h5DsfNtYzi1 172.24.203.81 54447 65.55.158.118 3544 udp teredo 0.003698 120 0 S0 - 0 D 2 176 0 0 70MGiRM1Qf4 +1333458850.029783 5OKnoww6xl4 172.24.16.67 52298 65.55.158.118 3544 udp teredo - - - S0 - 0 D 1 88 0 0 TEfuqmmG4bh +1333458850.032887 3PKsZ2Uye21 10.131.42.160 62069 94.245.121.253 3544 udp teredo - - - SHR - 0 d 0 0 1 84 k6kgXLOoSKl +1333458850.014199 arKYeMETxOg 172.24.204.200 56528 65.55.158.118 3544 udp teredo - - - S0 - 0 D 1 88 0 0 UWkUyAuUGXf +1333458850.035456 fRFu0wcOle6 172.27.159.9 63912 94.245.121.253 3544 udp teredo - - - S0 - 0 D 1 89 0 0 VW0XPVINV8a +1333458850.016620 j4u32Pc5bif 2001:0:5ef5:79fb:38b8:1695:2b37:be8e 128 2002:2571:c817::2571:c817 129 icmp - - - - OTH - 0 - 1 52 0 0 nQcgTWjvg4c +1333458850.035456 qSsw6ESzHV4 fe80::ffff:ffff:fffe 133 ff02::2 134 icmp - 0.000004 0 0 OTH - 0 - 2 96 0 0 fRFu0wcOle6,iE6yhOq3SF +#close 2012-10-19-17-34-25 diff --git a/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/tunnel.log new file mode 100644 index 0000000000..904fcc7db6 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.inner_teredo/tunnel.log @@ -0,0 +1,27 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-17-34-25 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458850.014199 UWkUyAuUGXf 174.94.190.213 2152 190.104.181.57 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.016620 k6kgXLOoSKl 174.94.190.229 2152 190.104.181.62 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.016620 nQcgTWjvg4c 172.24.16.121 61901 94.245.121.251 3544 Tunnel::TEREDO Tunnel::DISCOVER +1333458850.029781 TEfuqmmG4bh 190.104.181.254 2152 190.104.181.62 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.035456 VW0XPVINV8a 190.104.181.210 2152 190.104.181.125 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.035456 fRFu0wcOle6 172.27.159.9 63912 94.245.121.253 3544 Tunnel::TEREDO Tunnel::DISCOVER +1333458850.035460 iE6yhOq3SF 172.27.159.9 63912 94.245.121.254 3544 Tunnel::TEREDO Tunnel::DISCOVER +1333458850.037956 GSxOnSLghOa 190.104.181.57 2152 190.104.181.222 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.040098 70MGiRM1Qf4 174.94.190.229 2152 190.104.181.57 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.043796 70MGiRM1Qf4 174.94.190.229 2152 190.104.181.57 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 nQcgTWjvg4c 172.24.16.121 61901 94.245.121.251 3544 Tunnel::TEREDO Tunnel::CLOSE +1333458850.043796 VW0XPVINV8a 190.104.181.210 2152 190.104.181.125 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 k6kgXLOoSKl 174.94.190.229 2152 190.104.181.62 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 TEfuqmmG4bh 190.104.181.254 2152 190.104.181.62 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 iE6yhOq3SF 172.27.159.9 63912 94.245.121.254 3544 Tunnel::TEREDO Tunnel::CLOSE +1333458850.043796 GSxOnSLghOa 190.104.181.57 2152 190.104.181.222 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 UWkUyAuUGXf 174.94.190.213 2152 190.104.181.57 2152 Tunnel::GTPv1 Tunnel::CLOSE +1333458850.043796 fRFu0wcOle6 172.27.159.9 63912 94.245.121.253 3544 Tunnel::TEREDO Tunnel::CLOSE +#close 2012-10-19-17-34-25 diff --git a/testing/btest/Baseline/core.tunnels.gtp.non_recursive/out b/testing/btest/Baseline/core.tunnels.gtp.non_recursive/out new file mode 100644 index 0000000000..a299c4d592 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.non_recursive/out @@ -0,0 +1 @@ +protocol_violation, [orig_h=74.125.216.149, orig_p=2152/udp, resp_h=10.131.138.69, resp_p=2152/udp], GTP-in-GTP [n\xd9'|\x00\x00\x01\xb6[\xf6\xdc0\xb7d\xe5\xe6\xa76\x91\xfbk\x0e\x02\xc8A\x05\xa8\xe6\xf3Gi\x80(]\xcew\x84\xae}\xd2...] diff --git a/testing/btest/Baseline/core.tunnels.gtp.not_user_plane_data/conn.log b/testing/btest/Baseline/core.tunnels.gtp.not_user_plane_data/conn.log new file mode 100644 index 0000000000..ad6e4fb2c4 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.not_user_plane_data/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-46-48 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458850.532814 UWkUyAuUGXf 247.56.43.90 2152 247.56.43.248 2152 udp - - - - S0 - 0 D 1 52 0 0 (empty) +1333458850.867091 arKYeMETxOg 247.56.43.214 2152 237.56.101.238 2152 udp - 0.028676 12 14 SF - 0 Dd 1 40 1 42 (empty) +#close 2012-10-19-17-46-48 diff --git a/testing/btest/Baseline/core.tunnels.gtp.opt_header/conn.log b/testing/btest/Baseline/core.tunnels.gtp.opt_header/conn.log new file mode 100644 index 0000000000..9f250903f2 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.opt_header/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-17-19-16 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458852.011535 arKYeMETxOg 10.222.10.10 44960 173.194.69.188 5228 tcp ssl 0.573499 704 1026 S1 - 0 ShADad 17 1604 14 1762 UWkUyAuUGXf +1333458852.011535 UWkUyAuUGXf 79.188.154.91 2152 243.149.173.198 2152 udp gtpv1 0.573499 1740 1930 SF - 0 Dd 17 2216 14 2322 (empty) +#close 2012-10-19-17-19-16 diff --git a/testing/btest/Baseline/core.tunnels.gtp.opt_header/out b/testing/btest/Baseline/core.tunnels.gtp.opt_header/out new file mode 100644 index 0000000000..7feeb2a110 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.opt_header/out @@ -0,0 +1,31 @@ +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=60, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=60, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=64, teid=159098, seq=0, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=170, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=56, teid=159098, seq=1, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=194, teid=159098, seq=2, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=111, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=56, teid=159098, seq=3, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=89, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=56, teid=159098, seq=4, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=93, teid=159098, seq=5, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=457, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=157, teid=159098, seq=6, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=173, teid=159098, seq=7, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=137, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=56, teid=159098, seq=8, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=157, teid=159098, seq=9, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=189, teid=159098, seq=10, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=173, teid=159098, seq=11, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=205, teid=159098, seq=12, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=T, pn_flag=F, msg_type=255, length=189, teid=159098, seq=13, n_pdu=0, next_type=0] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] +gtpv1_packet, [version=1, pt_flag=T, rsv=F, e_flag=F, s_flag=F, pn_flag=F, msg_type=255, length=52, teid=1980578736, seq=, n_pdu=, next_type=] diff --git a/testing/btest/Baseline/core.tunnels.gtp.opt_header/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.opt_header/tunnel.log new file mode 100644 index 0000000000..a421f399ec --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.opt_header/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-17-19-16 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458852.011535 UWkUyAuUGXf 79.188.154.91 2152 243.149.173.198 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458852.585034 UWkUyAuUGXf 79.188.154.91 2152 243.149.173.198 2152 Tunnel::GTPv1 Tunnel::CLOSE +#close 2012-10-19-17-19-16 diff --git a/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/conn.log b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/conn.log new file mode 100644 index 0000000000..b5f61564cf --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2012-10-19-16-44-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1333458850.364667 arKYeMETxOg 10.131.47.185 1923 79.101.110.141 80 tcp http 0.069783 2100 56702 SF - 0 ShADadfF 27 3204 41 52594 UWkUyAuUGXf +1333458850.364667 UWkUyAuUGXf 239.114.155.111 2152 63.94.149.181 2152 udp gtpv1 0.069813 3420 52922 SF - 0 Dd 27 4176 41 54070 (empty) +#close 2012-10-19-16-44-02 diff --git a/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/http.log b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/http.log new file mode 100644 index 0000000000..8a994d56af --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/http.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open 2012-10-19-16-44-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1333458850.375568 arKYeMETxOg 10.131.47.185 1923 79.101.110.141 80 1 GET o-o.preferred.telekomrs-beg1.v2.lscache8.c.youtube.com /videoplayback?upn=MTU2MDY5NzQ5OTM0NTI3NDY4NDc&sparams=algorithm,burst,cp,factor,id,ip,ipbits,itag,source,upn,expire&fexp=912300,907210&algorithm=throttle-factor&itag=34&ip=212.0.0.0&burst=40&sver=3&signature=832FB1042E20780CFCA77A4DB5EA64AC593E8627.D1166C7E8365732E52DAFD68076DAE0146E0AE01&source=youtube&expire=1333484980&key=yt1&ipbits=8&factor=1.25&cp=U0hSSFRTUl9NSkNOMl9MTVZKOjh5eEN2SG8tZF84&id=ebf1e932d4bd1286&cm2=1 http://s.ytimg.com/yt/swfbin/watch_as3-vflqrJwOA.swf Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko; X-SBLSP) Chrome/17.0.963.83 Safari/535.11 0 56320 206 Partial Content - - - (empty) - - - application/octet-stream - - +#close 2012-10-19-16-44-02 diff --git a/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/tunnel.log new file mode 100644 index 0000000000..54c4acd0d6 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.outer_ip_frag/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-16-44-02 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458850.364667 UWkUyAuUGXf 239.114.155.111 2152 63.94.149.181 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458850.434480 UWkUyAuUGXf 239.114.155.111 2152 63.94.149.181 2152 Tunnel::GTPv1 Tunnel::CLOSE +#close 2012-10-19-16-44-02 diff --git a/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/dpd.log b/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/dpd.log new file mode 100644 index 0000000000..221fa16f4f --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/dpd.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dpd +#open 2012-10-19-17-38-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto analyzer failure_reason +#types time string addr port addr port enum string string +1333458853.075889 UWkUyAuUGXf 173.86.159.28 2152 213.72.147.186 2152 udp GTPV1 Truncated GTPv1 [E\x00\x05\xc8G\xea@\x00\x80\x06\xb6\x83\x0a\x83w&\xd9\x14\x9c\x04\xd9\xc2\x00P\xddh\xb4\x8f41eVP\x10\x10\xe0u\xcf\x00\x00...] +#close 2012-10-19-17-38-54 diff --git a/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/tunnel.log b/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/tunnel.log new file mode 100644 index 0000000000..659090a581 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.gtp.unknown_or_too_short/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2012-10-19-17-38-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1333458853.034734 UWkUyAuUGXf 173.86.159.28 2152 213.72.147.186 2152 Tunnel::GTPv1 Tunnel::DISCOVER +1333458853.108391 UWkUyAuUGXf 173.86.159.28 2152 213.72.147.186 2152 Tunnel::GTPv1 Tunnel::CLOSE +#close 2012-10-19-17-38-54 diff --git a/testing/btest/Traces/tunnels/gtp/gtp10_not_0xff.pcap b/testing/btest/Traces/tunnels/gtp/gtp10_not_0xff.pcap new file mode 100755 index 0000000000000000000000000000000000000000..575edf55f9fd21ae83c90cbf8363d92b995b877f GIT binary patch literal 258 zcmca|c+)~A1{MYw`2U}Qff2}A^u5a8PmzPc3CIRv28K8W#(OWeduTHr;9ziNU@!@a zWMKFws50lfg?1DW|KP~r$Y4;2oM|M*AOO|?Bm@?GQVwWkV7YSQs{_bHVQXFn8=yD{ zGcfS5uX)k&;PZ+7AAlzAV9;3p0VpFF{~T!AwYL_j@4zOCcmx_TLLB%n6RZtLfXotK xjcgXkbqs2!Ew_SPw}U|oWY#;uwNF6ifXoA%C1&Mi#Kgb`G6iH7ACTr_000LSMXdk; literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp1_gn_normal_incl_fragmentation.pcap b/testing/btest/Traces/tunnels/gtp/gtp1_gn_normal_incl_fragmentation.pcap new file mode 100755 index 0000000000000000000000000000000000000000..7ca3b3b05dc3d3b18330ef1ae226daa2b5402d19 GIT binary patch literal 68590 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp2_different_udp_port.pcap b/testing/btest/Traces/tunnels/gtp/gtp2_different_udp_port.pcap new file mode 100755 index 0000000000000000000000000000000000000000..fda97cdaf536a663c80cba7e531b61a08efd47ae GIT binary patch literal 75398 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 J@^V3Pi~xMY9l!tp literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp4_udp_2152_inside.pcap b/testing/btest/Traces/tunnels/gtp/gtp4_udp_2152_inside.pcap new file mode 100755 index 0000000000000000000000000000000000000000..ca67a370460ec34d5aa8bd071050d7b541b12f01 GIT binary patch literal 1020 zcmVu%X6d;kCewp;exFt=po=BGB1`)dvY z$Uz0D=JQ8sfGAzgcZ9Be(nojiMK%*dw@9aeaSg$7Ks2zq>j^wm;)C(z&yZPTn}Twj zJ~S}oRVGlywNK$=8@6}dit$Z(H&#!3+t$BKJZ%@9qeMN%eC*O5$xbZ ztIdiDR7m-fH5sefNTj-UFhP@wh>3Uu&7|ZbcZfXeW*!9^vj`73kK|062ol+~Rjq;2 z;LM)`Av*?lwa;sNbWBQ}>hgED-v#9@8ToCOE1mbsmX#@t!eW(Vm3dmTM~Chrf6Lc* zF15aQH1T9`D8#|qls-CyvPN`9m$OLaG&|ls&wFpIJflabROvqXG9JmIVtIEkN#yI_ zc%LQjQ_VzUBAtq;;9%YYikZFQvJ+&an9w4p3Od|ndwiPz>6Pl3dsO$_rPjZ6cf_(# zbd2#Pw#G$+LKXKg31xt$RZ!U;>zmufh3dVtl)zqA%9>t~t+=tgU5F-qX_76)-ldA2 ze5F&XHb%#k{pRy^eWuj*Vd5erCot-!^w0-U=4CGSytsZ0;6oXmAxo#?kV2itT{yed zNTZjnT6zo|M>3d&kwn`(ZhEE~y2CBck{G@|M_SuVWP)8IT!~)t54sV%T7CDjB0Uz7 z!lul+Zm!1ryH6gU>vJ6rL(XM#M|wx9t2~+EEbyho)#P#&y$+EEcX?8|oYR!k=^&+onBS9 qWv+4D9zzITUcP}UH9SpKb~9uWZIiZ6SUPa8-Q9PhZN0OXrL&h9E%pWg literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp6_gtp_0x32.pcap b/testing/btest/Traces/tunnels/gtp/gtp6_gtp_0x32.pcap new file mode 100755 index 0000000000000000000000000000000000000000..7dd3905c5d7a7f9b85aff9dd6d58c139d13003b4 GIT binary patch literal 5492 zcmai&2{@E%AI6`-*q1PtPKb(xBun%mDqARPAxn}Z;xOqX<%A<^${txlQj#?#6=f|n z%5t29Y~>(iNtTlDdERg}Grsv;*K=LAd4KPH|L^;G-kH{_qI5dI0G7WN7XiS*A2Mfr zjJUP};10h>3jlVedxIf8Q!k&5GXrgBVBZo9fExFDDWj*?t*7F0Ynh#yoq=IUp4=i( z`-4NZKpXx!eYYmiWQ-!PzGr34t<-*+pGG*PB_W-Tu9rqPKYnQp06GSIF#{blD_{@n zLBGe*)8i0*4Q+ZTMwg^X--FS4{}(;5@>lw0_Fw7v8~}*$7ia-s2XOBPOZ231&!Kin z;K*qYz!dk^2&5a`0jAx!zF&S3XaYJnAM_e+W}p@Z|4)i>VH9accR@InpQg@WBMd#r zNaImJ zP1i!y$eXKD1%17TVVstzt%%A`j{}}Ca&GiEBcGWUM8n|DpML)7S;{jJwdCfahubD4MKJM{@x4IHJ7ctVVmx^$sH;uw$sJAn#N0{nm% zumS}j54Hh3j5iT4(9Yrw{!L}bV1J)PQ3C~j`e)B zsVvpPli_~N#_gYm^8UZmI{^V+4u?Y*l{=fcXXFIVR{!?n><3JJq`O>F$C8OE0*Xq? z;q(dLeKu4_w5E!#PtguBOs@#7Jp2WDAaIzDM!tJCqNMS}lO>HZ-`ZHd1<8{pBM9?- z2j*L$5|(!DbF`@P9n;f-sN6YZ)Qcf{FyFr~<@@(^9W39St5OAh z74(ExsAGuwi%lXL?uOE>QSTys9H&kweA&f2KH_S#%~-gC@gZ~UQRi!s|H#yNafCkN zFmy=~8=m7wH_RnKPa~v8mMAJC$z)N{s~=wpDg9DNk6}@nr-;fO7*aD7Qgs+5WL1q2 z7YRmX43WbY=|MO&2`wtCe1~r%tC&W~tU4Lu1+B7LvdSu57qe=D!YVUtK+vkiqGhWh zcoA6uW=VATFU|n>c-%@FG+6d>O!1Xa`zU&GkQLWg&oJpEvu4YbKNt@$(S+EHm4r?H+HXtYlHjoX8*>`_Tyl8THlXtXBXC0 z=CDQI<*%D-|Eb%)H^uNU&5g&kR;(CQ~EC&4H-bwD8~? z+z!#AObTvv(gIO`y!w@jYrhmLw}`9znG{@I`aVRxdT~{%psx&F5;+wbf{W}BRClRM zd!x*kubE7r8(lcV$;F?*?vzq8p*9s9yvFCvmE=@E{l18uUPoGgs4wd8x11>T5Gf)F z%l7_r4NuH7^*Uh0b-Z5pR&LW7F0r@$aXwCUea2t!vXP30(z6^MbczynrHtH(W^B`Y z0=e#+jhkAHrXOXix`_C*<8T!+UquFYeiVrNN@yMM zDm*l+Qc|UAW#mJrZexADTRQakY7j5KbHBH?t-7x(80{^#3

M5<|q0OHa6L-9D zsH)n{61cbNv0TLW|18)r{n=QmH4`d682FdOTlq)rjCWjd8P9q8w?MI*jjZB_(#TKqfy2%> zihJkowmn*i5uTfo?!2N99$>P?aq$_VJU-gO2h%20z(W zVrkHQ5u5O&gBAysV={EpE!!UK&0f#ry^mdX(9zGTsv?gRzfqtx&XFfed(TZPBT-pv zTS@maBsXLyBaQ83HU<@YUi{Z$1Iq10AKOkSp21}~)ER8$(RT9W^GdPxYJ_;q5VhEV z7IhA0NR4|gmnPK!qwZiuLn*pogQ?ay~ROH{at+2^lNEf5u@*7#G=aevE^@b0(wIUf&<#Pdgo z`10vV`^~DG?92LA-|0SKl}>UJ7rBZAu0Q#nP?o3uP0DSPtlX5RImQi%JIm&bUZp^DV?TB>1~)&2Y5Vw zR;pS~DeniEQVT>r-@!zq{_SfK+2Ic|a&EooO8r@u>VFa=UtN_9>tFb4nM{yEWUT%s z4+}Ue?hT|b%JrmG2RWJB6!?wwGiYdaFZ{Vcc*!05an9)JjZI?PTn{sy_ajO%W$R27 zG4VzQOzoJVdu$q>Al9lm{6(uJnVYzl{)LFLx1pk92O6%xB^4ASB(b)akr7-yi$>f*S{aD%kU~%DNS9X{yCf}Dr ze$=vjMK5ak9zwiY)&iZX9|^_%3Rfqko=2Xs&N=TWc23-W5cj$7(Atk$nZ(ORr(9=i z3#3y?x3&*_{xGjt&3$4^zXqf4DIgrGxUlV&X-~>Rd6GQ-QE$g)s;cHBy8I7^8_fj zE)2f^gVVMlmwSY9S?(_Q(Dd`sn;^X$=18$IOXsf*IUdcDhsU0s={%jM8Bi`YeaME@ zv?E8_ZRbl;;Y48RwnL+(q<0678>jGAwDe|yOYJG@*S#aSx*Dtvxc;^F`Fv9GqAW{$ z<#RtJX-3`hnDVzqeBn_Zhd58Y>egLk6LDuz)~cJ)zU4V4)>0H2B);uyTEZ=H65dk8 zZu4Zb=-Ae}+t>7J@3pk_-$Ql`LOW=LUk$TEfy@q4UFS;pIhMljhS}jtVMo%k9R~W; zcKDTB6A%2|A4TlZ?5J|FsAigOjx)26oK?^$U$-Ovx}*-b4O8e$yRTWU4d;JvaIM43-K{ows^ z)b-E}TozY~Kha5Tv9^+}xKouyr~h=WWPT_e*8R84G|oa+0dzhLW{{l^lxN|7>{MDq zaVj~eGuW}CQ|VF8Pw6lPK{Y}IDMVGHO@$jOq^8lN9>Azvt5BmbssuGvoi=qHMopzj zHNvQz)YK!4h+0xeP2D$2)8VTamHhKYN{5XxD#t3+B#ipo3N;uyER7u2r%jE*sN|nB WQc_JYDmyjRUKCLu#;#C95cR(`itN<@ literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp7_ipv6.pcap b/testing/btest/Traces/tunnels/gtp/gtp7_ipv6.pcap new file mode 100755 index 0000000000000000000000000000000000000000..4f358bc374d6c0c69d4acd956cdca4f214cc233e GIT binary patch literal 292 zcmca|c+)~A1{MYw`2U}Qff2}A{JqNm!hUXsCLkMx85nrj*SzR>@cG344;&1x3=Adm zYzz!Gf>oYnF*TY%?7@-2k-?BK;kvhCK}X*GtRlY_nZ&k-??YFxAhha z0x(}jBLIVg+HYCm88U!E>{A1E#Bd)yJoS+%eDB3)Q3ZViN z$7L=?h$|P%y78H~fEoamxH?JgpwsS^Ri(ck6pcbq$!0md4Bo3HxKzT7a?a;=@_T2Q z<{FLZImvpzNUynAUq+BolaOv91fUsS4_dP0nIxO^2RM&2P+KHBL-$ZtjIwtq^W|jn zu?Un!s95_NltqXdNOtY4+QCkVg4s_4DDxRilheyKUS`>>N5`70C@Yq*TT-=a=}!Ra zsUS}j@-Tmd#w0p~t1g|@5e*V&A3g9BnKn?c+Fk|}m5ND=` z+h3U*hXDM<*&UP@Rg$Y>;_N<@#Q-zqj+w;>0|4B_DFKw1^@VLUqS4Q1!QYTC=Vtu9 zzg)`guB)31yUdwMu6UPVhL;$@N!O7klJzvU+D;{rN`+-C!uP2y+FQ9B94RlQ8>)t| z<#MVMZGEVUH*5EKu)s@y^IDG zb?7qEWiYb*$n?wRL#_w)iI%rKZ4*ax`GfXk0WE@~Ih$w(o@R5JXs@K>sbAkldHfSC zsC2nnKAxaj4%Q>h6WbVHORbozB^>2ynJlGRYD@T9rX-0*wf*4lc1q4A!Pk;@)mCYJ zT3B^ulev~IlkOU<4=>ccJcRqlzNuOhKUBc4Er05peL*R*?igEwx3xC1{eSU literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/gtp/gtp9_unknown_or_too_short_payload.pcap b/testing/btest/Traces/tunnels/gtp/gtp9_unknown_or_too_short_payload.pcap new file mode 100755 index 0000000000000000000000000000000000000000..a39026aeffb05b292694e195e75bbb71da192737 GIT binary patch literal 13195 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 +# @TEST-EXEC: btest-diff out + +# In telecoms there is never a GTP tunnel within another GTP tunnel. +# So if we find inside a GTP tunnel anohter IP/UDP packet with port 2152, +# it is just a UDP packet, but not another GTP tunnel. + +event protocol_violation(c: connection, atype: count, aid: count, reason: string) + { + print "protocol_violation", c$id, reason; + } diff --git a/testing/btest/core/tunnels/gtp/not_user_plane_data.test b/testing/btest/core/tunnels/gtp/not_user_plane_data.test new file mode 100644 index 0000000000..a6a3333360 --- /dev/null +++ b/testing/btest/core/tunnels/gtp/not_user_plane_data.test @@ -0,0 +1,9 @@ +# @TEST-EXEC: bro -r $TRACES/tunnels/gtp/gtp10_not_0xff.pcap +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: test ! -e tunnel.log + +# There are GTP tunnel packets, which do not contain user plane data. Only +# those with gtp.message==0xff contain user plane data. Other GTP packets +# without user plane data are echo request, echo reply, error indication +# and stop marker (not included in trace). Those non-user plane GTP +# packets are ignored for now. diff --git a/testing/btest/core/tunnels/gtp/opt_header.test b/testing/btest/core/tunnels/gtp/opt_header.test new file mode 100644 index 0000000000..b7100f2190 --- /dev/null +++ b/testing/btest/core/tunnels/gtp/opt_header.test @@ -0,0 +1,12 @@ +# @TEST-EXEC: bro -r $TRACES/tunnels/gtp/gtp6_gtp_0x32.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff tunnel.log + +# Some GTPv1 headers have some optional fields totaling to a 4-byte extension +# of the mandatory header. + +event gtpv1_g_pdu_packet(outer: connection, inner_gtp: gtpv1_hdr, inner_ip: pkt_hdr) + { + print "gtpv1_packet", inner_gtp; + } diff --git a/testing/btest/core/tunnels/gtp/outer_ip_frag.test b/testing/btest/core/tunnels/gtp/outer_ip_frag.test new file mode 100644 index 0000000000..b2badb9c1b --- /dev/null +++ b/testing/btest/core/tunnels/gtp/outer_ip_frag.test @@ -0,0 +1,11 @@ +# @TEST-EXEC: bro -C -r $TRACES/tunnels/gtp/gtp1_gn_normal_incl_fragmentation.pcap +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff tunnel.log + +# Normal GTP file, incl. TCP handshake and HTTP message. +# The inner IP packet is put into a GTP tunnel and as the original user payload +# is already 1500 byte, the tunneled packet incl. GTP/UDP/IP payload is +# bigger than 1500 byte and thus the outer IP must be fragmented, as seen here. +# (checksums are incorrect because packets were anonymized and tcprewrite +# seems to fail to correct the checksums when there's IP fragmentation). diff --git a/testing/btest/core/tunnels/gtp/unknown_or_too_short.test b/testing/btest/core/tunnels/gtp/unknown_or_too_short.test new file mode 100644 index 0000000000..e1b3d4ba20 --- /dev/null +++ b/testing/btest/core/tunnels/gtp/unknown_or_too_short.test @@ -0,0 +1,13 @@ +# @TEST-EXEC: bro -C -r $TRACES/tunnels/gtp/gtp9_unknown_or_too_short_payload.pcap +# @TEST-EXEC: btest-diff dpd.log +# @TEST-EXEC: btest-diff tunnel.log + +# Packet 11, epoch time 1333458853.075889 is malformed. Only 222 byte are +# captured, although according to the IP header a full packet should be +# available. In Sessions.cc this throws a weird message at line 710. +# Packet 12, epoch time 1333458853.075904 is malformed. The user plane +# packet is no IPv4 nor IPv6 packet. Very probably this is a follow up +# issue on a problem of the user plane packet before it was put into the +# tunnel. The user plane packet may got corrupt and then put into 2 tunnel +# packets, here packet 11 and 12, and in packet 12 the user plane data is +# part of the remainder of the broken user plane packet of packet 11. From 3e7fb3a659d617426259ac58bf282147a6d440e0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 19 Oct 2012 14:17:29 -0500 Subject: [PATCH 02/27] Add GTP tunnel analyzer memory leak unit test. --- testing/btest/core/leaks/gtp_opt_header.test | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 testing/btest/core/leaks/gtp_opt_header.test diff --git a/testing/btest/core/leaks/gtp_opt_header.test b/testing/btest/core/leaks/gtp_opt_header.test new file mode 100644 index 0000000000..76c65d5762 --- /dev/null +++ b/testing/btest/core/leaks/gtp_opt_header.test @@ -0,0 +1,15 @@ +# Needs perftools support. +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-GROUP: leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -r $TRACES/tunnels/gtp/gtp6_gtp_0x32.pcap %INPUT >out + +# Some GTPv1 headers have some optional fields totaling to a 4-byte extension +# of the mandatory header. + +event gtpv1_g_pdu_packet(outer: connection, inner_gtp: gtpv1_hdr, inner_ip: pkt_hdr) + { + print "gtpv1_packet", inner_gtp; + } From 7cf54b2541139bb62e8bb19240ab5f5f24f35f32 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 29 Oct 2012 12:15:48 -0500 Subject: [PATCH 03/27] Change binpac exceptions in AYIYA/GTP analyzers to do protocol_violation As opposed to creating weirds for e.g. "binpac::ExceptionOutOfBound". The protocol_violation will also result in the disabling of the analyzer by default. --- src/AYIYA.cc | 10 +++++++++- src/GTPv1.cc | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/AYIYA.cc b/src/AYIYA.cc index c525a73b6c..79fa44e743 100644 --- a/src/AYIYA.cc +++ b/src/AYIYA.cc @@ -20,5 +20,13 @@ void AYIYA_Analyzer::Done() void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - interp->NewData(orig, data, data + len); + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); + } } diff --git a/src/GTPv1.cc b/src/GTPv1.cc index b7a0fdc664..68b6f30a0c 100644 --- a/src/GTPv1.cc +++ b/src/GTPv1.cc @@ -20,5 +20,12 @@ void GTPv1_Analyzer::Done() void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - interp->NewData(orig, data, data + len); + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); + } } From e98343b5621bb38debded896a78404f1f7ff3bb3 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 30 Nov 2012 20:04:10 -0500 Subject: [PATCH 04/27] Remove hardcoded HTTP verbs from the analyzer (#741) --- scripts/base/protocols/http/main.bro | 14 ++++++++++ src/HTTP.cc | 42 ++++++++-------------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/scripts/base/protocols/http/main.bro b/scripts/base/protocols/http/main.bro index 21b4fb6113..ec8a5ffad8 100644 --- a/scripts/base/protocols/http/main.bro +++ b/scripts/base/protocols/http/main.bro @@ -94,6 +94,17 @@ export { "XROXY-CONNECTION", "PROXY-CONNECTION", } &redef; + + ## A list of HTTP methods. Other methods will generate a weird. + const http_methods: set[string] = { + "GET", "POST", "HEAD", "OPTIONS", + "PUT", "DELETE", "TRACE", "CONNECT", + # HTTP methods for distributed authoring: + "PROPFIND", "PROPPATCH", "MKCOL", + "COPY", "MOVE", "LOCK", "UNLOCK", + "POLL", "REPORT", "SUBSCRIBE", "BMOVE", + "SEARCH" + } &redef; ## Event that can be handled to access the HTTP record as it is sent on ## to the logging framework. @@ -180,6 +191,9 @@ event http_request(c: connection, method: string, original_URI: string, c$http$method = method; c$http$uri = unescaped_URI; + + if ( !(method in http_methods) ) + event conn_weird("unknown_HTTP_method", c, method); } event http_reply(c: connection, version: string, code: count, reason: string) &priority=5 diff --git a/src/HTTP.cc b/src/HTTP.cc index 9d9f01be64..0748ca55a7 100644 --- a/src/HTTP.cc +++ b/src/HTTP.cc @@ -1118,36 +1118,18 @@ const char* HTTP_Analyzer::PrefixWordMatch(const char* line, int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) { - const char* rest = 0; - static const char* http_methods[] = { - "GET", "POST", "HEAD", - - "OPTIONS", "PUT", "DELETE", "TRACE", "CONNECT", - - // HTTP methods for distributed authoring. - "PROPFIND", "PROPPATCH", "MKCOL", "DELETE", "PUT", - "COPY", "MOVE", "LOCK", "UNLOCK", - "POLL", "REPORT", "SUBSCRIBE", "BMOVE", - - "SEARCH", - - 0, - }; - - int i; - for ( i = 0; http_methods[i]; ++i ) - if ( (rest = PrefixWordMatch(line, end_of_line, http_methods[i])) != 0 ) - break; - - if ( ! http_methods[i] ) - { - // Weird("HTTP_unknown_method"); - if ( RequestExpected() ) - HTTP_Event("unknown_HTTP_method", new_string_val(line, end_of_line)); - return 0; - } - - request_method = new StringVal(http_methods[i]); + const char* request_method_str; + int request_method_len; + const char* rest; + get_word(strlen(line), line, request_method_len, request_method_str); + + request_method = new StringVal(request_method_len, request_method_str); + if ( (rest = PrefixWordMatch(line, end_of_line, (const char*) request_method->AsString()->Bytes() )) == 0) + { + // Most likely a DPD failure - this is pretty noisy for me, so leaving commented for now + // reporter->InternalError("HTTP RequestLine failed"); + return 0; + } if ( ! ParseRequest(rest, end_of_line) ) reporter->InternalError("HTTP ParseRequest failed"); From 318f38df4301f58e06ac9f9df153b89eed3a5b73 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 30 Nov 2012 22:06:54 -0500 Subject: [PATCH 05/27] A test for HTTP methods, including some horribly illegal requests. --- .../http.log | 58 ++++++++++++++++++ .../weird.log | 35 +++++++++++ testing/btest/Traces/http-methods.trace | Bin 0 -> 238829 bytes .../base/protocols/http/http-methods.bro | 9 +++ 4 files changed, 102 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log create mode 100644 testing/btest/Traces/http-methods.trace create mode 100644 testing/btest/scripts/base/protocols/http/http-methods.bro diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log new file mode 100644 index 0000000000..68ffd2e63d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log @@ -0,0 +1,58 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open 2012-12-01-03-01-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1354328870.191989 UWkUyAuUGXf 128.2.6.136 46562 173.194.75.103 80 1 OPTIONS www.google.com * - - 0 962 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328874.237327 arKYeMETxOg 128.2.6.136 46563 173.194.75.103 80 1 OPTIONS www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328874.299063 k6kgXLOoSKl 128.2.6.136 46564 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328874.342591 nQcgTWjvg4c 128.2.6.136 46565 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328874.364020 j4u32Pc5bif 128.2.6.136 46566 173.194.75.103 80 1 GET www.google.com / - - 0 43911 200 OK - - - (empty) - - - text/html - - +1354328878.470424 TEfuqmmG4bh 128.2.6.136 46567 173.194.75.103 80 1 GET www.google.com / - - 0 43983 200 OK - - - (empty) - - - text/html - - +1354328882.575456 FrJExwHcSal 128.2.6.136 46568 173.194.75.103 80 1 GET www.google.com /HTTP/1.1 - - 0 1207 403 Forbidden - - - (empty) - - - text/html - - +1354328882.908690 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 1 GET/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328882.968948 3PKsZ2Uye21 128.2.6.136 46570 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328882.990373 VW0XPVINV8a 128.2.6.136 46571 173.194.75.103 80 1 GET www.google.com / - - 0 43913 200 OK - - - (empty) - - - text/html - - +1354328887.094494 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83 www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328891.141058 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83 www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.183942 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 1 CCM_POST www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 1 CCM_POST/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328899.526682 EAr0uf4mhq 128.2.6.136 46582 173.194.75.103 80 1 CONNECT www.google.com / - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328903.572533 GvmoxJFXdTa 128.2.6.136 46583 173.194.75.103 80 1 CONNECT www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 1 CONNECT/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328903.676395 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328903.697693 UfGkYA2HI2g 128.2.6.136 46586 173.194.75.103 80 1 CONNECT www.google.com / - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328907.743696 i2rO3KD1Syg 128.2.6.136 46587 173.194.75.103 80 1 TRACE www.google.com / - - 0 960 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328911.790590 2cx26uAvUPl 128.2.6.136 46588 173.194.75.103 80 1 TRACE www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328911.832856 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 1 TRACE/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328911.897044 10XodEwRycf 128.2.6.136 46590 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328911.918511 zno26fFZkrh 128.2.6.136 46591 173.194.75.103 80 1 TRACE www.google.com / - - 0 960 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328915.964678 v5rgkJBig5l 128.2.6.136 46592 173.194.75.103 80 1 DELETE www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328920.010458 eWZCH7OONC1 128.2.6.136 46593 173.194.75.103 80 1 DELETE www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328920.052085 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 1 DELETE/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328920.114526 0HKorjr8Zp7 128.2.6.136 46595 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328920.136714 yC2d6kVg709 128.2.6.136 46596 173.194.75.103 80 1 DELETE www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328924.183211 VcgagLjnO92 128.2.6.136 46597 173.194.75.103 80 1 PUT www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - +1354328924.224567 bdRoHfaPBo3 128.2.6.136 46598 173.194.75.103 80 1 PUT www.google.com /HTTP/1.1 - - 0 934 411 Length Required - - - (empty) - - - text/html - - +1354328924.266693 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 1 PUT/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.328257 rrZWoMUQpv8 128.2.6.136 46600 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.350343 xNYSS2hJkle 128.2.6.136 46601 173.194.75.103 80 1 PUT www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - +1354328924.391728 vMVjlplKKbd 128.2.6.136 46602 173.194.75.103 80 1 POST www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - +1354328924.433150 3omNawSNrxj 128.2.6.136 46603 173.194.75.103 80 1 POST www.google.com /HTTP/1.1 - - 0 934 411 Length Required - - - (empty) - - - text/html - - +1354328924.476011 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 1 POST/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.537671 wEyF3OvvcQe 128.2.6.136 46605 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.559704 E490YZTUozc 128.2.6.136 46606 173.194.75.103 80 1 HEAD www.google.com / - - 0 0 200 OK - - - (empty) - - - - - - +1354328928.625437 YIeWJmXWNWj 128.2.6.136 46607 173.194.75.103 80 1 HEAD www.google.com / - - 0 0 200 OK - - - (empty) - - - - - - +1354328932.692706 ydiZblvsYri 128.2.6.136 46608 173.194.75.103 80 1 HEAD www.google.com /HTTP/1.1 - - 0 0 400 Bad Request - - - (empty) - - - - - - +1354328932.734579 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 1 HEAD/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +#close 2012-12-01-03-01-54 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log new file mode 100644 index 0000000000..aa1dcb7559 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log @@ -0,0 +1,35 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open 2012-12-01-03-01-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer +#types time string addr port addr port string string bool string +1354328874.299063 k6kgXLOoSKl 128.2.6.136 46564 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328874.342591 nQcgTWjvg4c 128.2.6.136 46565 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328882.908690 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 unknown_HTTP_method GET/ F bro +1354328882.968948 3PKsZ2Uye21 128.2.6.136 46570 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328887.094494 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83 F bro +1354328891.141058 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83 F bro +1354328891.183942 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83/ F bro +1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83/ F bro +1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro +1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro +1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 unknown_HTTP_method CCM_POST/ F bro +1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro +1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 unknown_HTTP_method CONNECT/ F bro +1354328903.676395 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328911.832856 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 unknown_HTTP_method TRACE/ F bro +1354328911.897044 10XodEwRycf 128.2.6.136 46590 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328920.052085 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 unknown_HTTP_method DELETE/ F bro +1354328920.114526 0HKorjr8Zp7 128.2.6.136 46595 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328924.266693 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 unknown_HTTP_method PUT/ F bro +1354328924.328257 rrZWoMUQpv8 128.2.6.136 46600 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328924.476011 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 unknown_HTTP_method POST/ F bro +1354328924.537671 wEyF3OvvcQe 128.2.6.136 46605 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328932.734579 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 unknown_HTTP_method HEAD/ F bro +1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 unmatched_HTTP_reply - F bro +#close 2012-12-01-03-01-54 diff --git a/testing/btest/Traces/http-methods.trace b/testing/btest/Traces/http-methods.trace new file mode 100644 index 0000000000000000000000000000000000000000..323e6ee06ac9e4a09b15e8b9d52111794f486648 GIT binary patch literal 238829 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 Date: Tue, 4 Dec 2012 12:38:09 -0600 Subject: [PATCH 06/27] Interpreter exceptions occurring in "when" blocks are now handled. The scripting error that caused the exception is still reported, but it no longer causes Bro to terminate. Addresses #779 --- src/Trigger.cc | 20 +++++- .../core.dns-interpreter-exceptions/out | 12 ++++ .../btest/core/dns-interpreter-exceptions.bro | 63 +++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 testing/btest/Baseline/core.dns-interpreter-exceptions/out create mode 100644 testing/btest/core/dns-interpreter-exceptions.bro diff --git a/src/Trigger.cc b/src/Trigger.cc index 164f11b885..b7e08b557e 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -217,8 +217,15 @@ bool Trigger::Eval() Name()); Unref(v); + v = 0; stmt_flow_type flow; - v = body->Exec(f, flow); + + try + { + v = body->Exec(f, flow); + } + catch ( InterpreterException& e ) + { /* Already reported. */ } if ( is_return ) { @@ -300,7 +307,14 @@ void Trigger::Timeout() { stmt_flow_type flow; Frame* f = frame->Clone(); - Val* v = timeout_stmts->Exec(f, flow); + Val* v = 0; + + try + { + v = timeout_stmts->Exec(f, flow); + } + catch ( InterpreterException& e ) + { /* Already reported. */ } if ( is_return ) { @@ -382,7 +396,7 @@ void Trigger::Attach(Trigger *trigger) void Trigger::Cache(const CallExpr* expr, Val* v) { - if ( disabled ) + if ( disabled || ! v ) return; ValCache::iterator i = cache.find(expr); diff --git a/testing/btest/Baseline/core.dns-interpreter-exceptions/out b/testing/btest/Baseline/core.dns-interpreter-exceptions/out new file mode 100644 index 0000000000..c081edc489 --- /dev/null +++ b/testing/btest/Baseline/core.dns-interpreter-exceptions/out @@ -0,0 +1,12 @@ +1300475167.096535 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 28: field value missing [p$ip] +1300475167.096535 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 49: field value missing [p$ip] +1300475168.902195 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 39: field value missing [p$ip] +1300475168.902195 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 12: field value missing [p$ip] +timeout g(), F +timeout g(), T +timeout +g() done, no exception, T +localhost resolved +localhost resolved from f(), T +localhost resolved from f(), F +f() done, no exception, T diff --git a/testing/btest/core/dns-interpreter-exceptions.bro b/testing/btest/core/dns-interpreter-exceptions.bro new file mode 100644 index 0000000000..a795971b58 --- /dev/null +++ b/testing/btest/core/dns-interpreter-exceptions.bro @@ -0,0 +1,63 @@ +# @TEST-EXEC: bro -b -r $TRACES/wikipedia.trace %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out +# interpreter exceptions in "when" blocks shouldn't cause termination +global p: pkt_hdr; + +function f(do_exception: bool): bool + { + return when ( local addrs = lookup_hostname("localhost") ) + { + print "localhost resolved from f()", do_exception; + if ( do_exception ) + print p$ip; + return T; + } + return F; + } + +function g(do_exception: bool): bool + { + return when ( local addrs = lookup_hostname("localhost") ) + { + print "shouldn't get here, g()", do_exception; + } + timeout 0 sec + { + print "timeout g()", do_exception; + if ( do_exception ) + print p$ip; + return T; + } + return F; + } + +event bro_init() + { + when ( local addrs = lookup_hostname("localhost") ) + { + print "localhost resolved"; + print p$ip; + } + + when ( local addrs2 = lookup_hostname("localhost") ) + { + print "shouldn't get here"; + } + timeout 0 sec + { + print "timeout"; + print p$ip; + } + + when ( local b = f(T) ) + print "f() exception done (shouldn't be printed)", b; + + when ( local b2 = g(T) ) + print "g() exception done (shouldn't be printed)", b2; + + when ( local b3 = f(F) ) + print "f() done, no exception", b3; + + when ( local b4 = g(F) ) + print "g() done, no exception", b4; + } From 7758f4dc9cab60fbb23e8e69a51463dfa0800e20 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 4 Dec 2012 12:45:52 -0600 Subject: [PATCH 07/27] Bump CPack RPM package requirement to python >= 2.6.0. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17ba34ab3b..e2a83e10f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,7 +195,7 @@ CheckOptionalBuildSources(aux/broccoli Broccoli INSTALL_BROCCOLI) if (INSTALL_BROCTL) # CPack RPM Generator may not automatically detect this - set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.4.0") + set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.6.0") endif () # If this CMake project is a sub-project of another, we will not From 75278af8a101395f06b3371e5a5dc3795032efad Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 4 Dec 2012 15:22:16 -0600 Subject: [PATCH 08/27] Invalid vector indices now generate error message (addresses #24). The error/behavior is the same as accessing tables at invalid indices. --- src/Expr.cc | 14 +++++--------- testing/btest/Baseline/language.invalid_index/out | 7 +++++++ testing/btest/language/invalid_index.bro | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 testing/btest/Baseline/language.invalid_index/out create mode 100644 testing/btest/language/invalid_index.bro diff --git a/src/Expr.cc b/src/Expr.cc index 07ee4eb1e1..97099a8995 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2950,16 +2950,12 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const if ( IsError() ) return 0; - if ( v1->Type()->Tag() == TYPE_VECTOR ) - { - Val* v = v1->AsVectorVal()->Lookup(v2); - // ### dangerous - this can silently fail larger operations - // due to a missing element - return v ? v->Ref() : 0; - } + Val* v = 0; - TableVal* v_tbl = v1->AsTableVal(); - Val* v = v_tbl->Lookup(v2); + if ( v1->Type()->Tag() == TYPE_VECTOR ) + v = v1->AsVectorVal()->Lookup(v2); + else + v = v1->AsTableVal()->Lookup(v2); if ( v ) return v->Ref(); diff --git a/testing/btest/Baseline/language.invalid_index/out b/testing/btest/Baseline/language.invalid_index/out new file mode 100644 index 0000000000..9110a8979d --- /dev/null +++ b/testing/btest/Baseline/language.invalid_index/out @@ -0,0 +1,7 @@ +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.invalid_index/invalid_index.bro, line 8: no such index (foo[1]) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.invalid_index/invalid_index.bro, line 9: no such index (foo[2]) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.invalid_index/invalid_index.bro, line 12: no such index (foo2[1]) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.invalid_index/invalid_index.bro, line 13: no such index (foo2[2]) +foo[0], 42 +foo2[0], 13 +done diff --git a/testing/btest/language/invalid_index.bro b/testing/btest/language/invalid_index.bro new file mode 100644 index 0000000000..96b7fa78c5 --- /dev/null +++ b/testing/btest/language/invalid_index.bro @@ -0,0 +1,15 @@ +# @TEST-EXEC: bro -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +global foo: vector of count = { 42 }; +global foo2: table[count] of count = { [0] = 13 }; + +print "foo[0]", foo[0]; +print "foo[1]", foo[1]; +print "foo[2]", foo[2]; + +print "foo2[0]", foo2[0]; +print "foo2[1]", foo2[1]; +print "foo2[2]", foo2[2]; + +print "done"; From 32239ea63395e523b7ad6ccdfa3a56c34d35a0fa Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 4 Dec 2012 16:29:23 -0600 Subject: [PATCH 09/27] Bad record constructor initializers now give an error (addresses #34). As opposed to a segfault. --- src/Expr.cc | 22 ++++++++++--------- .../Baseline/language.record-bad-ctor/out | 3 +++ testing/btest/language/record-bad-ctor.bro | 8 +++++++ 3 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 testing/btest/Baseline/language.record-bad-ctor/out create mode 100644 testing/btest/language/record-bad-ctor.bro diff --git a/src/Expr.cc b/src/Expr.cc index 97099a8995..7995d5d495 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3286,20 +3286,22 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list) Val* RecordConstructorExpr::InitVal(const BroType* t, Val* aggr) const { - RecordVal* rv = Eval(0)->AsRecordVal(); - RecordVal* ar = rv->CoerceTo(t->AsRecordType(), aggr); + Val* v = Eval(0); - if ( ar ) + if ( v ) { - Unref(rv); - return ar; + RecordVal* rv = v->AsRecordVal(); + RecordVal* ar = rv->CoerceTo(t->AsRecordType(), aggr); + + if ( ar ) + { + Unref(rv); + return ar; + } } - else - { - Error("bad record initializer"); - return 0; - } + Error("bad record initializer"); + return 0; } Val* RecordConstructorExpr::Fold(Val* v) const diff --git a/testing/btest/Baseline/language.record-bad-ctor/out b/testing/btest/Baseline/language.record-bad-ctor/out new file mode 100644 index 0000000000..2b890419ae --- /dev/null +++ b/testing/btest/Baseline/language.record-bad-ctor/out @@ -0,0 +1,3 @@ +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.record-bad-ctor/record-bad-ctor.bro, line 6: no type given (asdfasdf) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.record-bad-ctor/record-bad-ctor.bro, line 7: uninitialized list value ($ports=asdfasdf) +error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.record-bad-ctor/record-bad-ctor.bro, line 7: bad record initializer ([$ports=asdfasdf]) diff --git a/testing/btest/language/record-bad-ctor.bro b/testing/btest/language/record-bad-ctor.bro new file mode 100644 index 0000000000..6b7ae4ff19 --- /dev/null +++ b/testing/btest/language/record-bad-ctor.bro @@ -0,0 +1,8 @@ +# @TEST-EXEC-FAIL: bro -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +# At least shouldn't crash Bro, just report the invalid record ctor. + +global asdfasdf; +const blah = [$ports=asdfasdf]; +print blah; From f403e537ece415ec338e8b21d0cb233daf7f970c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 5 Dec 2012 12:36:09 -0600 Subject: [PATCH 10/27] Fix segfault: uninitialized identifiers w/ &synchronized (addresses #66) Synchronization of state between connecting peers now skips over identifiers that aren't initialized with a value yet. If they're assigned a value later, that will be synchronized like usual. --- src/RemoteSerializer.cc | 8 ++++++++ testing/btest/Baseline/istate.sync/receiver.vars.log | 1 + testing/btest/Baseline/istate.sync/sender.vars.log | 1 + testing/btest/istate/sync.bro | 11 ++++++++--- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 564ad2be68..54986610bc 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -1032,6 +1032,14 @@ bool RemoteSerializer::SendAllSynchronized(Peer* peer, SerialInfo* info) for ( ; index < sync_ids.length(); ++index ) { + if ( ! sync_ids[index]->ID_Val() ) + { +#ifdef DEBUG + DBG_LOG(DBG_COMM, "Skip sync of ID with null value: %s\n", + sync_ids[index]->Name()); +#endif + continue; + } cont->SaveContext(); StateAccess sa(OP_ASSIGN, sync_ids[index], diff --git a/testing/btest/Baseline/istate.sync/receiver.vars.log b/testing/btest/Baseline/istate.sync/receiver.vars.log index b28cfbd5c9..192876bd3e 100644 --- a/testing/btest/Baseline/istate.sync/receiver.vars.log +++ b/testing/btest/Baseline/istate.sync/receiver.vars.log @@ -31,3 +31,4 @@ file "test2" of string 6667/tcp [2, 20, 3, 4] [a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666, e=] +122112 diff --git a/testing/btest/Baseline/istate.sync/sender.vars.log b/testing/btest/Baseline/istate.sync/sender.vars.log index b28cfbd5c9..192876bd3e 100644 --- a/testing/btest/Baseline/istate.sync/sender.vars.log +++ b/testing/btest/Baseline/istate.sync/sender.vars.log @@ -31,3 +31,4 @@ file "test2" of string 6667/tcp [2, 20, 3, 4] [a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666, e=] +122112 diff --git a/testing/btest/istate/sync.bro b/testing/btest/istate/sync.bro index e1364a9553..a297e8a50f 100644 --- a/testing/btest/istate/sync.bro +++ b/testing/btest/istate/sync.bro @@ -1,7 +1,7 @@ # @TEST-SERIALIZE: comm # -# @TEST-EXEC: btest-bg-run sender bro %INPUT ../sender.bro -# @TEST-EXEC: btest-bg-run receiver bro %INPUT ../receiver.bro +# @TEST-EXEC: btest-bg-run sender bro -b %INPUT ../sender.bro +# @TEST-EXEC: btest-bg-run receiver bro -b %INPUT ../receiver.bro # @TEST-EXEC: btest-bg-wait 20 # # @TEST-EXEC: btest-diff sender/vars.log @@ -27,6 +27,7 @@ global foo13 = { [1,"ABC"] = 101, [2,"DEF"] = 102, [3,"GHI"] = 103 } &persiste global foo14 = { [12345] = foo11, [12346] = foo11 } &persistent &synchronized; global foo15 = 42/udp &persistent &synchronized; global foo16: vector of count = [1,2,3] &persistent &synchronized; +global foo18: count &persistent &synchronized; # not initialized type type1: record { a: string; @@ -70,6 +71,7 @@ event bro_done() print out, foo15; print out, foo16; print out, foo17; + print out, foo18; } @@ -128,7 +130,8 @@ function modify() delete foo17$e; foo2 = 1234567; -} + foo18 = 122112; + } @load frameworks/communication/listen @@ -148,6 +151,8 @@ redef Communication::nodes += { @TEST-START-FILE receiver.bro +@load base/frameworks/communication + event bro_init() { capture_events("events.bst"); From d367e227c1041b180fb1d49b6016f25d4db24457 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 5 Dec 2012 12:40:00 -0800 Subject: [PATCH 11/27] ok, this one is a bit... embarrassing. Delete the correct entry in case of error. Fixes a segfault when the faulty data is of type string and not the last field of the input... --- src/input/readers/Ascii.cc | 2 +- .../.stderrwithoutfirstline | 4 ++ .../out | 3 ++ .../base/frameworks/input/invalidtext.bro | 46 +++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline create mode 100644 testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/out create mode 100644 testing/btest/scripts/base/frameworks/input/invalidtext.bro diff --git a/src/input/readers/Ascii.cc b/src/input/readers/Ascii.cc index e9cba27205..173ce418ca 100644 --- a/src/input/readers/Ascii.cc +++ b/src/input/readers/Ascii.cc @@ -572,7 +572,7 @@ bool Ascii::DoUpdate() // array structure. for ( int i = 0; i < fpos; i++ ) - delete fields[fpos]; + delete fields[i]; delete [] fields; continue; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline new file mode 100644 index 0000000000..3d8ba5e267 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline @@ -0,0 +1,4 @@ +error: ../input.log/Input::READER_ASCII: String 'l' contained no parseable number +error: ../input.log/Input::READER_ASCII: Could not convert line ' l' to Val. Ignoring line. +received termination signal +>>> diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/out b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/out new file mode 100644 index 0000000000..4950b6f590 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/out @@ -0,0 +1,3 @@ +{ +[] = [c=5] +} diff --git a/testing/btest/scripts/base/frameworks/input/invalidtext.bro b/testing/btest/scripts/base/frameworks/input/invalidtext.bro new file mode 100644 index 0000000000..75efb1247d --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/invalidtext.bro @@ -0,0 +1,46 @@ +# (uses listen.bro just to ensure input sources are more reliably fully-read). +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-wait -k 5 +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline + +@TEST-START-FILE input.log +#separator \x09 +#fields i c +#types int count + l + 5 +@TEST-END-FILE + +@load frameworks/communication/listen + +global outfile: file; + +module A; + +type Idx: record { + i: string; +}; + +type Val: record { + c: count; +}; + +global servers: table[string] of Val = table(); + +event bro_init() + { + outfile = open("../out"); + # first read in the old stuff into the table... + Input::add_table([$source="../input.log", $name="ssh", $idx=Idx, $val=Val, $destination=servers]); + Input::remove("ssh"); + } + +event Input::end_of_data(name: string, source:string) + { + print outfile, servers; + terminate(); + } From 90fc5c97e5682a357fb501fd7971e96479dbcff2 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 5 Dec 2012 15:47:32 -0800 Subject: [PATCH 12/27] Reporting warnings if kill/waitpid fail in communication system. Also replace bzero with memset(). Patches from Bill Parker. --- CHANGES | 23 +++++++++++++++++++++++ VERSION | 2 +- aux/broccoli | 2 +- src/RemoteSerializer.cc | 19 +++++++++++++------ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 4ce30b9a35..64eee13f71 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,27 @@ +2.1-207 | 2012-12-05 15:47:32 -0800 + + * Reporting warnings if kill/waitpid fail in communication system. + (Bill Parker) + + * Replace() bzero with memset(). (Bill Parker) + + * Merge remote-tracking branch 'vlad/topic/vladg/http-verbs' + + * vlad/topic/vladg/http-verbs: + A test for HTTP methods, including some horribly illegal requests. + Remove hardcoded HTTP verbs from the analyzer (#741) + + I added a "bad_HTTP_request" weird for HTTP request lines that don't + have more than a single word. + + Closes #741. (Robin Sommer) + + * A test for HTTP methods, including some horribly illegal requests. (Vlad Grigorescu) + + * Remove hardcoded HTTP verbs from the analyzer (#741) (Vlad Grigorescu) + + 2.1-203 | 2012-12-05 14:36:56 -0800 * Fix segfault: Synchronization of state between connecting peers diff --git a/VERSION b/VERSION index 5a8388c35d..e0c0306d87 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-203 +2.1-207 diff --git a/aux/broccoli b/aux/broccoli index a8846fc5b0..5c983a00ce 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit a8846fc5b004ffe4e3d00e826d0077ba19518192 +Subproject commit 5c983a00ce45b2687d0235b67602c98916910412 diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 54986610bc..66f8def489 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -545,8 +545,11 @@ RemoteSerializer::~RemoteSerializer() { if ( child_pid ) { - kill(child_pid, SIGKILL); - waitpid(child_pid, 0, 0); + if ( kill(child_pid, SIGKILL) < 0 ) + reporter->Warning("warning: cannot kill child (pid %d), %s", child_pid, strerror(errno)); + + else if ( waitpid(child_pid, 0, 0) < 0 ) + reporter->Warning("warning: error encountered during waitpid(%d), %s", child_pid, strerror(errno)); } delete io; @@ -3161,7 +3164,10 @@ void RemoteSerializer::FatalError(const char* msg) reporter->Error("%s", msg); closed = true; - kill(child_pid, SIGQUIT); + + if ( kill(child_pid, SIGQUIT) < 0 ) + reporter->Warning("warning: cannot kill child pid %d, %s", child_pid, strerror(errno)); + child_pid = 0; using_communication = false; io->Clear(); @@ -3971,7 +3977,7 @@ bool SocketComm::Connect(Peer* peer) { int status; addrinfo hints, *res, *res0; - bzero(&hints, sizeof(hints)); + memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_protocol = IPPROTO_TCP; @@ -4103,7 +4109,7 @@ bool SocketComm::Listen() { int status, on = 1; addrinfo hints, *res, *res0; - bzero(&hints, sizeof(hints)); + memset(&hints, 0, sizeof(hints)); IPAddr listen_ip(listen_if); @@ -4368,7 +4374,8 @@ void SocketComm::Kill() CloseListenFDs(); - kill(getpid(), SIGTERM); + if ( kill(getpid(), SIGTERM) < 0 ) + Log(fmt("warning: cannot kill SocketComm pid %d, %s", getpid(), strerror(errno))); while ( 1 ) ; // loop until killed From c8d264f10502ddc1fc25dbd2387426218646d3c0 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 5 Dec 2012 15:50:46 -0800 Subject: [PATCH 13/27] Updating submodule(s). [nomail] --- aux/broccoli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broccoli b/aux/broccoli index 5c983a00ce..06682dbb15 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 5c983a00ce45b2687d0235b67602c98916910412 +Subproject commit 06682dbb15d26d2688bdc9ad76efec17d38dc80f From 57510464a1c100f174382daa48934f2404762f3d Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 5 Dec 2012 16:44:04 -0800 Subject: [PATCH 14/27] Adapting the HTTP request line parsing to only accept methods consisting of letters [A-Za-z]. I had some bogus HTTP sessions now with the test-suite that reported data as HTTP because it started with "Weird(Conn(), "bad_HTTP_request"); - return 0; + // The method must consist of only letters. + if ( (*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') ) + goto error; } + rest = skip_whitespace(end_of_request, end_of_line); + if ( rest == end_of_request ) + // End of line already reached. Most likely a DPD failure. + goto error; + request_method = new StringVal(request_method_len, request_method_str); if ( ! ParseRequest(rest, end_of_line) ) @@ -1144,6 +1152,10 @@ int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) unescaped_URI->AsString()->Len(), true, true, true, true); return 1; + +error: + reporter->Weird(Conn(), "bad_HTTP_request"); + return 0; } int HTTP_Analyzer::ParseRequest(const char* line, const char* end_of_line) diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log index 37d8410143..8626071e18 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path http -#open 2012-12-05-23-27-37 +#open 2012-12-06-00-55-27 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file #types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file 1354328870.191989 UWkUyAuUGXf 128.2.6.136 46562 173.194.75.103 80 1 OPTIONS www.google.com * - - 0 962 405 Method Not Allowed - - - (empty) - - - text/html - - @@ -13,46 +13,46 @@ 1354328874.364020 j4u32Pc5bif 128.2.6.136 46566 173.194.75.103 80 1 GET www.google.com / - - 0 43911 200 OK - - - (empty) - - - text/html - - 1354328878.470424 TEfuqmmG4bh 128.2.6.136 46567 173.194.75.103 80 1 GET www.google.com / - - 0 43983 200 OK - - - (empty) - - - text/html - - 1354328882.575456 FrJExwHcSal 128.2.6.136 46568 173.194.75.103 80 1 GET www.google.com /HTTP/1.1 - - 0 1207 403 Forbidden - - - (empty) - - - text/html - - -1354328882.908690 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 1 GET/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328882.928027 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328882.968948 3PKsZ2Uye21 128.2.6.136 46570 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328882.990373 VW0XPVINV8a 128.2.6.136 46571 173.194.75.103 80 1 GET www.google.com / - - 0 43913 200 OK - - - (empty) - - - text/html - - -1354328887.094494 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83 www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - -1354328891.141058 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83 www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328891.183942 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328887.114613 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 0 - - - - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328891.161077 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.204740 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 1 \xc3\x83\xc3\x82\xc3\x83/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - -1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 1 CCM_POST www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 1 CCM_POST/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.287655 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.328583 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 0 - - - - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328895.375116 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328895.416133 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328895.500315 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 0 - - - - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328899.526682 EAr0uf4mhq 128.2.6.136 46582 173.194.75.103 80 1 CONNECT www.google.com / - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328903.572533 GvmoxJFXdTa 128.2.6.136 46583 173.194.75.103 80 1 CONNECT www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 1 CONNECT/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328903.634196 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328903.676395 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328903.697693 UfGkYA2HI2g 128.2.6.136 46586 173.194.75.103 80 1 CONNECT www.google.com / - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328907.743696 i2rO3KD1Syg 128.2.6.136 46587 173.194.75.103 80 1 TRACE www.google.com / - - 0 960 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328911.790590 2cx26uAvUPl 128.2.6.136 46588 173.194.75.103 80 1 TRACE www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328911.832856 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 1 TRACE/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328911.853464 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328911.897044 10XodEwRycf 128.2.6.136 46590 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328911.918511 zno26fFZkrh 128.2.6.136 46591 173.194.75.103 80 1 TRACE www.google.com / - - 0 960 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328915.964678 v5rgkJBig5l 128.2.6.136 46592 173.194.75.103 80 1 DELETE www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328920.010458 eWZCH7OONC1 128.2.6.136 46593 173.194.75.103 80 1 DELETE www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328920.052085 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 1 DELETE/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328920.072101 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328920.114526 0HKorjr8Zp7 128.2.6.136 46595 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328920.136714 yC2d6kVg709 128.2.6.136 46596 173.194.75.103 80 1 DELETE www.google.com / - - 0 961 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328924.183211 VcgagLjnO92 128.2.6.136 46597 173.194.75.103 80 1 PUT www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - 1354328924.224567 bdRoHfaPBo3 128.2.6.136 46598 173.194.75.103 80 1 PUT www.google.com /HTTP/1.1 - - 0 934 411 Length Required - - - (empty) - - - text/html - - -1354328924.266693 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 1 PUT/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.287402 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328924.328257 rrZWoMUQpv8 128.2.6.136 46600 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328924.350343 xNYSS2hJkle 128.2.6.136 46601 173.194.75.103 80 1 PUT www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - 1354328924.391728 vMVjlplKKbd 128.2.6.136 46602 173.194.75.103 80 1 POST www.google.com / - - 0 934 411 Length Required - - - (empty) - - - text/html - - 1354328924.433150 3omNawSNrxj 128.2.6.136 46603 173.194.75.103 80 1 POST www.google.com /HTTP/1.1 - - 0 934 411 Length Required - - - (empty) - - - text/html - - -1354328924.476011 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 1 POST/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328924.496732 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328924.537671 wEyF3OvvcQe 128.2.6.136 46605 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328924.559704 E490YZTUozc 128.2.6.136 46606 173.194.75.103 80 1 HEAD www.google.com / - - 0 0 200 OK - - - (empty) - - - - - - 1354328928.625437 YIeWJmXWNWj 128.2.6.136 46607 173.194.75.103 80 1 HEAD www.google.com / - - 0 0 200 OK - - - (empty) - - - - - - 1354328932.692706 ydiZblvsYri 128.2.6.136 46608 173.194.75.103 80 1 HEAD www.google.com /HTTP/1.1 - - 0 0 400 Bad Request - - - (empty) - - - - - - -1354328932.734579 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 1 HEAD/ www.google.com HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328932.754657 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -#close 2012-12-05-23-27-37 +#close 2012-12-06-00-55-28 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log index c09c4e7158..8a9dcf17cc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log @@ -3,44 +3,59 @@ #empty_field (empty) #unset_field - #path weird -#open 2012-12-05-23-27-37 +#open 2012-12-06-00-55-27 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1354328874.278822 k6kgXLOoSKl 128.2.6.136 46564 173.194.75.103 80 bad_HTTP_request - F bro 1354328874.299063 k6kgXLOoSKl 128.2.6.136 46564 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328874.321792 nQcgTWjvg4c 128.2.6.136 46565 173.194.75.103 80 bad_HTTP_request - F bro 1354328874.342591 nQcgTWjvg4c 128.2.6.136 46565 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328882.908690 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 unknown_HTTP_method GET/ F bro +1354328882.908690 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 bad_HTTP_request - F bro +1354328882.928027 5OKnoww6xl4 128.2.6.136 46569 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328882.949510 3PKsZ2Uye21 128.2.6.136 46570 173.194.75.103 80 bad_HTTP_request - F bro 1354328882.968948 3PKsZ2Uye21 128.2.6.136 46570 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328887.094494 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83 F bro -1354328891.141058 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83 F bro -1354328891.183942 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83/ F bro +1354328887.094494 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 bad_HTTP_request - F bro +1354328887.114613 fRFu0wcOle6 128.2.6.136 46572 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328891.141058 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.161077 qSsw6ESzHV4 128.2.6.136 46573 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328891.183942 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.204740 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328891.226199 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 bad_HTTP_request - F bro 1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 unknown_HTTP_method \xc3\x83\xc3\x82\xc3\x83/ F bro -1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro -1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro -1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 unknown_HTTP_method CCM_POST/ F bro +1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.287655 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 bad_HTTP_request - F bro +1354328891.328583 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 bad_HTTP_request - F bro +1354328895.375116 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 bad_HTTP_request - F bro +1354328895.416133 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328895.438812 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 bad_HTTP_request - F bro 1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro -1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 unknown_HTTP_method CONNECT/ F bro +1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 bad_HTTP_request - F bro +1354328895.500315 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 bad_HTTP_request - F bro +1354328903.634196 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328903.656369 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 bad_HTTP_request - F bro 1354328903.676395 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328911.832856 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 unknown_HTTP_method TRACE/ F bro +1354328911.832856 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 bad_HTTP_request - F bro +1354328911.853464 BWaU4aSuwkc 128.2.6.136 46589 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328911.876341 10XodEwRycf 128.2.6.136 46590 173.194.75.103 80 bad_HTTP_request - F bro 1354328911.897044 10XodEwRycf 128.2.6.136 46590 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328920.052085 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 unknown_HTTP_method DELETE/ F bro +1354328920.052085 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 bad_HTTP_request - F bro +1354328920.072101 0Pwk3ntf8O3 128.2.6.136 46594 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328920.094072 0HKorjr8Zp7 128.2.6.136 46595 173.194.75.103 80 bad_HTTP_request - F bro 1354328920.114526 0HKorjr8Zp7 128.2.6.136 46595 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328924.266693 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 unknown_HTTP_method PUT/ F bro +1354328924.266693 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 bad_HTTP_request - F bro +1354328924.287402 zHqb7t7kv28 128.2.6.136 46599 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328924.308714 rrZWoMUQpv8 128.2.6.136 46600 173.194.75.103 80 bad_HTTP_request - F bro 1354328924.328257 rrZWoMUQpv8 128.2.6.136 46600 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328924.476011 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 unknown_HTTP_method POST/ F bro +1354328924.476011 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 bad_HTTP_request - F bro +1354328924.496732 Rv8AJVfi9Zi 128.2.6.136 46604 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328924.518204 wEyF3OvvcQe 128.2.6.136 46605 173.194.75.103 80 bad_HTTP_request - F bro 1354328924.537671 wEyF3OvvcQe 128.2.6.136 46605 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328932.734579 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 unknown_HTTP_method HEAD/ F bro +1354328932.734579 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 bad_HTTP_request - F bro +1354328932.754657 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328932.776609 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 bad_HTTP_request - F bro 1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 unmatched_HTTP_reply - F bro -#close 2012-12-05-23-27-37 +#close 2012-12-06-00-55-28 From a31161ef267e2e4d54170e39bfcee9920ff385bd Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 6 Dec 2012 08:34:46 -0800 Subject: [PATCH 15/27] Updating submodule(s). [nomail] --- aux/broctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broctl b/aux/broctl index 834131cd0e..5629b535c5 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 834131cd0ec0f63cce9de818726fe6167dedbf34 +Subproject commit 5629b535c564a3e389fd5bbcf0c16b1b57687e3b From 5598e1ca9b121e55acec47ba1689d6381c62ba46 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 6 Dec 2012 15:52:36 -0800 Subject: [PATCH 16/27] Updating submodule(s). [nomail] --- aux/broctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broctl b/aux/broctl index 5629b535c5..91e3b8ad44 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 5629b535c564a3e389fd5bbcf0c16b1b57687e3b +Subproject commit 91e3b8ad445cb4d8919b4ee1cc6f0753c3fa0a55 From e2d20cb7bc5139192977fa5d0a63249b8a4a22ce Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 7 Dec 2012 19:42:03 -0800 Subject: [PATCH 17/27] Changing the HTTP parser to accept methods that align with the RFC. --- src/HTTP.cc | 42 +++++++++++-------- .../http.log | 10 ++--- .../weird.log | 13 +++--- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/HTTP.cc b/src/HTTP.cc index 7a18e903e8..7e4079b853 100644 --- a/src/HTTP.cc +++ b/src/HTTP.cc @@ -1116,33 +1116,39 @@ const char* HTTP_Analyzer::PrefixWordMatch(const char* line, return line; } +static bool is_HTTP_token_char(char c) + { + return c > 31 && c != 127 && // CTL per RFC 2616. + c != ' ' && c != '\t' && // Separators. + c != '(' && c != ')' && c != '<' && c != '>' && c != '@' && + c != ',' && c != ';' && c != ':' && c != '\\' && c != '"' && + c != '/' && c != '[' && c != ']' && c != '?' && c != '=' && + c != '{' && c != '}'; + } + +static const char* get_HTTP_token(const char* s, const char* e) + { + while ( s < e && is_HTTP_token_char(*s) ) + ++s; + + return s; + } + + int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line) { - const char* request_method_str = 0; - const char* end_of_request = 0; const char* rest = 0; - int request_method_len = 0; + const char* end_of_method = get_HTTP_token(line, end_of_line); - get_word(end_of_line - line, line, request_method_len, request_method_str); - - if ( request_method_len == 0 ) + if ( end_of_method == line ) goto error; - end_of_request = request_method_str + request_method_len; + rest = skip_whitespace(end_of_method, end_of_line); - for ( const char* p = request_method_str; p < end_of_request; p++ ) - { - // The method must consist of only letters. - if ( (*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') ) - goto error; - } - - rest = skip_whitespace(end_of_request, end_of_line); - if ( rest == end_of_request ) - // End of line already reached. Most likely a DPD failure. + if ( rest == end_of_method ) goto error; - request_method = new StringVal(request_method_len, request_method_str); + request_method = new StringVal(end_of_method - line, line); if ( ! ParseRequest(rest, end_of_line) ) reporter->InternalError("HTTP ParseRequest failed"); diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log index 8626071e18..ac84e5ae7a 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/http.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path http -#open 2012-12-06-00-55-27 +#open 2012-12-07-04-43-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file #types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file 1354328870.191989 UWkUyAuUGXf 128.2.6.136 46562 173.194.75.103 80 1 OPTIONS www.google.com * - - 0 962 405 Method Not Allowed - - - (empty) - - - text/html - - @@ -21,11 +21,11 @@ 1354328891.204740 iE6yhOq3SF 128.2.6.136 46574 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328891.287655 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328891.328583 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 0 - - - - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - -1354328895.375116 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - +1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 1 CCM_POST www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328895.416133 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -1354328895.500315 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 0 - - - - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - +1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 1 CCM_POST www.google.com / - - 0 963 405 Method Not Allowed - - - (empty) - - - text/html - - 1354328899.526682 EAr0uf4mhq 128.2.6.136 46582 173.194.75.103 80 1 CONNECT www.google.com / - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328903.572533 GvmoxJFXdTa 128.2.6.136 46583 173.194.75.103 80 1 CONNECT www.google.com /HTTP/1.1 - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328903.634196 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - @@ -55,4 +55,4 @@ 1354328932.692706 ydiZblvsYri 128.2.6.136 46608 173.194.75.103 80 1 HEAD www.google.com /HTTP/1.1 - - 0 0 400 Bad Request - - - (empty) - - - - - - 1354328932.754657 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - 1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 0 - - - - - 0 925 400 Bad Request - - - (empty) - - - text/html - - -#close 2012-12-06-00-55-28 +#close 2012-12-07-04-43-19 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log index 8a9dcf17cc..8b963f00cf 100644 --- a/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-methods/weird.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path weird -#open 2012-12-06-00-55-27 +#open 2012-12-07-04-43-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1354328874.278822 k6kgXLOoSKl 128.2.6.136 46564 173.194.75.103 80 bad_HTTP_request - F bro @@ -24,16 +24,13 @@ 1354328891.245592 GSxOnSLghOa 128.2.6.136 46575 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328891.267625 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 bad_HTTP_request - F bro 1354328891.287655 qCaWGmzFtM5 128.2.6.136 46576 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 bad_HTTP_request - F bro -1354328891.328583 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 bad_HTTP_request - F bro -1354328895.375116 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328891.309065 70MGiRM1Qf4 128.2.6.136 46577 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro +1354328895.355012 h5DsfNtYzi1 128.2.6.136 46578 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro 1354328895.396634 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 bad_HTTP_request - F bro 1354328895.416133 P654jzLoe3a 128.2.6.136 46579 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328895.438812 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 bad_HTTP_request - F bro 1354328895.459490 Tw8jXtpTGu6 128.2.6.136 46580 173.194.75.103 80 unmatched_HTTP_reply - F bro -1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 bad_HTTP_request - F bro -1354328895.500315 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 unmatched_HTTP_reply - F bro +1354328895.480865 c4Zw9TmAE05 128.2.6.136 46581 173.194.75.103 80 unknown_HTTP_method CCM_POST F bro 1354328903.614145 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 bad_HTTP_request - F bro 1354328903.634196 0Q4FH8sESw5 128.2.6.136 46584 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328903.656369 slFea8xwSmb 128.2.6.136 46585 173.194.75.103 80 bad_HTTP_request - F bro @@ -58,4 +55,4 @@ 1354328932.754657 HFYOnBqSE5e 128.2.6.136 46609 173.194.75.103 80 unmatched_HTTP_reply - F bro 1354328932.776609 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 bad_HTTP_request - F bro 1354328932.796568 JcUvhfWUMgd 128.2.6.136 46610 173.194.75.103 80 unmatched_HTTP_reply - F bro -#close 2012-12-06-00-55-28 +#close 2012-12-07-04-43-19 From e8482fef9962bf142092eb44c0acfd9086393c10 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sat, 8 Dec 2012 12:05:32 -0800 Subject: [PATCH 18/27] Updating CHANGES and VERSION. --- CHANGES | 5 +++++ VERSION | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b912354f04..fd6b69f099 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +2.1-212 | 2012-12-07 19:42:03 -0800 + + * Changing the HTTP parser to accept request methods in alignment + with the RFC. (Robin Sommer) + 2.1-209 | 2012-12-05 16:44:04 -0800 * Adapting the HTTP request line parsing to only accept methods diff --git a/VERSION b/VERSION index f169e62b3a..ae0289baaf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-209 +2.1-212 From cb7fd7c87cc67cd66f3a2b98540ed4e53cc49bbb Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Mon, 10 Dec 2012 15:43:13 -0600 Subject: [PATCH 19/27] Remove unused attributes Removed attributes &postprocessor and &match from documentation and source code. Removed undocumented attribute &attr from source code. Removed internal attribute (&tracked) from documentation. --- doc/scripts/builtins.rst | 11 ----------- src/Attr.cc | 9 ++------- src/Attr.h | 2 -- src/File.h | 2 +- src/parse.y | 2 +- src/scan.l | 1 - 6 files changed, 4 insertions(+), 23 deletions(-) diff --git a/doc/scripts/builtins.rst b/doc/scripts/builtins.rst index 322aafc2cf..b9febb176c 100644 --- a/doc/scripts/builtins.rst +++ b/doc/scripts/builtins.rst @@ -663,20 +663,12 @@ scripting language supports the following built-in attributes. ``&synchronized`` variable is automatically propagated to all peers when it changes. -.. bro:attr:: &postprocessor - -.. TODO: needs to be documented. - .. bro:attr:: &encrypt Encrypts files right before writing them to disk. .. TODO: needs to be documented in more detail. -.. bro:attr:: &match - -.. TODO: needs to be documented. - .. bro:attr:: &raw_output Opens a file in raw mode, i.e., non-ASCII characters are not @@ -710,6 +702,3 @@ scripting language supports the following built-in attributes. .. TODO: needs documented -.. bro:attr:: (&tracked) - -.. TODO: needs documented or removed if it's not used anywhere. diff --git a/src/Attr.cc b/src/Attr.cc index 6cc582f053..244d1e1687 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -14,8 +14,8 @@ const char* attr_name(attr_tag t) "&rotate_interval", "&rotate_size", "&add_func", "&delete_func", "&expire_func", "&read_expire", "&write_expire", "&create_expire", - "&persistent", "&synchronized", "&postprocessor", - "&encrypt", "&match", + "&persistent", "&synchronized", + "&encrypt", "&raw_output", "&mergeable", "&priority", "&group", "&log", "&error_handler", "&type_column", "(&tracked)", @@ -337,11 +337,6 @@ void Attributes::CheckAttr(Attr* a) Error("&rotate_size only applicable to files"); break; - case ATTR_POSTPROCESSOR: - if ( type->Tag() != TYPE_FILE ) - Error("&postprocessor only applicable to files"); - break; - case ATTR_ENCRYPT: if ( type->Tag() != TYPE_FILE ) Error("&encrypt only applicable to files"); diff --git a/src/Attr.h b/src/Attr.h index c9a0dedb33..c3e05d4762 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -25,9 +25,7 @@ typedef enum { ATTR_EXPIRE_CREATE, ATTR_PERSISTENT, ATTR_SYNCHRONIZED, - ATTR_POSTPROCESSOR, ATTR_ENCRYPT, - ATTR_MATCH, ATTR_RAW_OUTPUT, ATTR_MERGEABLE, ATTR_PRIORITY, diff --git a/src/File.h b/src/File.h index 8e3d0ca6e7..a37b7fe0a6 100644 --- a/src/File.h +++ b/src/File.h @@ -56,7 +56,7 @@ public: // Rotates the logfile. Returns rotate_info. RecordVal* Rotate(); - // Set &rotate_interval, &rotate_size, &postprocessor, + // Set &rotate_interval, &rotate_size, // and &raw_output attributes. void SetAttrs(Attributes* attrs); diff --git a/src/parse.y b/src/parse.y index 0385c1c4e1..079fc16c43 100644 --- a/src/parse.y +++ b/src/parse.y @@ -17,7 +17,7 @@ %token TOK_STRING TOK_SUBNET TOK_SWITCH TOK_TABLE %token TOK_TIME TOK_TIMEOUT TOK_TIMER TOK_TYPE TOK_UNION TOK_VECTOR TOK_WHEN -%token TOK_ATTR_ADD_FUNC TOK_ATTR_ATTR TOK_ATTR_ENCRYPT TOK_ATTR_DEFAULT +%token TOK_ATTR_ADD_FUNC TOK_ATTR_ENCRYPT TOK_ATTR_DEFAULT %token TOK_ATTR_OPTIONAL TOK_ATTR_REDEF TOK_ATTR_ROTATE_INTERVAL %token TOK_ATTR_ROTATE_SIZE TOK_ATTR_DEL_FUNC TOK_ATTR_EXPIRE_FUNC %token TOK_ATTR_EXPIRE_CREATE TOK_ATTR_EXPIRE_READ TOK_ATTR_EXPIRE_WRITE diff --git a/src/scan.l b/src/scan.l index 4e1a66144e..bf4cd76f23 100644 --- a/src/scan.l +++ b/src/scan.l @@ -319,7 +319,6 @@ vector return TOK_VECTOR; when return TOK_WHEN; &add_func return TOK_ATTR_ADD_FUNC; -&attr return TOK_ATTR_ATTR; &create_expire return TOK_ATTR_EXPIRE_CREATE; &default return TOK_ATTR_DEFAULT; &delete_func return TOK_ATTR_DEL_FUNC; From aff58984422814c98b89c4d2036b34acd1119602 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 11 Dec 2012 16:26:01 -0600 Subject: [PATCH 20/27] Maybe fix reliability of a unit test that relies on when statements. --- .../Baseline/core.dns-interpreter-exceptions/out | 12 ------------ .../core.when-interpreter-exceptions/bro..stderr | 5 +++++ .../core.when-interpreter-exceptions/bro..stdout | 8 ++++++++ ...xceptions.bro => when-interpreter-exceptions.bro} | 8 ++++++-- 4 files changed, 19 insertions(+), 14 deletions(-) delete mode 100644 testing/btest/Baseline/core.dns-interpreter-exceptions/out create mode 100644 testing/btest/Baseline/core.when-interpreter-exceptions/bro..stderr create mode 100644 testing/btest/Baseline/core.when-interpreter-exceptions/bro..stdout rename testing/btest/core/{dns-interpreter-exceptions.bro => when-interpreter-exceptions.bro} (80%) diff --git a/testing/btest/Baseline/core.dns-interpreter-exceptions/out b/testing/btest/Baseline/core.dns-interpreter-exceptions/out deleted file mode 100644 index c081edc489..0000000000 --- a/testing/btest/Baseline/core.dns-interpreter-exceptions/out +++ /dev/null @@ -1,12 +0,0 @@ -1300475167.096535 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 28: field value missing [p$ip] -1300475167.096535 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 49: field value missing [p$ip] -1300475168.902195 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 39: field value missing [p$ip] -1300475168.902195 expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.dns-interpreter-exceptions/dns-interpreter-exceptions.bro, line 12: field value missing [p$ip] -timeout g(), F -timeout g(), T -timeout -g() done, no exception, T -localhost resolved -localhost resolved from f(), T -localhost resolved from f(), F -f() done, no exception, T diff --git a/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stderr b/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stderr new file mode 100644 index 0000000000..256600445d --- /dev/null +++ b/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stderr @@ -0,0 +1,5 @@ +1355264617.053514 expression error in /home/jsiwek/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.bro, line 32: field value missing [p$ip] +1355264617.053514 expression error in /home/jsiwek/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.bro, line 53: field value missing [p$ip] +1355264617.053514 expression error in /home/jsiwek/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.bro, line 43: field value missing [p$ip] +1355264617.053514 expression error in /home/jsiwek/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.bro, line 16: field value missing [p$ip] +1355264617.053514 received termination signal diff --git a/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stdout b/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stdout new file mode 100644 index 0000000000..49eafc365f --- /dev/null +++ b/testing/btest/Baseline/core.when-interpreter-exceptions/bro..stdout @@ -0,0 +1,8 @@ +timeout g(), F +timeout g(), T +timeout +g() done, no exception, T +localhost resolved +localhost resolved from f(), T +localhost resolved from f(), F +f() done, no exception, T diff --git a/testing/btest/core/dns-interpreter-exceptions.bro b/testing/btest/core/when-interpreter-exceptions.bro similarity index 80% rename from testing/btest/core/dns-interpreter-exceptions.bro rename to testing/btest/core/when-interpreter-exceptions.bro index a795971b58..b1880c5139 100644 --- a/testing/btest/core/dns-interpreter-exceptions.bro +++ b/testing/btest/core/when-interpreter-exceptions.bro @@ -1,6 +1,10 @@ -# @TEST-EXEC: bro -b -r $TRACES/wikipedia.trace %INPUT >out 2>&1 -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/rotation.trace %INPUT +# @TEST-EXEC: btest-bg-wait -k 3 +# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff bro/.stderr +# @TEST-EXEC: btest-diff bro/.stdout + # interpreter exceptions in "when" blocks shouldn't cause termination + global p: pkt_hdr; function f(do_exception: bool): bool From 43ed437daabb4575549e82f53881980353905242 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 11 Dec 2012 17:06:54 -0600 Subject: [PATCH 21/27] Trick for parallelizing input framework unit tests. Instead of loading listen.bro to block until files are read, just read a pcap file in pseudo-realtime. Seems to work well. --- .../.stderrwithoutfirstline | 14 +++++++------- .../.stderrwithoutfirstline | 6 +++--- .../bro..stderr | 10 +++++----- .../btest/scripts/base/frameworks/input/basic.bro | 6 +----- .../scripts/base/frameworks/input/bignumber.bro | 7 +------ .../btest/scripts/base/frameworks/input/binary.bro | 7 +------ .../base/frameworks/input/empty-values-hashing.bro | 8 +------- .../scripts/base/frameworks/input/emptyvals.bro | 7 +------ .../btest/scripts/base/frameworks/input/event.bro | 7 +------ .../scripts/base/frameworks/input/executeraw.bro | 7 +------ .../base/frameworks/input/invalidnumbers.bro | 9 ++------- .../scripts/base/frameworks/input/invalidtext.bro | 9 ++------- .../scripts/base/frameworks/input/missing-file.bro | 7 +------ .../base/frameworks/input/onecolumn-norecord.bro | 7 +------ .../base/frameworks/input/onecolumn-record.bro | 7 +------ .../scripts/base/frameworks/input/optional.bro | 7 +------ .../btest/scripts/base/frameworks/input/port.bro | 7 +------ .../base/frameworks/input/predicate-stream.bro | 7 +------ .../scripts/base/frameworks/input/predicate.bro | 7 +------ .../base/frameworks/input/predicatemodify.bro | 7 +------ .../frameworks/input/predicatemodifyandreread.bro | 7 +------ .../input/predicaterefusesecondsamerecord.bro | 7 +------ .../btest/scripts/base/frameworks/input/raw.bro | 7 +------ .../btest/scripts/base/frameworks/input/repeat.bro | 7 +------ .../btest/scripts/base/frameworks/input/reread.bro | 6 +----- .../scripts/base/frameworks/input/rereadraw.bro | 7 +------ .../btest/scripts/base/frameworks/input/set.bro | 7 +------ .../scripts/base/frameworks/input/setseparator.bro | 7 +------ .../base/frameworks/input/setspecialcases.bro | 8 +------- .../btest/scripts/base/frameworks/input/stream.bro | 6 +----- .../scripts/base/frameworks/input/streamraw.bro | 7 +------ .../base/frameworks/input/subrecord-event.bro | 6 +----- .../scripts/base/frameworks/input/subrecord.bro | 6 +----- .../scripts/base/frameworks/input/tableevent.bro | 7 +------ .../scripts/base/frameworks/input/twotables.bro | 6 +----- .../base/frameworks/input/unsupported_types.bro | 6 +----- 36 files changed, 50 insertions(+), 210 deletions(-) diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline index 3ef51e40f2..54005fb4b8 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline @@ -1,8 +1,8 @@ -error: ../input.log/Input::READER_ASCII: Number '12129223372036854775800' out of supported range. -error: ../input.log/Input::READER_ASCII: Could not convert line '12129223372036854775800 121218446744073709551612' to Val. Ignoring line. -warning: ../input.log/Input::READER_ASCII: Number '9223372036854775801TEXTHERE' contained non-numeric trailing characters. Ignored trailing characters 'TEXTHERE' -warning: ../input.log/Input::READER_ASCII: Number '1Justtext' contained non-numeric trailing characters. Ignored trailing characters 'Justtext' -error: ../input.log/Input::READER_ASCII: String 'Justtext' contained no parseable number -error: ../input.log/Input::READER_ASCII: Could not convert line 'Justtext 1' to Val. Ignoring line. -received termination signal +1355266097.683599 error: ../input.log/Input::READER_ASCII: Number '12129223372036854775800' out of supported range. +1355266097.683599 error: ../input.log/Input::READER_ASCII: Could not convert line '12129223372036854775800 121218446744073709551612' to Val. Ignoring line. +1355266097.683599 warning: ../input.log/Input::READER_ASCII: Number '9223372036854775801TEXTHERE' contained non-numeric trailing characters. Ignored trailing characters 'TEXTHERE' +1355266097.683599 warning: ../input.log/Input::READER_ASCII: Number '1Justtext' contained non-numeric trailing characters. Ignored trailing characters 'Justtext' +1355266097.683599 error: ../input.log/Input::READER_ASCII: String 'Justtext' contained no parseable number +1355266097.683599 error: ../input.log/Input::READER_ASCII: Could not convert line 'Justtext 1' to Val. Ignoring line. +1355266097.683599 received termination signal >>> diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline index 3d8ba5e267..f0545daeae 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidtext/.stderrwithoutfirstline @@ -1,4 +1,4 @@ -error: ../input.log/Input::READER_ASCII: String 'l' contained no parseable number -error: ../input.log/Input::READER_ASCII: Could not convert line ' l' to Val. Ignoring line. -received termination signal +1355265853.593476 error: ../input.log/Input::READER_ASCII: String 'l' contained no parseable number +1355265853.593476 error: ../input.log/Input::READER_ASCII: Could not convert line ' l' to Val. Ignoring line. +1355265853.593476 received termination signal >>> diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.missing-file/bro..stderr b/testing/btest/Baseline/scripts.base.frameworks.input.missing-file/bro..stderr index 4380007b93..e61280cdfc 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.missing-file/bro..stderr +++ b/testing/btest/Baseline/scripts.base.frameworks.input.missing-file/bro..stderr @@ -1,5 +1,5 @@ -error: does-not-exist.dat/Input::READER_ASCII: Init: cannot open does-not-exist.dat -error: does-not-exist.dat/Input::READER_ASCII: Init failed -warning: Stream input is already queued for removal. Ignoring remove. -error: does-not-exist.dat/Input::READER_ASCII: terminating thread -received termination signal +1355265996.626106 error: does-not-exist.dat/Input::READER_ASCII: Init: cannot open does-not-exist.dat +1355265996.626106 error: does-not-exist.dat/Input::READER_ASCII: Init failed +1355265996.626106 warning: Stream input is already queued for removal. Ignoring remove. +1355265996.626106 error: does-not-exist.dat/Input::READER_ASCII: terminating thread +1355265996.626106 received termination signal diff --git a/testing/btest/scripts/base/frameworks/input/basic.bro b/testing/btest/scripts/base/frameworks/input/basic.bro index dfac84d062..fbb320e03f 100644 --- a/testing/btest/scripts/base/frameworks/input/basic.bro +++ b/testing/btest/scripts/base/frameworks/input/basic.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,7 +11,6 @@ T -42 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen global outfile: file; diff --git a/testing/btest/scripts/base/frameworks/input/bignumber.bro b/testing/btest/scripts/base/frameworks/input/bignumber.bro index 5b93472551..098481a518 100644 --- a/testing/btest/scripts/base/frameworks/input/bignumber.bro +++ b/testing/btest/scripts/base/frameworks/input/bignumber.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -13,8 +10,6 @@ -9223372036854775800 18446744073709551612 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/binary.bro b/testing/btest/scripts/base/frameworks/input/binary.bro index 8d75abc5a9..7caa734d34 100644 --- a/testing/btest/scripts/base/frameworks/input/binary.bro +++ b/testing/btest/scripts/base/frameworks/input/binary.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -25,8 +22,6 @@ abc\xff\x7cdef|DATA2 #end|2012-07-20-01-49-19 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/empty-values-hashing.bro b/testing/btest/scripts/base/frameworks/input/empty-values-hashing.bro index c8760b467e..78f3d3a72e 100644 --- a/testing/btest/scripts/base/frameworks/input/empty-values-hashing.bro +++ b/testing/btest/scripts/base/frameworks/input/empty-values-hashing.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 2 # @TEST-EXEC: cp input2.log input.log # @TEST-EXEC: btest-bg-wait -k 5 @@ -23,9 +20,6 @@ 2 TEST TEST @TEST-END-FILE -@load frameworks/communication/listen - - module A; type Idx: record { diff --git a/testing/btest/scripts/base/frameworks/input/emptyvals.bro b/testing/btest/scripts/base/frameworks/input/emptyvals.bro index 94b0f1b620..e5e9bc22e3 100644 --- a/testing/btest/scripts/base/frameworks/input/emptyvals.bro +++ b/testing/btest/scripts/base/frameworks/input/emptyvals.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,8 +11,6 @@ T 1 - 2 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/event.bro b/testing/btest/scripts/base/frameworks/input/event.bro index ba47d5e3f2..7d553a53e3 100644 --- a/testing/btest/scripts/base/frameworks/input/event.bro +++ b/testing/btest/scripts/base/frameworks/input/event.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -19,8 +16,6 @@ 7 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/executeraw.bro b/testing/btest/scripts/base/frameworks/input/executeraw.bro index 626b9cdfd2..09cd920bee 100644 --- a/testing/btest/scripts/base/frameworks/input/executeraw.bro +++ b/testing/btest/scripts/base/frameworks/input/executeraw.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: cat out.tmp | sed 's/^ *//g' >out # @TEST-EXEC: btest-diff out @@ -17,8 +14,6 @@ sdf 3rw43wRRERLlL#RWERERERE. @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; type Val: record { diff --git a/testing/btest/scripts/base/frameworks/input/invalidnumbers.bro b/testing/btest/scripts/base/frameworks/input/invalidnumbers.bro index 1deec605ae..3c467598ad 100644 --- a/testing/btest/scripts/base/frameworks/input/invalidnumbers.bro +++ b/testing/btest/scripts/base/frameworks/input/invalidnumbers.bro @@ -1,11 +1,8 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out # @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline +# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff .stderrwithoutfirstline @TEST-START-FILE input.log #separator \x09 @@ -17,8 +14,6 @@ Justtext 1 9223372036854775800 -18446744073709551612 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/invalidtext.bro b/testing/btest/scripts/base/frameworks/input/invalidtext.bro index 75efb1247d..668716d045 100644 --- a/testing/btest/scripts/base/frameworks/input/invalidtext.bro +++ b/testing/btest/scripts/base/frameworks/input/invalidtext.bro @@ -1,11 +1,8 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out # @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline +# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff .stderrwithoutfirstline @TEST-START-FILE input.log #separator \x09 @@ -15,8 +12,6 @@ 5 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/missing-file.bro b/testing/btest/scripts/base/frameworks/input/missing-file.bro index aa5acf619e..7048698221 100644 --- a/testing/btest/scripts/base/frameworks/input/missing-file.bro +++ b/testing/btest/scripts/base/frameworks/input/missing-file.bro @@ -1,12 +1,7 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff bro/.stderr -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/onecolumn-norecord.bro b/testing/btest/scripts/base/frameworks/input/onecolumn-norecord.bro index c08b1420fb..505aa2245d 100644 --- a/testing/btest/scripts/base/frameworks/input/onecolumn-norecord.bro +++ b/testing/btest/scripts/base/frameworks/input/onecolumn-norecord.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -13,8 +10,6 @@ T -42 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/onecolumn-record.bro b/testing/btest/scripts/base/frameworks/input/onecolumn-record.bro index 9e420e75fe..e85267b4c3 100644 --- a/testing/btest/scripts/base/frameworks/input/onecolumn-record.bro +++ b/testing/btest/scripts/base/frameworks/input/onecolumn-record.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -13,8 +10,6 @@ T -42 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/optional.bro b/testing/btest/scripts/base/frameworks/input/optional.bro index 2fe0e5c86f..670f0f48ba 100644 --- a/testing/btest/scripts/base/frameworks/input/optional.bro +++ b/testing/btest/scripts/base/frameworks/input/optional.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -19,8 +16,6 @@ 7 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/port.bro b/testing/btest/scripts/base/frameworks/input/port.bro index 081c59559b..2225132395 100644 --- a/testing/btest/scripts/base/frameworks/input/port.bro +++ b/testing/btest/scripts/base/frameworks/input/port.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -12,8 +9,6 @@ 1.2.3.6 30 unknown @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/predicate-stream.bro b/testing/btest/scripts/base/frameworks/input/predicate-stream.bro index 8cf927e346..b931bbc41e 100644 --- a/testing/btest/scripts/base/frameworks/input/predicate-stream.bro +++ b/testing/btest/scripts/base/frameworks/input/predicate-stream.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out # @@ -23,8 +20,6 @@ 7 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/predicate.bro b/testing/btest/scripts/base/frameworks/input/predicate.bro index 8fb33242e8..9f2c4362de 100644 --- a/testing/btest/scripts/base/frameworks/input/predicate.bro +++ b/testing/btest/scripts/base/frameworks/input/predicate.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -19,8 +16,6 @@ 7 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/predicatemodify.bro b/testing/btest/scripts/base/frameworks/input/predicatemodify.bro index 17467bbc27..4129a47873 100644 --- a/testing/btest/scripts/base/frameworks/input/predicatemodify.bro +++ b/testing/btest/scripts/base/frameworks/input/predicatemodify.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,8 +11,6 @@ 2 T test2 idx2 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/predicatemodifyandreread.bro b/testing/btest/scripts/base/frameworks/input/predicatemodifyandreread.bro index 5a9e993651..17e7fa4bf2 100644 --- a/testing/btest/scripts/base/frameworks/input/predicatemodifyandreread.bro +++ b/testing/btest/scripts/base/frameworks/input/predicatemodifyandreread.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 2 # @TEST-EXEC: cp input2.log input.log # @TEST-EXEC: sleep 2 @@ -58,8 +55,6 @@ 1 T test1 idx1 @TEST-END-FILE -@load frameworks/communication/listen - redef InputAscii::empty_field = "EMPTY"; module A; diff --git a/testing/btest/scripts/base/frameworks/input/predicaterefusesecondsamerecord.bro b/testing/btest/scripts/base/frameworks/input/predicaterefusesecondsamerecord.bro index ba0b468cdc..0df8b14dd6 100644 --- a/testing/btest/scripts/base/frameworks/input/predicaterefusesecondsamerecord.bro +++ b/testing/btest/scripts/base/frameworks/input/predicaterefusesecondsamerecord.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -17,8 +14,6 @@ need-to-know 8c864306-d21a-37b1-8705-746a786719bf medium 95 1342569600 1.228.83. need-to-know 8c864306-d21a-37b1-8705-746a786719bf medium 65 1342656000 1.228.83.33 - - 9318 HANARO-AS Hanaro Telecom Inc. 1.224.0.0/13 apnic KR spam infrastructure spamming;malware domain public http://reputation.alienvault.com/reputation.generic @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/raw.bro b/testing/btest/scripts/base/frameworks/input/raw.bro index d15aec22bb..7201e9ad3a 100644 --- a/testing/btest/scripts/base/frameworks/input/raw.bro +++ b/testing/btest/scripts/base/frameworks/input/raw.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -16,8 +13,6 @@ sdf 3rw43wRRERLlL#RWERERERE. @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/repeat.bro b/testing/btest/scripts/base/frameworks/input/repeat.bro index a966ac064e..f29061fa8b 100644 --- a/testing/btest/scripts/base/frameworks/input/repeat.bro +++ b/testing/btest/scripts/base/frameworks/input/repeat.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out @@ -13,8 +10,6 @@ 1 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/reread.bro b/testing/btest/scripts/base/frameworks/input/reread.bro index 11aa873f9d..bfb7b6fd84 100644 --- a/testing/btest/scripts/base/frameworks/input/reread.bro +++ b/testing/btest/scripts/base/frameworks/input/reread.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 2 # @TEST-EXEC: cp input2.log input.log # @TEST-EXEC: sleep 2 @@ -59,7 +56,6 @@ F -48 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/rereadraw.bro b/testing/btest/scripts/base/frameworks/input/rereadraw.bro index 2fdcdc8f9e..d1db2bb049 100644 --- a/testing/btest/scripts/base/frameworks/input/rereadraw.bro +++ b/testing/btest/scripts/base/frameworks/input/rereadraw.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -16,8 +13,6 @@ sdf 3rw43wRRERLlL#RWERERERE. @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/set.bro b/testing/btest/scripts/base/frameworks/input/set.bro index b2b5cea323..a460f6788a 100644 --- a/testing/btest/scripts/base/frameworks/input/set.bro +++ b/testing/btest/scripts/base/frameworks/input/set.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out @@ -16,8 +13,6 @@ 192.168.17.42 @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/setseparator.bro b/testing/btest/scripts/base/frameworks/input/setseparator.bro index b7148d80bd..156f566d28 100644 --- a/testing/btest/scripts/base/frameworks/input/setseparator.bro +++ b/testing/btest/scripts/base/frameworks/input/setseparator.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out @@ -13,8 +10,6 @@ redef InputAscii::set_separator = "|"; -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/setspecialcases.bro b/testing/btest/scripts/base/frameworks/input/setspecialcases.bro index 022eac9731..86e53feb0a 100644 --- a/testing/btest/scripts/base/frameworks/input/setspecialcases.bro +++ b/testing/btest/scripts/base/frameworks/input/setspecialcases.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out @@ -16,9 +13,6 @@ 6 @TEST-END-FILE - -@load frameworks/communication/listen - global outfile: file; module A; diff --git a/testing/btest/scripts/base/frameworks/input/stream.bro b/testing/btest/scripts/base/frameworks/input/stream.bro index 1ecd8a2eb0..684f4ea395 100644 --- a/testing/btest/scripts/base/frameworks/input/stream.bro +++ b/testing/btest/scripts/base/frameworks/input/stream.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 3 # @TEST-EXEC: cat input2.log >> input.log # @TEST-EXEC: sleep 3 @@ -25,7 +22,6 @@ F -43 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/streamraw.bro b/testing/btest/scripts/base/frameworks/input/streamraw.bro index 3bc06f7dea..d8e43d6386 100644 --- a/testing/btest/scripts/base/frameworks/input/streamraw.bro +++ b/testing/btest/scripts/base/frameworks/input/streamraw.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 3 # @TEST-EXEC: cat input2.log >> input.log # @TEST-EXEC: sleep 3 @@ -27,8 +24,6 @@ sdf 3rw43wRRERLlL#RWERERERE. @TEST-END-FILE -@load frameworks/communication/listen - module A; type Val: record { diff --git a/testing/btest/scripts/base/frameworks/input/subrecord-event.bro b/testing/btest/scripts/base/frameworks/input/subrecord-event.bro index 4e7dc1690a..92ee6dd500 100644 --- a/testing/btest/scripts/base/frameworks/input/subrecord-event.bro +++ b/testing/btest/scripts/base/frameworks/input/subrecord-event.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,7 +11,6 @@ T -42 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/subrecord.bro b/testing/btest/scripts/base/frameworks/input/subrecord.bro index 512b8ec58f..11f247f764 100644 --- a/testing/btest/scripts/base/frameworks/input/subrecord.bro +++ b/testing/btest/scripts/base/frameworks/input/subrecord.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,7 +11,6 @@ T -42 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen global outfile: file; diff --git a/testing/btest/scripts/base/frameworks/input/tableevent.bro b/testing/btest/scripts/base/frameworks/input/tableevent.bro index 723e519237..db39fdf72b 100644 --- a/testing/btest/scripts/base/frameworks/input/tableevent.bro +++ b/testing/btest/scripts/base/frameworks/input/tableevent.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -19,8 +16,6 @@ 7 T @TEST-END-FILE -@load frameworks/communication/listen - global outfile: file; global try: count; diff --git a/testing/btest/scripts/base/frameworks/input/twotables.bro b/testing/btest/scripts/base/frameworks/input/twotables.bro index 83ae86cd46..5540019971 100644 --- a/testing/btest/scripts/base/frameworks/input/twotables.bro +++ b/testing/btest/scripts/base/frameworks/input/twotables.bro @@ -1,8 +1,5 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# # @TEST-EXEC: cp input1.log input.log -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: sleep 5 # @TEST-EXEC: cp input3.log input.log # @TEST-EXEC: btest-bg-wait -k 10 @@ -34,7 +31,6 @@ F -44 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.000000 hurz @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen redef InputAscii::empty_field = "EMPTY"; diff --git a/testing/btest/scripts/base/frameworks/input/unsupported_types.bro b/testing/btest/scripts/base/frameworks/input/unsupported_types.bro index e1350f61a9..0651e0693e 100644 --- a/testing/btest/scripts/base/frameworks/input/unsupported_types.bro +++ b/testing/btest/scripts/base/frameworks/input/unsupported_types.bro @@ -1,7 +1,4 @@ -# (uses listen.bro just to ensure input sources are more reliably fully-read). -# @TEST-SERIALIZE: comm -# -# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-run bro bro -b --pseudo-realtime -r $TRACES/socks.trace %INPUT # @TEST-EXEC: btest-bg-wait -k 5 # @TEST-EXEC: btest-diff out @@ -14,7 +11,6 @@ whatever T -42 SSH::LOG 21 123 10.0.0.0/24 1.2.3.4 3.14 1315801931.273616 100.00 @TEST-END-FILE @load base/protocols/ssh -@load frameworks/communication/listen global outfile: file; From 6603b851fe0aafdff8cc11dd6b0153b329c59453 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 12 Dec 2012 14:29:10 -0800 Subject: [PATCH 22/27] Updating submodule(s). [nomail] --- aux/broctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broctl b/aux/broctl index 91e3b8ad44..f4d6a2af15 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 91e3b8ad445cb4d8919b4ee1cc6f0753c3fa0a55 +Subproject commit f4d6a2af15404dc1349d12d2ad21a3eebcb2ff1e From 0cf98ac3259d503f479460b721833d43095d216b Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Thu, 13 Dec 2012 10:27:08 -0500 Subject: [PATCH 23/27] Improved file name extraction for SMTP when file name is included in Content-Type header. --- scripts/base/protocols/smtp/entities.bro | 4 ++++ scripts/base/utils/files.bro | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/base/protocols/smtp/entities.bro b/scripts/base/protocols/smtp/entities.bro index e158d045e0..b4b5fd1f03 100644 --- a/scripts/base/protocols/smtp/entities.bro +++ b/scripts/base/protocols/smtp/entities.bro @@ -177,6 +177,10 @@ event mime_one_header(c: connection, h: mime_header_rec) if ( h$name == "CONTENT-DISPOSITION" && /[fF][iI][lL][eE][nN][aA][mM][eE]/ in h$value ) c$smtp$current_entity$filename = extract_filename_from_content_disposition(h$value); + + if ( h$name == "CONTENT-TYPE" && + /[nN][aA][mM][eE][:blank:]*=/ in h$value ) + c$smtp$current_entity$filename = extract_filename_from_content_disposition(h$value); } event mime_end_entity(c: connection) &priority=-5 diff --git a/scripts/base/utils/files.bro b/scripts/base/utils/files.bro index e1e599b0b6..76d2ecea4f 100644 --- a/scripts/base/utils/files.bro +++ b/scripts/base/utils/files.bro @@ -19,7 +19,7 @@ function generate_extraction_filename(prefix: string, c: connection, suffix: str ## the filename. function extract_filename_from_content_disposition(data: string): string { - local filename = sub(data, /^.*[fF][iI][lL][eE][nN][aA][mM][eE][[:blank:]]*=[[:blank:]]*/, ""); + local filename = sub(data, /^.*[nN][aA][mM][eE][[:blank:]]*=[[:blank:]]*/, ""); # Remove quotes around the filename if they are there. if ( /^\"/ in filename ) filename = split_n(filename, /\"/, F, 2)[2]; From 3c27267223bbd3f6c9910ef20acb9ce0e42cfacb Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Thu, 13 Dec 2012 11:09:41 -0500 Subject: [PATCH 24/27] Improvements for the "bad checksums" detector to make it detect bad TCP checksums. --- .../base/misc/find-checksum-offloading.bro | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/scripts/base/misc/find-checksum-offloading.bro b/scripts/base/misc/find-checksum-offloading.bro index a0a2c692b7..f371628c33 100644 --- a/scripts/base/misc/find-checksum-offloading.bro +++ b/scripts/base/misc/find-checksum-offloading.bro @@ -14,7 +14,8 @@ export { } # Keep track of how many bad checksums have been seen. -global bad_checksums = 0; +global bad_ip_checksums = 0; +global bad_tcp_checksums = 0; # Track to see if this script is done so that messages aren't created multiple times. global done = F; @@ -25,10 +26,19 @@ event ChecksumOffloading::check() return; local pkts_recvd = net_stats()$pkts_recvd; - if ( (bad_checksums*1.0 / net_stats()$pkts_recvd*1.0) > 0.05 ) + local bad_ip_checksum_pct = bad_ip_checksums*1.0 / net_stats()$pkts_recvd*1.0; + local bad_tcp_checksum_pct = bad_tcp_checksums*1.0 / net_stats()$pkts_recvd*1.0; + if ( bad_ip_checksum_pct > 0.05 || bad_tcp_checksum_pct > 0.05 ) { local packet_src = reading_traces() ? "trace file likely has" : "interface is likely receiving"; - local message = fmt("Your %s invalid IP checksums, most likely from NIC checksum offloading.", packet_src); + local bad_checksum_msg = bad_ip_checksum_pct > 0.0 ? "IP" : ""; + if ( bad_tcp_checksum_pct > 0.0 ) + { + if ( |bad_checksum_msg| > 0 ) + bad_checksum_msg += " and "; + bad_checksum_msg += "TCP"; + } + local message = fmt("Your %s invalid %s checksums, most likely from NIC checksum offloading.", packet_src, bad_checksum_msg); Reporter::warning(message); done = T; } @@ -48,7 +58,13 @@ event bro_init() event net_weird(name: string) { if ( name == "bad_IP_checksum" ) - ++bad_checksums; + ++bad_ip_checksums; + } + +event conn_weird(name: string, c: connection, addl: string) + { + if ( name == "bad_TCP_checksum" ) + ++bad_tcp_checksums; } event bro_done() From 524e15f2c5d49e8a3883e83f01078487c289cacd Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Thu, 13 Dec 2012 11:41:13 -0800 Subject: [PATCH 25/27] Fix memory leak in ascii input reader. In case an error was encountered while parsing an element, that element itself was not deleted, but remained in memory indefenitely. --- src/input/readers/Ascii.cc | 42 ++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/input/readers/Ascii.cc b/src/input/readers/Ascii.cc index 173ce418ca..e2ddffd9ff 100644 --- a/src/input/readers/Ascii.cc +++ b/src/input/readers/Ascii.cc @@ -273,14 +273,14 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { Error(Fmt("Field: %s Invalid value for boolean: %s", field.name.c_str(), s.c_str())); - return 0; + goto parse_error; } break; case TYPE_INT: val->val.int_val = strtoll(s.c_str(), &end, 10); if ( CheckNumberError(s, end) ) - return 0; + goto parse_error; break; case TYPE_DOUBLE: @@ -288,20 +288,20 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) case TYPE_INTERVAL: val->val.double_val = strtod(s.c_str(), &end); if ( CheckNumberError(s, end) ) - return 0; + goto parse_error; break; case TYPE_COUNT: case TYPE_COUNTER: val->val.uint_val = strtoull(s.c_str(), &end, 10); if ( CheckNumberError(s, end) ) - return 0; + goto parse_error; break; case TYPE_PORT: val->val.port_val.port = strtoull(s.c_str(), &end, 10); if ( CheckNumberError(s, end) ) - return 0; + goto parse_error; val->val.port_val.proto = TRANSPORT_UNKNOWN; break; @@ -313,13 +313,13 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) if ( pos == s.npos ) { Error(Fmt("Invalid value for subnet: %s", s.c_str())); - return 0; + goto parse_error; } uint8_t width = (uint8_t) strtol(s.substr(pos+1).c_str(), &end, 10); if ( CheckNumberError(s, end) ) - return 0; + goto parse_error; string addr = s.substr(0, pos); @@ -349,6 +349,7 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) } unsigned int pos = 0; + bool error = false; if ( s.compare(empty_field) == 0 ) length = 0; @@ -385,14 +386,16 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { Error(Fmt("Internal error while parsing set. pos %d >= length %d." " Element: %s", pos, length, element.c_str())); + error = true; break; } Value* newval = EntryToVal(element, field.subType()); if ( newval == 0 ) { - Error("Error while reading set"); - return 0; + Error("Error while reading set or vector"); + error = true; + break; } lvals[pos] = newval; @@ -403,22 +406,31 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) // Test if the string ends with a set_separator... or if the // complete string is empty. In either of these cases we have // to push an empty val on top of it. - if ( s.empty() || *s.rbegin() == set_separator[0] ) + if ( !error && ( s.empty() || *s.rbegin() == set_separator[0] ) ) { lvals[pos] = EntryToVal("", field.subType()); if ( lvals[pos] == 0 ) { Error("Error while trying to add empty set element"); - return 0; + goto parse_error; } pos++; } + if ( error ) { + // we had an error while reading a set or a vector. + // hence we have to clean up the values that have been read so far + for ( int i = 0; i < pos; i++ ) + delete lvals[i]; + + goto parse_error; + } + if ( pos != length ) { Error(Fmt("Internal error while parsing set: did not find all elements: %s", s.c_str())); - return 0; + goto parse_error; } break; @@ -427,10 +439,14 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) default: Error(Fmt("unsupported field format %d for %s", field.type, field.name.c_str())); - return 0; + goto parse_error; } return val; + +parse_error: + delete val; + return 0; } // read the entire file and send appropriate thingies back to InputMgr From 290c2a0b4df2db38ade684cf386a5c9b6b271d9e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 13 Dec 2012 15:05:29 -0600 Subject: [PATCH 26/27] Make const variables actually constant. Addresses #922. Both local and global variables declared with "const" could be modified, but now expressions that would modify them should generate an error message at parse-time. --- scripts/base/frameworks/notice/cluster.bro | 6 +- src/Expr.cc | 15 +++- src/Expr.h | 3 +- src/Var.cc | 4 +- .../Baseline/language.const/invalid.stderr | 13 +++ .../Baseline/language.const/invalid.stdout | 0 .../Baseline/language.const/valid.stderr | 0 .../Baseline/language.const/valid.stdout | 10 +++ testing/btest/language/const.bro | 79 +++++++++++++++++++ 9 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 testing/btest/Baseline/language.const/invalid.stderr create mode 100644 testing/btest/Baseline/language.const/invalid.stdout create mode 100644 testing/btest/Baseline/language.const/valid.stderr create mode 100644 testing/btest/Baseline/language.const/valid.stdout create mode 100644 testing/btest/language/const.bro diff --git a/scripts/base/frameworks/notice/cluster.bro b/scripts/base/frameworks/notice/cluster.bro index 3ee113acf3..e812c3fdca 100644 --- a/scripts/base/frameworks/notice/cluster.bro +++ b/scripts/base/frameworks/notice/cluster.bro @@ -21,12 +21,10 @@ redef Cluster::manager2worker_events += /Notice::begin_suppression/; redef Cluster::worker2manager_events += /Notice::cluster_notice/; @if ( Cluster::local_node_type() != Cluster::MANAGER ) + # The notice policy is completely handled by the manager and shouldn't be # done by workers or proxies to save time for packet processing. -event bro_init() &priority=11 - { - Notice::policy = table(); - } +redef Notice::policy = table(); event Notice::begin_suppression(n: Notice::Info) { diff --git a/src/Expr.cc b/src/Expr.cc index 7995d5d495..3a4e8add70 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -229,9 +229,10 @@ bool Expr::DoUnserialize(UnserialInfo* info) } -NameExpr::NameExpr(ID* arg_id) : Expr(EXPR_NAME) +NameExpr::NameExpr(ID* arg_id, bool const_init) : Expr(EXPR_NAME) { id = arg_id; + in_const_init = const_init; SetType(id->Type()->Ref()); EventHandler* h = event_registry->Lookup(id->Name()); @@ -287,6 +288,9 @@ Expr* NameExpr::MakeLvalue() if ( id->AsType() ) ExprError("Type name is not an lvalue"); + if ( id->IsConst() && ! in_const_init ) + ExprError("const is not a modifiable lvalue"); + return new RefExpr(this); } @@ -337,9 +341,11 @@ bool NameExpr::DoSerialize(SerialInfo* info) const // Write out just the name of the function if requested. if ( info->globals_as_names && id->IsGlobal() ) - return SERIALIZE('n') && SERIALIZE(id->Name()); + return SERIALIZE('n') && SERIALIZE(id->Name()) && + SERIALIZE(in_const_init); else - return SERIALIZE('f') && id->Serialize(info); + return SERIALIZE('f') && id->Serialize(info) && + SERIALIZE(in_const_init); } bool NameExpr::DoUnserialize(UnserialInfo* info) @@ -370,6 +376,9 @@ bool NameExpr::DoUnserialize(UnserialInfo* info) if ( ! id ) return false; + if ( ! UNSERIALIZE(&in_const_init) ) + return false; + return true; } diff --git a/src/Expr.h b/src/Expr.h index afdf02c124..ea17c735b5 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -198,7 +198,7 @@ protected: class NameExpr : public Expr { public: - NameExpr(ID* id); + NameExpr(ID* id, bool const_init = false); ~NameExpr(); ID* Id() const { return id; } @@ -220,6 +220,7 @@ protected: DECLARE_SERIAL(NameExpr); ID* id; + bool in_const_init; }; class ConstExpr : public Expr { diff --git a/src/Var.cc b/src/Var.cc index 2e9fdbe946..b4d76097d3 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -210,7 +210,6 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init, // defined. Func* f = new BroFunc(id, 0, 0, 0, 0); id->SetVal(new Val(f)); - id->SetConst(); } } @@ -233,8 +232,9 @@ Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init, Ref(id); + Expr* name_expr = new NameExpr(id, dt == VAR_CONST); Stmt* stmt = - new ExprStmt(new AssignExpr(new NameExpr(id), init, 0, 0, + new ExprStmt(new AssignExpr(name_expr, init, 0, 0, id->Attrs() ? id->Attrs()->Attrs() : 0 )); stmt->SetLocationInfo(init->GetLocationInfo()); diff --git a/testing/btest/Baseline/language.const/invalid.stderr b/testing/btest/Baseline/language.const/invalid.stderr new file mode 100644 index 0000000000..b08c472708 --- /dev/null +++ b/testing/btest/Baseline/language.const/invalid.stderr @@ -0,0 +1,13 @@ +error in ./invalid.bro, line 15: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 16: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 17: const is not a modifiable lvalue (bar) +error in ./invalid.bro, line 17: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 18: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 19: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 20: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 22: const is not a modifiable lvalue (foo) +error in ./invalid.bro, line 25: const is not a modifiable lvalue (bar) +error in ./invalid.bro, line 26: const is not a modifiable lvalue (baz) +error in ./invalid.bro, line 27: const is not a modifiable lvalue (bar) +error in ./invalid.bro, line 28: const is not a modifiable lvalue (baz) +error in ./invalid.bro, line 33: const is not a modifiable lvalue (foo) diff --git a/testing/btest/Baseline/language.const/invalid.stdout b/testing/btest/Baseline/language.const/invalid.stdout new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/language.const/valid.stderr b/testing/btest/Baseline/language.const/valid.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/language.const/valid.stdout b/testing/btest/Baseline/language.const/valid.stdout new file mode 100644 index 0000000000..5e3a76f060 --- /dev/null +++ b/testing/btest/Baseline/language.const/valid.stdout @@ -0,0 +1,10 @@ +40 +enter f, 10 +exit f, 110 +enter f, 9 +exit f, 109 +enter f, 7 +exit f, 107 +foo, 10 +bar, 9 +baz, 7 diff --git a/testing/btest/language/const.bro b/testing/btest/language/const.bro new file mode 100644 index 0000000000..ee938e8d45 --- /dev/null +++ b/testing/btest/language/const.bro @@ -0,0 +1,79 @@ +# @TEST-EXEC: bro -b valid.bro 2>valid.stderr 1>valid.stdout +# @TEST-EXEC: btest-diff valid.stderr +# @TEST-EXEC: btest-diff valid.stdout + +# @TEST-EXEC-FAIL: bro -b invalid.bro 2>invalid.stderr 1>invalid.stdout +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff invalid.stderr +# @TEST-EXEC: btest-diff invalid.stdout + +@TEST-START-FILE valid.bro +# First some simple code that should be valid and error-free. + +function f(c: count) + { + print "enter f", c; + c = c + 100; + print "exit f", c; + } + +const foo = 0 &redef; +redef foo = 10; + +const bar = 9; + +event bro_init() + { + const baz = 7; + local i = foo; + i = i + bar + 2; + i = i + baz + 11; + ++i; + print i; + --i; + f(foo); + f(bar); + f(baz); + print "foo", foo; + print "bar", bar; + print "baz", baz; + } + +@TEST-END-FILE + +@TEST-START-FILE invalid.bro +# Now some const assignments that should generate errors at parse-time. + +const foo = 0 &redef; +redef foo = 10; + +const bar = 9; + +event bro_init() + { + const baz = 7; + local s = 0; + + print "nope"; + + foo = 100; + foo = bar; + foo = bar = baz; + foo = s; + ++foo; + s = foo = bar; + + if ( foo = 0 ) + print "nope"; + + bar = 1 + 1; + baz = s; + ++bar; + --baz; + + print "foo", foo; + print "bar", bar; + print "baz", baz; + print "foo=foo", foo = foo; + } + +@TEST-END-FILE From 7a2901ec6b7649611e12b9fe8ff090390e8c681e Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 14 Dec 2012 14:35:23 -0800 Subject: [PATCH 27/27] Fixing checksums in test trace because Bro now reports them. :-) --- CHANGES | 8 +++ VERSION | 2 +- .../conn.ds.txt | 46 +++++++++--------- .../conn.ds.txt | 46 +++++++++--------- .../http.ds.txt | 28 +++++------ testing/btest/Traces/wikipedia.trace | Bin 27460 -> 27460 bytes 6 files changed, 69 insertions(+), 61 deletions(-) diff --git a/CHANGES b/CHANGES index e26e7c375d..d0a64e1f0a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,12 @@ +2.1-229 | 2012-12-14 14:46:12 -0800 + + * Fix memory leak in ASCII reader when encoutering errors in input. + (Bernhard Amann) + + * Improvements for the "bad checksums" detector to make it detect + bad TCP checksums. (Seth Hall) + 2.1-223 | 2012-12-12 14:25:15 -0800 * Trick for parallelizing input framework unit tests. Instead of diff --git a/VERSION b/VERSION index 42edbac7b2..44d3909c31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-223 +2.1-229 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt index c4ac546ab6..5d95fdc0c0 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt @@ -56,20 +56,20 @@ ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes 1300475167096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 73 0 0 1300475167097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0 0 0 S0 F 0 D 1 199 0 0 1300475167099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0 0 0 S0 F 0 D 1 179 0 0 -1300475168853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 435 0 89 SHR F 0 Cd 0 0 1 117 -1300475168854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 420 0 99 SHR F 0 Cd 0 0 1 127 -1300475168854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 391 0 183 SHR F 0 Cd 0 0 1 211 -1300475168857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 317 0 89 SHR F 0 Cd 0 0 1 117 -1300475168858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 343 0 99 SHR F 0 Cd 0 0 1 127 -1300475168858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 375 0 183 SHR F 0 Cd 0 0 1 211 -1300475168891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 339 0 89 SHR F 0 Cd 0 0 1 117 -1300475168892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 334 0 99 SHR F 0 Cd 0 0 1 127 -1300475168892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 420 0 183 SHR F 0 Cd 0 0 1 211 -1300475168893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 384 0 89 SHR F 0 Cd 0 0 1 117 -1300475168894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 316 0 99 SHR F 0 Cd 0 0 1 127 -1300475168894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 422 0 183 SHR F 0 Cd 0 0 1 211 -1300475168901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 402 0 131 SHR F 0 Cd 0 0 1 159 -1300475168902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 374 0 198 SHR F 0 Cd 0 0 1 226 +1300475168853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 435 38 89 SF F 0 Dd 1 66 1 117 +1300475168854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 420 52 99 SF F 0 Dd 1 80 1 127 +1300475168854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 391 38 183 SF F 0 Dd 1 66 1 211 +1300475168857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 317 38 89 SF F 0 Dd 1 66 1 117 +1300475168858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 343 52 99 SF F 0 Dd 1 80 1 127 +1300475168858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 375 38 183 SF F 0 Dd 1 66 1 211 +1300475168891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 339 38 89 SF F 0 Dd 1 66 1 117 +1300475168892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 334 52 99 SF F 0 Dd 1 80 1 127 +1300475168892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 420 38 183 SF F 0 Dd 1 66 1 211 +1300475168893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 384 38 89 SF F 0 Dd 1 66 1 117 +1300475168894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 316 52 99 SF F 0 Dd 1 80 1 127 +1300475168894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 422 38 183 SF F 0 Dd 1 66 1 211 +1300475168901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 402 36 131 SF F 0 Dd 1 64 1 159 +1300475168902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 374 36 198 SF F 0 Dd 1 64 1 226 1300475169899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 85 0 0 1300475170862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2613016 350 0 S0 F 0 D 7 546 0 0 1300475171675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 100096 66 0 S0 F 0 D 2 162 0 0 @@ -77,13 +77,13 @@ ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes 1300475173116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 99801 66 0 S0 F 0 D 2 162 0 0 1300475173117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 99848 66 0 S0 F 0 D 2 122 0 0 1300475173153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0 0 0 S0 F 0 D 1 78 0 0 -1300475168859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp 215893 1130 734 S1 F 1130 ShACad 4 216 4 950 -1300475168652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 61328 0 350 OTH F 0 CdA 1 52 1 402 -1300475168895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp 227283 1178 734 S1 F 1178 ShACad 4 216 4 950 -1300475168902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 120040 534 412 S1 F 534 ShACad 3 164 3 576 -1300475168892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp 229603 1148 734 S1 F 1148 ShACad 4 216 4 950 -1300475168855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp 218501 1171 733 S1 F 1171 ShACad 4 216 4 949 -1300475168892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp 220960 1137 733 S1 F 1137 ShACad 4 216 4 949 +1300475168859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp http 215893 1130 734 S1 F 0 ShADad 6 1450 4 950 +1300475168652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 61328 463 350 OTH F 0 DdA 2 567 1 402 +1300475168895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp http 227283 1178 734 S1 F 0 ShADad 6 1498 4 950 +1300475168902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp http 120040 534 412 S1 F 0 ShADad 4 750 3 576 +1300475168892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp http 229603 1148 734 S1 F 0 ShADad 6 1468 4 950 +1300475168855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp http 218501 1171 733 S1 F 0 ShADad 6 1491 4 949 +1300475168892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp http 220960 1137 733 S1 F 0 ShADad 6 1457 4 949 1300475169780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0 0 0 OTH F 0 h 0 0 1 48 -1300475168724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 119904 525 232 S1 F 525 ShACad 3 164 3 396 -1300475168855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp 219720 1125 734 S1 F 1125 ShACad 4 216 4 950 +1300475168724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp http 119904 525 232 S1 F 0 ShADad 4 741 3 396 +1300475168855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp http 219720 1125 734 S1 F 0 ShADad 6 1445 4 950 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt index b74b9fd7e3..5af6f702b8 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt @@ -56,20 +56,20 @@ ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes 1300475167.096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 73 0 0 1300475167.097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0.000000 0 0 S0 F 0 D 1 199 0 0 1300475167.099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0.000000 0 0 S0 F 0 D 1 179 0 0 -1300475168.853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 0.000435 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 0.000420 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 0.000392 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 0.000317 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 0.000343 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 0.000375 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 0.000339 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 0.000335 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 0.000421 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 0.000384 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 0.000317 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 0.000423 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 0.000402 0 131 SHR F 0 Cd 0 0 1 159 -1300475168.902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 0.000374 0 198 SHR F 0 Cd 0 0 1 226 +1300475168.853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 0.000435 38 89 SF F 0 Dd 1 66 1 117 +1300475168.854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 0.000420 52 99 SF F 0 Dd 1 80 1 127 +1300475168.854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 0.000392 38 183 SF F 0 Dd 1 66 1 211 +1300475168.857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 0.000317 38 89 SF F 0 Dd 1 66 1 117 +1300475168.858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 0.000343 52 99 SF F 0 Dd 1 80 1 127 +1300475168.858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 0.000375 38 183 SF F 0 Dd 1 66 1 211 +1300475168.891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 0.000339 38 89 SF F 0 Dd 1 66 1 117 +1300475168.892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 0.000335 52 99 SF F 0 Dd 1 80 1 127 +1300475168.892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 0.000421 38 183 SF F 0 Dd 1 66 1 211 +1300475168.893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 0.000384 38 89 SF F 0 Dd 1 66 1 117 +1300475168.894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 0.000317 52 99 SF F 0 Dd 1 80 1 127 +1300475168.894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 0.000423 38 183 SF F 0 Dd 1 66 1 211 +1300475168.901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 0.000402 36 131 SF F 0 Dd 1 64 1 159 +1300475168.902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 0.000374 36 198 SF F 0 Dd 1 64 1 226 1300475169.899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 85 0 0 1300475170.862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2.613017 350 0 S0 F 0 D 7 546 0 0 1300475171.675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 0.100096 66 0 S0 F 0 D 2 162 0 0 @@ -77,13 +77,13 @@ ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes 1300475173.116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 0.099801 66 0 S0 F 0 D 2 162 0 0 1300475173.117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 0.099849 66 0 S0 F 0 D 2 122 0 0 1300475173.153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0.000000 0 0 S0 F 0 D 1 78 0 0 -1300475168.859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp 0.215893 1130 734 S1 F 1130 ShACad 4 216 4 950 -1300475168.652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 0.061329 0 350 OTH F 0 CdA 1 52 1 402 -1300475168.895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp 0.227284 1178 734 S1 F 1178 ShACad 4 216 4 950 -1300475168.902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 0.120041 534 412 S1 F 534 ShACad 3 164 3 576 -1300475168.892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp 0.229603 1148 734 S1 F 1148 ShACad 4 216 4 950 -1300475168.855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp 0.218501 1171 733 S1 F 1171 ShACad 4 216 4 949 -1300475168.892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp 0.220961 1137 733 S1 F 1137 ShACad 4 216 4 949 +1300475168.859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp http 0.215893 1130 734 S1 F 0 ShADad 6 1450 4 950 +1300475168.652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 0.061329 463 350 OTH F 0 DdA 2 567 1 402 +1300475168.895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp http 0.227284 1178 734 S1 F 0 ShADad 6 1498 4 950 +1300475168.902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp http 0.120041 534 412 S1 F 0 ShADad 4 750 3 576 +1300475168.892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp http 0.229603 1148 734 S1 F 0 ShADad 6 1468 4 950 +1300475168.855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp http 0.218501 1171 733 S1 F 0 ShADad 6 1491 4 949 +1300475168.892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp http 0.220961 1137 733 S1 F 0 ShADad 6 1457 4 949 1300475169.780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0.000000 0 0 OTH F 0 h 0 0 1 48 -1300475168.724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 0.119905 525 232 S1 F 525 ShACad 3 164 3 396 -1300475168.855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp 0.219720 1125 734 S1 F 1125 ShACad 4 216 4 950 +1300475168.724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp http 0.119905 525 232 S1 F 0 ShADad 4 741 3 396 +1300475168.855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp http 0.219720 1125 734 S1 F 0 ShADad 6 1445 4 950 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt index ae62fbec3d..756a49a427 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt @@ -65,17 +65,17 @@ # Extent, type='http' ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file -1300475168.843894 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 0 0 0 304 Not Modified 0 -1300475168.975800 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475168.976327 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475168.979160 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.012666 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.012730 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.014860 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.022665 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 0 0 0 304 Not Modified 0 -1300475169.036294 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.036798 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.039923 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.074793 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.074938 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.075065 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475168.784020 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 1 GET bits.wikimedia.org /skins-1.5/monobook/main.css http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.916018 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/6/63/Wikipedia-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.916183 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.918358 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/b/bd/Bookshelf-40x201_6.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.952307 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.952296 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/4/4a/Wiktionary-logo-en-35px.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.954820 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 1 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikiquote-logo.svg/35px-Wikiquote-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.962687 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 1 GET meta.wikimedia.org /images/wikimedia-button.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.975934 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/f/fa/Wikibooks-logo.svg/35px-Wikibooks-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.976436 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/d/df/Wikispecies-logo.svg/35px-Wikispecies-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475168.979264 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4c/Wikisource-logo.svg/35px-Wikisource-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014619 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/4/4a/Commons-logo.svg/35px-Commons-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014593 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/9/91/Wikiversity-logo.svg/35px-Wikiversity-logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 +1300475169.014927 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 2 GET upload.wikimedia.org /wikipedia/commons/thumb/7/75/Wikimedia_Community_Logo.svg/35px-Wikimedia_Community_Logo.svg.png http://www.wikipedia.org/ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 0 0 304 Not Modified 0 diff --git a/testing/btest/Traces/wikipedia.trace b/testing/btest/Traces/wikipedia.trace index 68d85e0190b0fbefe12ba1bb066c4d06e987c9cf..9e21966243dacf96c2c88650a4cfe7eed70a3709 100644 GIT binary patch delta 309 zcmX?djq%7e#tr<;OuoUJ1)0@ZnRIt;w&E~kVX4}={L5rPN%_frJQtYUmTpeqR@D%zjRsz zY7pmSXOZJ9OD?k5g4Mc+US!!VqWKam3o_AB>?R|Nqw3voxOz8<<4g~qZ045)S{}rA zAP}z9MXH{WNq_t1qtcR$OeW!*AIRh|G0k|k*-u`MnQ5}#<~$`2W+skfn|G+5WoELp z-rTNP#l-Yx%VuUBOJ*jilbh}I?U|Xbdv2~bl4WJ`c)NL?`BD}pjUSs`ZT_$@ae8ld hcHGF$l+V2Ro5yq}rsY#N_j@m5VVb>rvvGi+Gyp4ZYU}_2 delta 309 zcmX?djq%7e#tr<;Ojmq23o@&-GF|z<*^0xEh2`g!x6UQR}! zVCo03V80OO=Ba!)8JT`wnOq?7k>%&3*=;}xv&pjsF9KEFu>h&s+%MDt(sNn_Y7pmS zXOZJTwJf$^wJxF{wVE%%vLF*3#cqPs-wlVWcat~{vYcNMZ25sexKbCXdZ6W(HXoIi z1k(>>a+sK|EZpoTF9-C?>CJgc9zc4@<{heMf%MAF?V43U`8}JNbu5AWL!0gN?Sb@^ z&GkmIKtCVaJkNY73)7Wjn_X@G0O=!}ogFu_gZSS(rUUiu+uZNH2q=DSvvGi+GyqRs BezyPs