diff --git a/aux/broccoli b/aux/broccoli index 930e7c7822..d6e36c95e0 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 930e7c78221929849086a578308e2fdc99ac3fb8 +Subproject commit d6e36c95e0335f7cc081191c8612085bd12706f9 diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 396fd4fb79..0fd3120c34 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2159,26 +2159,6 @@ const forward_remote_state_changes = F &redef; ## Place-holder constant indicating "no peer". const PEER_ID_NONE = 0; -## Deprecated. -## -## .. todo:: The connection compressor is scheduled to be removed from Bro. -const use_connection_compressor = F &redef; - -## Deprecated. -## -## .. todo:: The connection compressor is scheduled to be removed from Bro. -const cc_handle_resets = F &redef; - -## Deprecated. -## -## .. todo:: The connection compressor is scheduled to be removed from Bro. -const cc_handle_only_syns = T &redef; - -## Deprecated. -## -## .. todo:: The connection compressor is scheduled to be removed from Bro. -const cc_instantiate_on_data = F &redef; - # Signature payload pattern types. # todo::use enum to help autodoc # todo::Still used? diff --git a/src/Anon.cc b/src/Anon.cc index 4c4146ac3e..d2a28a0e08 100644 --- a/src/Anon.cc +++ b/src/Anon.cc @@ -154,7 +154,7 @@ void AnonymizeIPAddr_A50::init() int AnonymizeIPAddr_A50::PreservePrefix(ipaddr32_t input, int num_bits) { DEBUG_MSG("%s/%d\n", - IPAddr(IPAddr::IPv4, &input, IPAddr::Network).AsString().c_str(), + IPAddr(IPv4, &input, IPAddr::Network).AsString().c_str(), num_bits); if ( ! before_anonymization ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1dd414b3ba..d9ec76f8d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -291,7 +291,6 @@ set(bro_SRCS ChunkedIO.cc CompHash.cc Conn.cc - ConnCompressor.cc ConnSizeAnalyzer.cc ContentLine.cc DCE_RPC.cc diff --git a/src/CompHash.cc b/src/CompHash.cc index ae0e082216..86677f9719 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -709,7 +709,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, const uint32* const kp = AlignType(kp0); kp1 = reinterpret_cast(kp+4); - IPAddr addr(IPAddr::IPv6, kp, IPAddr::Network); + IPAddr addr(IPv6, kp, IPAddr::Network); switch ( tag ) { case TYPE_ADDR: diff --git a/src/Conn.h b/src/Conn.h index a5ed560bde..b3eb9013d0 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -239,30 +239,6 @@ public: // Sets the transport protocol in use. void SetTransport(TransportProto arg_proto) { proto = arg_proto; } - // If the connection compressor is activated, we need a special memory - // layout for connections. (See ConnCompressor.h) - void* operator new(size_t size) - { - if ( ! use_connection_compressor ) - return ::operator new(size); - - void* c = ::operator new(size + 4); - - // We have to turn off the is_pending bit. By setting the - // first four bytes to zero, we'll achieve this. - *((uint32*) c) = 0; - - return ((char *) c) + 4; - } - - void operator delete(void* ptr) - { - if ( ! use_connection_compressor ) - ::operator delete(ptr); - else - ::operator delete(((char*) ptr) - 4); - } - void SetUID(uint64 arg_uid) { uid = arg_uid; } protected: diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc deleted file mode 100644 index 29e24457f5..0000000000 --- a/src/ConnCompressor.cc +++ /dev/null @@ -1,1042 +0,0 @@ -#include - -#include "ConnCompressor.h" -#include "Event.h" -#include "ConnSizeAnalyzer.h" -#include "net_util.h" - -// The basic model of the compressor is to wait for an answer before -// instantiating full connection state. Until we see a reply, only a minimal -// amount of state is stored. This has some consequences: -// -// - We try to mimic TCP.cc as close as possible, but this works only to a -// certain degree; e.g., we don't consider any of the wait-a-bit-after- -// the-connection-has-been-closed timers. That means we will get differences -// in connection semantics if the compressor is turned on. On the other -// hand, these differences will occur only for not well-established -// sessions, and experience shows that for these kinds of connections -// semantics are ill-defined in any case. -// -// - If an originator sends multiple different packets before we see a reply, -// we lose the information about additional packets (more precisely, we -// merge the packet headers into one). In particular, we lose any payload. -// This is a major problem if we see only one direction of a connection. -// When analyzing only SYN/FIN/RSTs this leads to differences if we miss -// the SYN/ACK. -// -// To avoid losing payload, there is the option cc_instantiate_on_data: -// if enabled and the originator sends a non-control packet after the -// initial packet, we instantiate full connection state. -// -// - We lose some of the information contained in initial packets (e.g., most -// IP/TCP options and any payload). If you depend on them, you don't -// want to use the compressor. -// -// Optionally, the compressor can take care only of initial SYNs and -// instantiate full connection state for all other connection setups. -// To enable, set cc_handle_only_syns to true. -// -// - The compressor may handle refused connections (i.e., initial packets -// followed by RST from responder) itself. Again, this leads to differences -// from default TCP processing and is therefore turned off by default. -// To enable, set cc_handle_resets to true. -// -// - We don't match signatures on connections which are completely handled -// by the compressor. Matching would require significant additional state -// w/o being very helpful. -// -// - If use_conn_size_analyzer is True, the reported counts for bytes and -// packets may not account for some packets/data that is part of those -// packets which the connection compressor handles. The error, if any, will -// however be small. - - -#ifdef DEBUG -static inline const char* fmt_conn_id(const ConnCompressor::PendingConn* c) - { - if ( c->ip1_is_src ) - return fmt_conn_id(c->key.ip1, c->key.port1, - c->key.ip2, c->key.port2); - else - return fmt_conn_id(c->key.ip2, c->key.port2, - c->key.ip1, c->key.port1); - } - -static inline const char* fmt_conn_id(const Connection* c) - { - return fmt_conn_id(c->OrigAddr(), c->OrigPort(), - c->RespAddr(), c->RespPort()); - } - -static inline const char* fmt_conn_id(const IP_Hdr* ip) - { - const struct tcphdr* tp = (const struct tcphdr*) ip->Payload(); - return fmt_conn_id(ip->SrcAddr(), tp->th_sport, - ip->DstAddr(), tp->th_dport); - } -#endif - -ConnCompressor::ConnCompressor() - { - first_block = last_block = 0; - first_non_expired = 0; - conn_val = 0; - - sizes.connections = sizes.connections_total = 0; - sizes.pending_valid = sizes.pending_total = sizes.pending_in_mem = 0; - sizes.hash_table_size = 0; - sizes.memory = 0; - } - -ConnCompressor::~ConnCompressor() - { - Block* next; - for ( Block* b = first_block; b; b = next ) - { - next = b->next; - delete b; - } - } - -Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip, - const struct pcap_pkthdr* hdr, const u_char* const pkt) - { - // Expire old stuff. - DoExpire(t); - - // Most sanity checks on header sizes are already done ... - const struct tcphdr* tp = (const struct tcphdr*) ip->Payload(); - - // ... except this one. - uint32 tcp_hdr_len = tp->th_off * 4; - if ( tcp_hdr_len > uint32(ip->TotalLen() - ip->HdrLen()) ) - { - sessions->Weird("truncated_header", hdr, pkt); - delete key; - return 0; - } - - bool external = current_iosrc->GetCurrentTag(); - ConnData* c = conns.Lookup(key); - - Unref(conn_val); - conn_val = 0; - - // Do we already have a Connection object? - if ( c && IsConnPtr(c) ) - { - Connection* conn = MakeConnPtr(c); - int consistent = 1; - - if ( external ) - { - // External, and we already have a full connection. - // That means we use the same logic as in NetSessions - // to compare the tags. - consistent = sessions->CheckConnectionTag(conn); - if ( consistent < 0 ) - { - delete key; - return 0; - } - } - - if ( ! consistent || conn->IsReuse(t, ip->Payload()) ) - { - if ( consistent ) - { - DBG_LOG(DBG_COMPRESSOR, "%s reuse", fmt_conn_id(conn)); - conn->Event(connection_reused, 0); - } - - sessions->Remove(conn); - --sizes.connections; - - return Instantiate(t, key, ip); - } - - DBG_LOG(DBG_COMPRESSOR, "%s pass through", fmt_conn_id(conn)); - delete key; - return conn; - } - - PendingConn* pending = c ? MakePendingConnPtr(c) : 0; - - if ( c && external ) - { - // External, but previous packets were not, i.e., they used - // the global timer queue. We finish the old connection - // and instantiate a full one now. - DBG_LOG(DBG_TM, "got packet with tag %s for already" - "known cc connection, instantiating full conn", - current_iosrc->GetCurrentTag()->c_str()); - - Event(pending, 0, connection_attempt, - TCP_ENDPOINT_INACTIVE, 0, TCP_ENDPOINT_INACTIVE); - Event(pending, 0, connection_state_remove, - TCP_ENDPOINT_INACTIVE, 0, TCP_ENDPOINT_INACTIVE); - Remove(key); - - return Instantiate(t, key, ip); - } - - if ( c && pending->invalid && - network_time < pending->time + tcp_session_timer ) - { - // The old connection has terminated sooner than - // tcp_session_timer. We assume this packet to be - // a latecomer, and ignore it. - DBG_LOG(DBG_COMPRESSOR, "%s ignored", fmt_conn_id(pending)); - sessions->DumpPacket(hdr, pkt); - delete key; - return 0; - } - - // Simulate tcp_{reset,close}_delay for initial FINs/RSTs - if ( c && ! pending->invalid && - ((pending->FIN && pending->time + tcp_close_delay < t ) || - (pending->RST && pending->time + tcp_reset_delay < t )) ) - { - DBG_LOG(DBG_COMPRESSOR, "%s closed", fmt_conn_id(pending)); - int orig_state = - pending->FIN ? TCP_ENDPOINT_CLOSED : TCP_ENDPOINT_RESET; - - Event(pending, 0, connection_partial_close, orig_state, - ip->PayloadLen() - (tp->th_off * 4), - TCP_ENDPOINT_INACTIVE); - Event(pending, 0, connection_state_remove, orig_state, - ip->PayloadLen() - (tp->th_off * 4), - TCP_ENDPOINT_INACTIVE); - - Remove(key); - - Connection* tc = FirstFromOrig(t, key, ip, tp); - if ( ! tc ) - { - delete key; - sessions->DumpPacket(hdr, pkt); - } - - return tc; - } - - Connection* tc; - - if ( ! c || pending->invalid ) - { - // First packet of a connection. - if ( c ) - Remove(key); - - if ( external ) - // External, we directly instantiate a full connection. - tc = Instantiate(t, key, ip); - else - tc = FirstFromOrig(t, key, ip, tp); - } - - else if ( ip->SrcAddr() == - IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network) && - tp->th_sport == SrcPort(pending) ) - // Another packet from originator. - tc = NextFromOrig(pending, t, key, ip, tp); - - else - // A reply. - tc = Response(pending, t, key, ip, tp); - - if ( ! tc ) - { - delete key; - sessions->DumpPacket(hdr, pkt); - } - - return tc; - } - -static int parse_tcp_options(unsigned int opt, unsigned int optlen, - const u_char* option, TCP_Analyzer* analyzer, - bool is_orig, void* cookie) - { - ConnCompressor::PendingConn* c = (ConnCompressor::PendingConn*) cookie; - - // We're only interested in window_scale. - if ( opt == 3 ) - c->window_scale = option[2]; - - return 0; - } - -Connection* ConnCompressor::FirstFromOrig(double t, HashKey* key, - const IP_Hdr* ip, const tcphdr* tp) - { - if ( cc_handle_only_syns && ! (tp->th_flags & TH_SYN) ) - return Instantiate(t, key, ip); - - // The first packet of a connection. - PendingConn* pending = MakeNewState(t); - PktHdrToPendingConn(t, key, ip, tp, pending); - - DBG_LOG(DBG_COMPRESSOR, "%s our", fmt_conn_id(pending)); - - // The created DictEntry will point directly into our PendingConn. - // So, we have to be careful when we delete it. - conns.Dictionary::Insert(&pending->key, sizeof(pending->key), - pending->hash, MakeMapPtr(pending), 0); - - // Mimic some of TCP_Analyzer's weirds for SYNs. - // To be completely precise, we'd need to check this at a few - // more locations in NextFromOrig() and Reply(). However, that - // does not really seem worth it, as this is the standard case. - if ( tp->th_flags & TH_SYN ) - { - if ( tp->th_flags & TH_RST ) - Weird(pending, t, "TCP_christmas"); - - if ( tp->th_flags & TH_URG ) - Weird(pending, t, "baroque_SYN"); - - int len = ip->TotalLen() - ip->HdrLen() - tp->th_off * 4; - - if ( len > 0 ) - // T/TCP definitely complicates this. - Weird(pending, t, "SYN_with_data"); - } - - if ( tp->th_flags & TH_FIN ) - { - if ( ! (tp->th_flags & TH_SYN) ) - Weird(pending, t, "spontaneous_FIN"); - } - - if ( tp->th_flags & TH_RST ) - { - if ( ! (tp->th_flags & TH_SYN) ) - Weird(pending, t, "spontaneous_RST"); - } - - ++sizes.pending_valid; - ++sizes.pending_total; - ++sizes.pending_in_mem; - - Event(pending, 0, new_connection, - TCP_ENDPOINT_INACTIVE, 0, TCP_ENDPOINT_INACTIVE); - - if ( current_iosrc->GetCurrentTag() ) - { - Val* tag = - new StringVal(current_iosrc->GetCurrentTag()->c_str()); - Event(pending, 0, connection_external, - TCP_ENDPOINT_INACTIVE, 0, TCP_ENDPOINT_INACTIVE, tag); - } - - return 0; - } - -Connection* ConnCompressor::NextFromOrig(PendingConn* pending, double t, - HashKey* key, const IP_Hdr* ip, - const tcphdr* tp) - { - // Another packet from the same host without seeing an answer so far. - DBG_LOG(DBG_COMPRESSOR, "%s same again", fmt_conn_id(pending)); - - ++pending->num_pkts; - ++pending->num_bytes_ip += ip->PayloadLen(); - - // New window scale overrides old - not great, this is a (subtle) - // evasion opportunity. - if ( TCP_Analyzer::ParseTCPOptions(tp, parse_tcp_options, 0, 0, - pending) < 0 ) - Weird(pending, t, "corrupt_tcp_options"); - - if ( tp->th_flags & TH_SYN ) - // New seq overrides old. - pending->seq = tp->th_seq; - - // Mimic TCP_Endpoint::Size() - int size = ntohl(tp->th_seq) - ntohl(pending->seq); - if ( size != 0 ) - --size; - - if ( size != 0 && (pending->FIN || (tp->th_flags & TH_FIN)) ) - --size; - - if ( size < 0 ) - // We only care about the size for broken connections. - // Surely for those it's more likely that the sequence - // numbers are confused than that they really transferred - // > 2 GB of data. Plus, for 64-bit ints these sign-extend - // up to truly huge, non-sensical unsigned values. - size = 0; - - if ( pending->SYN ) - { - // We're in state SYN_SENT or SYN_ACK_SENT. - if ( tp->th_flags & TH_RST) - { - Event(pending, t, connection_reset, - TCP_ENDPOINT_RESET, size, TCP_ENDPOINT_INACTIVE); - Event(pending, t, connection_state_remove, - TCP_ENDPOINT_RESET, size, TCP_ENDPOINT_INACTIVE); - - Invalidate(key); - return 0; - } - - else if ( tp->th_flags & TH_FIN) - { - Event(pending, t, connection_partial_close, - TCP_ENDPOINT_CLOSED, size, TCP_ENDPOINT_INACTIVE); - Event(pending, t, connection_state_remove, - TCP_ENDPOINT_CLOSED, size, TCP_ENDPOINT_INACTIVE); - Invalidate(key); - return 0; - } - - else if ( tp->th_flags & TH_SYN ) - { - if ( (tp->th_flags & TH_ACK) && ! pending->ACK ) - Weird(pending, t, "repeated_SYN_with_ack"); - } - - else - { - // A data packet without seeing a SYN/ACK first. As - // long as we stick with the principle of instantiating - // state only when we see a reply, we have to throw - // this data away. Optionally we may instantiate a - // real connection now. - - if ( cc_instantiate_on_data ) - return Instantiate(key, pending); - // else - // Weird(pending, t, "data_without_SYN_ACK"); - } - } - - else - { // We're in state INACTIVE. - if ( tp->th_flags & TH_RST) - { - Event(pending, t, connection_reset, - TCP_ENDPOINT_RESET, size, TCP_ENDPOINT_INACTIVE); - Event(pending, t, connection_state_remove, - TCP_ENDPOINT_RESET, size, TCP_ENDPOINT_INACTIVE); - - Invalidate(key); - return 0; - } - - else if ( tp->th_flags & TH_FIN) - { - Event(pending, t, connection_half_finished, - TCP_ENDPOINT_CLOSED, size, TCP_ENDPOINT_INACTIVE); - Event(pending, t, connection_state_remove, - TCP_ENDPOINT_CLOSED, size, TCP_ENDPOINT_INACTIVE); - - Invalidate(key); - return 0; - } - - else if ( tp->th_flags & TH_SYN ) - { - if ( ! (tp->th_flags & TH_ACK) ) - { - Weird(pending, t, "SYN_after_partial"); - pending->SYN = 1; - } - } - - else - // Another data packet. See discussion above. - if ( cc_instantiate_on_data ) - return Instantiate(key, pending); - - // else - // Weird(pending, t, "data_without_SYN_ACK"); - } - - return 0; - } - -Connection* ConnCompressor::Response(PendingConn* pending, double t, - HashKey* key, const IP_Hdr* ip, - const tcphdr* tp) - { - // The packet comes from the former responder. That means we are - // seeing a reply, so we are going to create a "real" connection now. - DBG_LOG(DBG_COMPRESSOR, "%s response", fmt_conn_id(pending)); - - // Optional: if it's a RST after SYN, we directly generate a - // connection_rejected and throw the state away. - if ( cc_handle_resets && (tp->th_flags & TH_RST) && pending->SYN ) - { - // See discussion of size in DoExpire(). - DBG_LOG(DBG_COMPRESSOR, "%s reset", fmt_conn_id(pending)); - - Event(pending, t, connection_reset, - TCP_ENDPOINT_SYN_SENT, 0, TCP_ENDPOINT_RESET); - Event(pending, t, connection_state_remove, - TCP_ENDPOINT_SYN_SENT, 0, TCP_ENDPOINT_RESET); - - Invalidate(key); - return 0; - } - - // If a connection's initial packet is a RST, Bro's standard TCP - // processing considers the connection done right away. We simulate - // this by instantiating a second connection in this case. The - // first one will time out eventually. - if ( pending->RST && ! pending->SYN ) - { - int orig_state = - pending->RST ? TCP_ENDPOINT_RESET : TCP_ENDPOINT_CLOSED; - Event(pending, 0, connection_attempt, - orig_state, 0, TCP_ENDPOINT_INACTIVE); - Event(pending, 0, connection_state_remove, - orig_state, 0, TCP_ENDPOINT_INACTIVE); - - // Override with current packet. - PktHdrToPendingConn(t, key, ip, tp, pending); - return 0; - } - - return Instantiate(key, pending); - } - -Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending) - { - // Instantantiate a Connection. - ConnID conn_id; - conn_id.src_addr = IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network); - conn_id.dst_addr = IPAddr(IPAddr::IPv6, DstAddr(pending), IPAddr::Network); - conn_id.src_port = SrcPort(pending); - conn_id.dst_port = DstPort(pending); - - pending->invalid = 1; - --sizes.pending_valid; - --sizes.pending_total; - - // Fake the first packet. - const IP_Hdr* faked_pkt = PendingConnToPacket(pending); - Connection* new_conn = sessions->NewConn(key, pending->time, &conn_id, - faked_pkt->Payload(), IPPROTO_TCP); - - if ( ! new_conn ) - { - // This connection is not to be analyzed (e.g., it may be - // a partial one). - DBG_LOG(DBG_COMPRESSOR, "%s nop", fmt_conn_id(pending)); - return 0; - } - - new_conn->SetUID(pending->uid); - - DBG_LOG(DBG_COMPRESSOR, "%s instantiated", fmt_conn_id(pending)); - - ++sizes.connections; - ++sizes.connections_total; - - if ( new_packet ) - new_conn->Event(new_packet, 0, - sessions->BuildHeader(faked_pkt->IP4_Hdr())); - - // NewConn() may have swapped originator and responder. - int is_orig = conn_id.src_addr == new_conn->OrigAddr() && - conn_id.src_port == new_conn->OrigPort(); - - // Pass the faked packet to the connection. - const u_char* payload = faked_pkt->Payload(); - - int dummy_record_packet, dummy_record_content; - new_conn->NextPacket(pending->time, is_orig, - faked_pkt, faked_pkt->PayloadLen(), - faked_pkt->PayloadLen(), payload, - dummy_record_packet, dummy_record_content, 0, 0, 0); - - // Removing necessary because the key will be destroyed at some point. - conns.Remove(&pending->key, sizeof(pending->key), pending->hash, true); - conns.Insert(key, MakeMapPtr(new_conn)); - - return new_conn; - } - -Connection* ConnCompressor::Instantiate(double t, HashKey* key, - const IP_Hdr* ip) - { - const struct tcphdr* tp = (const struct tcphdr*) ip->Payload(); - - ConnID conn_id; - conn_id.src_addr = ip->SrcAddr(); - conn_id.dst_addr = ip->DstAddr(); - conn_id.src_port = tp->th_sport; - conn_id.dst_port = tp->th_dport; - - Connection* new_conn = - sessions->NewConn(key, t, &conn_id, ip->Payload(), IPPROTO_TCP); - - if ( ! new_conn ) - { - // This connection is not to be analyzed (e.g., it may be - // a partial one). - DBG_LOG(DBG_COMPRESSOR, "%s nop", fmt_conn_id(ip)); - return 0; - } - - DBG_LOG(DBG_COMPRESSOR, "%s instantiated", fmt_conn_id(ip)); - - conns.Insert(key, MakeMapPtr(new_conn)); - ++sizes.connections; - ++sizes.connections_total; - - if ( new_connection ) - new_conn->Event(new_connection, 0); - - if ( current_iosrc->GetCurrentTag() ) - { - Val* tag = - new StringVal(current_iosrc->GetCurrentTag()->c_str()); - new_conn->Event(connection_external, 0, tag); - } - - return new_conn; - } - -void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key, - const IP_Hdr* ip, const struct tcphdr* tp, PendingConn* c) - { - memcpy(&c->key, key->Key(), key->Size()); - - c->hash = key->Hash(); - IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network); - c->ip1_is_src = ip1 == ip->SrcAddr() && - c->key.port1 == tp->th_sport; - c->time = time; - c->window = tp->th_win; - c->seq = tp->th_seq; - c->ack = tp->th_ack; - c->window_scale = 0; - c->SYN = (tp->th_flags & TH_SYN) != 0; - c->FIN = (tp->th_flags & TH_FIN) != 0; - c->RST = (tp->th_flags & TH_RST) != 0; - c->ACK = (tp->th_flags & TH_ACK) != 0; - c->uid = calculate_unique_id(); - c->num_bytes_ip = ip->TotalLen(); - c->num_pkts = 1; - c->invalid = 0; - - if ( TCP_Analyzer::ParseTCPOptions(tp, parse_tcp_options, 0, 0, c) < 0 ) - sessions->Weird("corrupt_tcp_options", ip); - } - -// Fakes an empty TCP packet based on the information in PendingConn. -const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c) - { - static ip* ip = 0; - static tcphdr* tp = 0; - static IP_Hdr* ip_hdr = 0; - - if ( ! ip ) - { // Initialize. ### Note, only handles IPv4 for now. - int packet_length = sizeof(*ip) + sizeof(*tp); - ip = (struct ip*) new char[packet_length]; - tp = (struct tcphdr*) (((char*) ip) + sizeof(*ip)); - ip_hdr = new IP_Hdr(ip); - - // Constant fields. - ip->ip_v = 4; - ip->ip_hl = sizeof(*ip) / 4; // no options - ip->ip_tos = 0; - ip->ip_len = htons(packet_length); - ip->ip_id = 0; - ip->ip_off = 0; - ip->ip_ttl = 255; - ip->ip_p = IPPROTO_TCP; - ip->ip_sum = 0; // is not going to be checked - - tp->th_off = sizeof(*tp) / 4; // no options for now - tp->th_urp = 0; - } - - IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network); - IPAddr ip2(IPAddr::IPv6, c->key.ip2, IPAddr::Network); - if ( ip1.GetFamily() == IPAddr::IPv6 || - ip2.GetFamily() == IPAddr::IPv6 ) - reporter->InternalError("IPv6 snuck into connection compressor"); - else - { - ip1.CopyIPv4(c->ip1_is_src ? &ip->ip_src : &ip->ip_dst); - ip2.CopyIPv4(c->ip1_is_src ? &ip->ip_dst : &ip->ip_dst); - } - - if ( c->ip1_is_src ) - { - tp->th_sport = c->key.port1; - tp->th_dport = c->key.port2; - } - else - { - tp->th_sport = c->key.port2; - tp->th_dport = c->key.port1; - } - - tp->th_win = c->window; - tp->th_seq = c->seq; - tp->th_ack = c->ack; - tp->th_flags = MakeFlags(c); - tp->th_sum = 0; - tp->th_sum = 0xffff - tcp_checksum(ip, tp, 0); - - // FIXME: Add TCP options. - return ip_hdr; - } - -uint8 ConnCompressor::MakeFlags(const PendingConn* c) const - { - uint8 tcp_flags = 0; - if ( c->SYN ) - tcp_flags |= TH_SYN; - if ( c->FIN ) - tcp_flags |= TH_FIN; - if ( c->RST ) - tcp_flags |= TH_RST; - if ( c->ACK ) - tcp_flags |= TH_ACK; - - return tcp_flags; - } - -ConnCompressor::PendingConn* ConnCompressor::MakeNewState(double t) - { - // See if there is enough space in the current block. - if ( last_block && - int(sizeof(PendingConn)) <= BLOCK_SIZE - last_block->bytes_used ) - { - PendingConn* c = (PendingConn*) &last_block->data[last_block->bytes_used]; - last_block->bytes_used += sizeof(PendingConn); - c->is_pending = true; - return c; - } - - // Get new block. - Block* b = new Block; - b->time = t; - b->bytes_used = sizeof(PendingConn); - b->next = 0; - b->prev = last_block; - - if ( last_block ) - last_block->next = b; - else - first_block = b; - - last_block = b; - - sizes.memory += padded_sizeof(*b); - PendingConn* c = (PendingConn*) &b->data; - c->is_pending = true; - return c; - } - -void ConnCompressor::DoExpire(double t) - { - while ( first_block ) - { - Block* b = first_block; - - unsigned char* p = - first_non_expired ? first_non_expired : b->data; - - while ( p < b->data + b->bytes_used ) - { - Unref(conn_val); - conn_val = 0; - - PendingConn* c = (PendingConn*) p; - if ( t && (c->time + tcp_SYN_timeout > t) ) - { - // All following entries are still - // recent enough. - first_non_expired = p; - return; - } - - if ( ! c->invalid ) - { - // Expired. - DBG_LOG(DBG_COMPRESSOR, "%s expire", fmt_conn_id(c)); - - HashKey key(&c->key, sizeof(c->key), c->hash, true); - - ConnData* cd = conns.Lookup(&key); - if ( cd && ! IsConnPtr(cd) ) - conns.Remove(&c->key, sizeof(c->key), - c->hash, true); - - int orig_state = TCP_ENDPOINT_INACTIVE; - - if ( c->FIN ) - orig_state = TCP_ENDPOINT_CLOSED; - if ( c->RST ) - orig_state = TCP_ENDPOINT_RESET; - if ( c->SYN ) - orig_state = TCP_ENDPOINT_SYN_SENT; - - // We're not able to get the correct size - // here (with "correct" meaning value that - // standard connection processing reports). - // We could if would also store last_seq, but - // doesn't seem worth it. - - Event(c, 0, connection_attempt, - orig_state, 0, TCP_ENDPOINT_INACTIVE); - Event(c, 0, connection_state_remove, - orig_state, 0, TCP_ENDPOINT_INACTIVE); - - c->invalid = 1; - --sizes.pending_valid; - } - - p += sizeof(PendingConn); - --sizes.pending_in_mem; - } - - // Full block expired, so delete it. - first_block = b->next; - - if ( b->next ) - b->next->prev = 0; - else - last_block = 0; - - delete b; - - first_non_expired = 0; - sizes.memory -= padded_sizeof(*b); - } - } - -void ConnCompressor::Event(const PendingConn* pending, double t, - const EventHandlerPtr& event, int orig_state, - int orig_size, int resp_state, Val* arg) - { - if ( ! conn_val ) - { - if ( ! event ) - return; - - // We only raise events if NewConn() would have actually - // instantiated the Connection. - bool flip_roles; - if ( ! sessions->WantConnection(ntohs(SrcPort(pending)), - ntohs(DstPort(pending)), - TRANSPORT_TCP, - MakeFlags(pending), - flip_roles) ) - return; - - conn_val = new RecordVal(connection_type); - RecordVal* id_val = new RecordVal(conn_id); - RecordVal* orig_endp = new RecordVal(endpoint); - RecordVal* resp_endp = new RecordVal(endpoint); - - if ( orig_state == TCP_ENDPOINT_INACTIVE ) - { - if ( pending->SYN ) - orig_state = pending->ACK ? - TCP_ENDPOINT_SYN_ACK_SENT : - TCP_ENDPOINT_SYN_SENT; - else - orig_state = TCP_ENDPOINT_PARTIAL; - } - - int tcp_state = TCP_ENDPOINT_INACTIVE; - - if ( ! flip_roles ) - { - id_val->Assign(0, new AddrVal(SrcAddr(pending))); - id_val->Assign(1, new PortVal(ntohs(SrcPort(pending)), - TRANSPORT_TCP)); - id_val->Assign(2, new AddrVal(DstAddr(pending))); - id_val->Assign(3, new PortVal(ntohs(DstPort(pending)), - TRANSPORT_TCP)); - orig_endp->Assign(0, new Val(orig_size, TYPE_COUNT)); - orig_endp->Assign(1, new Val(orig_state, TYPE_COUNT)); - - if ( ConnSize_Analyzer::Available() ) - { - // Fill in optional fields if ConnSize_Analyzer is on. - orig_endp->Assign(2, new Val(pending->num_pkts, TYPE_COUNT)); - orig_endp->Assign(3, new Val(pending->num_bytes_ip, TYPE_COUNT)); - } - - resp_endp->Assign(0, new Val(0, TYPE_COUNT)); - resp_endp->Assign(1, new Val(resp_state, TYPE_COUNT)); - resp_endp->Assign(2, new Val(0, TYPE_COUNT)); - resp_endp->Assign(3, new Val(0, TYPE_COUNT)); - } - else - { - id_val->Assign(0, new AddrVal(DstAddr(pending))); - id_val->Assign(1, new PortVal(ntohs(DstPort(pending)), - TRANSPORT_TCP)); - id_val->Assign(2, new AddrVal(SrcAddr(pending))); - id_val->Assign(3, new PortVal(ntohs(SrcPort(pending)), - TRANSPORT_TCP)); - - orig_endp->Assign(0, new Val(0, TYPE_COUNT)); - orig_endp->Assign(1, new Val(resp_state, TYPE_COUNT)); - orig_endp->Assign(2, new Val(0, TYPE_COUNT)); - orig_endp->Assign(3, new Val(0, TYPE_COUNT)); - - resp_endp->Assign(0, new Val(orig_size, TYPE_COUNT)); - resp_endp->Assign(1, new Val(orig_state, TYPE_COUNT)); - - if ( ConnSize_Analyzer::Available() ) - { - // Fill in optional fields if ConnSize_Analyzer is on - resp_endp->Assign(2, new Val(pending->num_pkts, TYPE_COUNT)); - resp_endp->Assign(3, new Val(pending->num_bytes_ip, TYPE_COUNT)); - } - - DBG_LOG(DBG_COMPRESSOR, "%s swapped direction", fmt_conn_id(pending)); - } - - conn_val->Assign(0, id_val); - conn_val->Assign(1, orig_endp); - conn_val->Assign(2, resp_endp); - conn_val->Assign(3, new Val(pending->time, TYPE_TIME)); - conn_val->Assign(4, new Val(t > 0 ? t - pending->time : 0, - TYPE_INTERVAL)); // duration - conn_val->Assign(5, new TableVal(string_set)); // service - conn_val->Assign(6, new StringVal("cc=1")); // addl - conn_val->Assign(7, new Val(0, TYPE_COUNT)); // hot - conn_val->Assign(8, new StringVal("")); // history - - char tmp[20]; // uid. - conn_val->Assign(9, new StringVal(uitoa_n(pending->uid, tmp, sizeof(tmp), 62))); - - conn_val->SetOrigin(0); - } - - if ( event == conn_weird ) - { - // Special case to go through the logger. - const char* msg = arg->AsString()->CheckString(); - reporter->Weird(conn_val->Ref(), msg); - return; - } - - val_list* vl = new val_list; - if ( arg ) - vl->append(arg); - vl->append(conn_val->Ref()); - - mgr.QueueEvent(event, vl, SOURCE_LOCAL); - } - -void ConnCompressor::Drain() - { - IterCookie* cookie = conns.InitForIteration(); - ConnData* c; - - DoExpire(0); - - while ( (c = conns.NextEntry(cookie)) ) - { - Unref(conn_val); - conn_val = 0; - - if ( IsConnPtr(c) ) - { - Connection* tc = MakeConnPtr(c); - tc->Done(); - tc->Event(connection_state_remove, 0); - Unref(tc); - --sizes.connections; - } - - else - { - PendingConn* pc = MakePendingConnPtr(c); - if ( ! pc->invalid ) - { - // Same discussion for size here than - // in DoExpire(). - Event(pc, 0, connection_attempt, - TCP_ENDPOINT_INACTIVE, 0, - TCP_ENDPOINT_INACTIVE); - Event(pc, 0, connection_state_remove, - TCP_ENDPOINT_INACTIVE, 0, - TCP_ENDPOINT_INACTIVE); - - --sizes.pending_valid; - pc->invalid = 1; - } - } - } - } - -void ConnCompressor::Invalidate(HashKey* k) - { - ConnData* c = (ConnData*) conns.Lookup(k); - - assert(c && ! IsConnPtr(c)); - PendingConn* pc = MakePendingConnPtr(c); - - DBG_LOG(DBG_COMPRESSOR, "%s invalidate", fmt_conn_id(pc)); - - if ( ! pc->invalid ) - { - conns.Remove(&pc->key, sizeof(pc->key), pc->hash, true); - pc->invalid = 1; - --sizes.pending_valid; - } - } - -Connection* ConnCompressor::Insert(Connection* newconn) - { - HashKey* key = newconn->Key(); - ConnData* c = conns.Lookup(key); - Connection* old = 0; - - // Do we already have a Connection object? - if ( c ) - { - if ( IsConnPtr(c) ) - old = MakeConnPtr(c); - Remove(key); - } - - conns.Insert(key, MakeMapPtr(newconn)); - return old; - } - -bool ConnCompressor::Remove(HashKey* k) - { - ConnData* c = (ConnData*) conns.Lookup(k); - if ( ! c ) - return false; - - if ( IsConnPtr(c) ) - { - DBG_LOG(DBG_COMPRESSOR, "%s remove", fmt_conn_id(MakeConnPtr(c))); - conns.Remove(k); - --sizes.connections; - } - else - { - PendingConn* pc = MakePendingConnPtr(c); - DBG_LOG(DBG_COMPRESSOR, "%s remove", fmt_conn_id(pc)); - - conns.Remove(&pc->key, sizeof(pc->key), pc->hash, true); - - if ( ! pc->invalid ) - { - pc->invalid = 1; - --sizes.pending_valid; - } - } - - return true; - } diff --git a/src/ConnCompressor.h b/src/ConnCompressor.h deleted file mode 100644 index 96be7faff3..0000000000 --- a/src/ConnCompressor.h +++ /dev/null @@ -1,240 +0,0 @@ -// The ConnCompressor keeps track of the first packet seen for a conn_id using -// only a minimal amount of memory. This helps us to avoid instantiating -// full Connection objects for never-established sessions. -// -// TCP only. - -#ifndef CONNCOMPRESSOR_H -#define CONNCOMPRESSOR_H - -#include "Conn.h" -#include "Dict.h" -#include "NetVar.h" -#include "TCP.h" - -class ConnCompressor { -public: - ConnCompressor(); - ~ConnCompressor(); - - // Handle next packet. Returns 0 if packet in handled internally. - // Takes ownership of key. - Connection* NextPacket(double t, HashKey* k, const IP_Hdr* ip_hdr, - const struct pcap_pkthdr* hdr, const u_char* const pkt); - - // Look up a connection. Returns non-nil for connections for - // which a Connection object has already been instantiated. - Connection* Lookup(HashKey* k) - { - ConnData* c = conns.Lookup(k); - return c && IsConnPtr(c) ? MakeConnPtr(c) : 0; - } - - // Inserts connection into compressor. If another entry with this key - // already exists, it's replaced. If that was a full connection, it is - // also returned. - Connection* Insert(Connection* c); - - // Remove all state belonging to the given connection. Returns - // true if the connection was found in the compressor's table, - // false if not. - bool Remove(HashKey* k); - - // Flush state. - void Drain(); - - struct Sizes { - // Current number of already fully instantiated connections. - unsigned int connections; - - // Total number of fully instantiated connections. - unsigned int connections_total; - - // Current number of seen but non-yet instantiated connections. - unsigned int pending_valid; - - // Total number of seen but non-yet instantiated connections. - unsigned int pending_total; - - // Total number of all entries in pending list (some a which - // may already been invalid, but not yet removed from memory). - unsigned int pending_in_mem; - - // Total number of hash table entires - // (should equal connections + pending_valid) - unsigned int hash_table_size; - - // Total memory usage; - unsigned int memory; - }; - - const Sizes& Size() - { sizes.hash_table_size = conns.Length(); return sizes; } - - unsigned int MemoryAllocation() const { return sizes.memory; } - - // As long as we have only seen packets from one side, we just - // store a PendingConn. - struct PendingConn { - // True if the block is indeed a PendingConn (see below). - unsigned int is_pending:1; - - // Whether roles in key are flipped. - unsigned int ip1_is_src:1; - - unsigned int invalid:1; // deleted - int window_scale:4; - unsigned int SYN:1; - unsigned int FIN:1; - unsigned int RST:1; - unsigned int ACK:1; - - double time; - struct Key { - uint32 ip1[4]; - uint32 ip2[4]; - uint16 port1; - uint16 port2; - } key; - uint32 seq; - uint32 ack; - hash_t hash; - uint16 window; - uint64 uid; - - // The following are set if use_conn_size_analyzer is T. - uint16 num_pkts; - uint16 num_bytes_ip; - }; - -private: - // Helpers to extract addrs/ports from PendingConn. - - const uint32* SrcAddr(const PendingConn* c) - { return c->ip1_is_src ? c->key.ip1 : c->key.ip2; } - const uint32* DstAddr(const PendingConn* c) - { return c->ip1_is_src ? c->key.ip2 : c->key.ip1; } - - uint16 SrcPort(const PendingConn* c) - { return c->ip1_is_src ? c->key.port1 : c->key.port2; } - uint16 DstPort(const PendingConn* c) - { return c->ip1_is_src ? c->key.port2 : c->key.port1; } - - - // Called for the first packet in a connection. - Connection* FirstFromOrig(double t, HashKey* key, - const IP_Hdr* ip, const tcphdr* tp); - - // Called for more packets from the orginator w/o seeing a response. - Connection* NextFromOrig(PendingConn* pending, double t, HashKey* key, - const IP_Hdr* ip, const tcphdr* tp); - - // Called for the first response packet. Instantiates a Connection. - Connection* Response(PendingConn* pending, double t, HashKey* key, - const IP_Hdr* ip, const tcphdr* tp); - - // Instantiates a full TCP connection (invalidates pending connection). - Connection* Instantiate(HashKey* key, PendingConn* pending); - - // Same but based on packet. - Connection* Instantiate(double t, HashKey* key, const IP_Hdr* ip); - - // Fills the attributes of a PendingConn based on the given arguments. - void PktHdrToPendingConn(double time, const HashKey* key, - const IP_Hdr* ip, const struct tcphdr* tp, PendingConn* c); - - // Fakes a TCP packet based on the available information. - const IP_Hdr* PendingConnToPacket(const PendingConn* c); - - // Construct a TCP-flags byte. - uint8 MakeFlags(const PendingConn* c) const; - - // Allocate room for a new (Ext)PendingConn. - PendingConn* MakeNewState(double t); - - // Expire PendingConns. - void DoExpire(double t); - - // Remove all state belonging to the given connection. - void Invalidate(HashKey* k); - - // Sends the given connection_* event. If orig_state is - // TCP_ENDPOINT__INACTIVE, tries to guess a better one based - // on pending. If arg in non-nil, it will be used as the - // *first* argument of the event call (this is for conn_weird()). - void Event(const PendingConn* pending, double t, - const EventHandlerPtr& event, int orig_state, - int orig_size, int resp_state, Val* arg = 0); - - void Weird(const PendingConn* pending, double t, const char* msg) - { - // This will actually go through the Reporter; Event() takes - // care of that. - Event(pending, t, conn_weird, TCP_ENDPOINT_INACTIVE, 0, - TCP_ENDPOINT_INACTIVE, new StringVal(msg)); - } - - static const int BLOCK_SIZE = 16 * 1024; - - // The memory managment for PendConns. - struct Block { - double time; - Block* prev; - Block* next; - int bytes_used; - unsigned char data[BLOCK_SIZE]; - }; - - // In the connection hash table, we store pointers to both PendingConns - // and Connections. Thus, we need a way to differentiate between - // these two types. To avoid an additional indirection, we use a little - // hack: a pointer retrieved from the table is interpreted as a - // PendingConn first. However, if is_pending is false, it's in fact a - // Connection which starts at offset 4. The methods below help to - // implement this scheme transparently. An "operator new" in - // Connection takes care of building Connection's accordingly. - typedef PendingConn ConnData; - declare(PDict, ConnData); - typedef PDict(ConnData) ConnMap; - ConnMap conns; - - static ConnData* MakeMapPtr(PendingConn* c) - { assert(c->is_pending); return c; } - - static ConnData* MakeMapPtr(Connection* c) - { - ConnData* p = (ConnData*) (((char*) c) - 4); - assert(!p->is_pending); - return p; - } - - static PendingConn* MakePendingConnPtr(ConnData* c) - { assert(c->is_pending); return c; } - - static Connection* MakeConnPtr(ConnData* c) - { - assert(!c->is_pending); - return (Connection*) (((char*) c) + 4); - } - - static bool IsConnPtr(ConnData* c) - { return ! c->is_pending; } - - // New blocks are inserted at the end. - Block* first_block; - Block* last_block; - - // If we have already expired some entries in a block, - // this points to the first non-expired. - unsigned char* first_non_expired; - - // Last "connection" that we have build. - RecordVal* conn_val; - - // Statistics. - Sizes sizes; - }; - -extern ConnCompressor* conn_compressor; - -#endif diff --git a/src/DCE_RPC.cc b/src/DCE_RPC.cc index 88cdb48e80..21cb3be9a0 100644 --- a/src/DCE_RPC.cc +++ b/src/DCE_RPC.cc @@ -137,7 +137,7 @@ static bool is_mapped_dce_rpc_endpoint(const dce_rpc_endpoint_addr& addr) bool is_mapped_dce_rpc_endpoint(const ConnID* id, TransportProto proto) { - if ( id->dst_addr.GetFamily() == IPAddr::IPv6 ) + if ( id->dst_addr.GetFamily() == IPv6 ) // TODO: Does the protocol support v6 addresses? #773 return false; @@ -414,7 +414,7 @@ void DCE_RPC_Session::DeliverEpmapperMapResponse( case binpac::DCE_RPC_Simple::EPM_PROTOCOL_IP: uint32 hostip = floor->rhs()->data()->ip(); - mapped.addr.addr = IPAddr(IPAddr::IPv4, &hostip, IPAddr::Host); + mapped.addr.addr = IPAddr(IPv4, &hostip, IPAddr::Host); break; } } diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index a80de42704..9e65d3c9a9 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -321,10 +321,10 @@ void DNS_Mapping::Init(struct hostent* h) addrs = new IPAddr[num_addrs]; for ( int i = 0; i < num_addrs; ++i ) if ( h->h_addrtype == AF_INET ) - addrs[i] = IPAddr(IPAddr::IPv4, (uint32*)h->h_addr_list[i], + addrs[i] = IPAddr(IPv4, (uint32*)h->h_addr_list[i], IPAddr::Network); else if ( h->h_addrtype == AF_INET6 ) - addrs[i] = IPAddr(IPAddr::IPv6, (uint32*)h->h_addr_list[i], + addrs[i] = IPAddr(IPv6, (uint32*)h->h_addr_list[i], IPAddr::Network); } else diff --git a/src/Desc.cc b/src/Desc.cc index 12b4a524eb..9d94321427 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -157,6 +157,16 @@ void ODesc::Add(double d) } } +void ODesc::Add(const IPAddr& addr) + { + Add(addr.AsString()); + } + +void ODesc::Add(const IPPrefix& prefix) + { + Add(prefix.AsString()); + } + void ODesc::AddCS(const char* s) { int n = strlen(s); diff --git a/src/Desc.h b/src/Desc.h index 9f8d7ab109..9c60c68106 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -8,7 +8,6 @@ #include #include "BroString.h" -#include "IPAddr.h" typedef enum { DESC_READABLE, @@ -23,6 +22,8 @@ typedef enum { } desc_style; class BroFile; +class IPAddr; +class IPPrefix; class ODesc { public: @@ -76,8 +77,8 @@ public: void Add(int64 i); void Add(uint64 u); void Add(double d); - void Add(const IPAddr& addr) { Add(addr.AsString()); } - void Add(const IPPrefix& prefix) { Add(prefix.AsString()); } + void Add(const IPAddr& addr); + void Add(const IPPrefix& prefix); // Add s as a counted string. void AddCS(const char* s); diff --git a/src/Frag.cc b/src/Frag.cc index b72fac4b16..21abc324f8 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -125,7 +125,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt, void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) { - IP_Hdr proto_h((const struct ip*) proto_hdr); + IP_Hdr proto_h(proto_hdr, false); if ( memcmp((const void*) b1, (const void*) b2, n) ) s->Weird("fragment_inconsistency", &proto_h); @@ -157,7 +157,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) // can happen for benign reasons when we're // intermingling parts of two fragmented packets. - IP_Hdr proto_h((const struct ip*) proto_hdr); + IP_Hdr proto_h(proto_hdr, false); s->Weird("fragment_size_inconsistency", &proto_h); // We decide to analyze the contiguous portion now. @@ -171,7 +171,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) else if ( last_block->upper > frag_size ) { - IP_Hdr proto_h((const struct ip*) proto_hdr); + IP_Hdr proto_h(proto_hdr, false); s->Weird("fragment_size_inconsistency", &proto_h); frag_size = last_block->upper; } @@ -214,7 +214,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) } delete reassembled_pkt; - reassembled_pkt = new IP_Hdr(reassem4); + reassembled_pkt = new IP_Hdr(reassem4, true); DeleteTimer(); } diff --git a/src/IP.h b/src/IP.h index ba37fb4c69..36e8634912 100644 --- a/src/IP.h +++ b/src/IP.h @@ -9,23 +9,13 @@ class IP_Hdr { public: - IP_Hdr(struct ip* arg_ip4) - : ip4(arg_ip4), ip6(0), del(1) + IP_Hdr(const struct ip* arg_ip4, bool arg_del) + : ip4(arg_ip4), ip6(0), del(arg_del) { } - IP_Hdr(const struct ip* arg_ip4) - : ip4(arg_ip4), ip6(0), del(0) - { - } - - IP_Hdr(struct ip6_hdr* arg_ip6) - : ip4(0), ip6(arg_ip6), del(1) - { - } - - IP_Hdr(const struct ip6_hdr* arg_ip6) - : ip4(0), ip6(arg_ip6), del(0) + IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del) + : ip4(0), ip6(arg_ip6), del(arg_del) { } @@ -90,7 +80,7 @@ public: private: const struct ip* ip4; const struct ip6_hdr* ip6; - int del; + bool del; }; #endif diff --git a/src/IPAddr.cc b/src/IPAddr.cc index ff124025f9..29c8f1b8cf 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -250,7 +250,7 @@ IPPrefix::IPPrefix(const in6_addr& in6, uint8_t length) IPPrefix::IPPrefix(const IPAddr& addr, uint8_t length) : prefix(addr) { - if ( prefix.GetFamily() == IPAddr::IPv4 ) + if ( prefix.GetFamily() == IPv4 ) { if ( length > 32 ) reporter->InternalError("Bad IPAddr(v4) IPPrefix length : %d", @@ -275,7 +275,7 @@ string IPPrefix::AsString() const { char l[16]; - if ( prefix.GetFamily() == IPAddr::IPv4 ) + if ( prefix.GetFamily() == IPv4 ) modp_uitoa10(length - 96, l); else modp_uitoa10(length, l); diff --git a/src/IPAddr.h b/src/IPAddr.h index f0c0ac12c8..8e1921e07b 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -10,6 +10,8 @@ #include "BroString.h" #include "Hash.h" #include "util.h" +#include "Type.h" +#include "threading/SerialTypes.h" struct ConnID; class ExpectedConn; @@ -25,7 +27,7 @@ public: /** * Address family. */ - enum Family { IPv4, IPv6 }; + typedef IPFamily Family; /** * Byte order. @@ -45,7 +47,7 @@ public: * * @param in6 The IPv6 address. */ - IPAddr(const in4_addr& in4) + explicit IPAddr(const in4_addr& in4) { memcpy(in6.s6_addr, v4_mapped_prefix, sizeof(v4_mapped_prefix)); memcpy(&in6.s6_addr[12], &in4.s_addr, sizeof(in4.s_addr)); @@ -56,7 +58,7 @@ public: * * @param in6 The IPv6 address. */ - IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { } + explicit IPAddr(const in6_addr& arg_in6) : in6(arg_in6) { } /** * Constructs an address instance from a string representation. @@ -318,14 +320,19 @@ public: return memcmp(&addr1.in6, &addr2.in6, sizeof(in6_addr)) < 0; } + /** Converts the address into the type used internally by the + * inter-thread communication. + */ + void ConvertToThreadingValue(threading::Value::addr_t* v) const; + friend HashKey* BuildConnIDHashKey(const ConnID& id); friend HashKey* BuildExpectedConnHashKey(const ExpectedConn& c); - friend class IPPrefix; - unsigned int MemoryAllocation() const { return padded_sizeof(*this); } private: + friend class IPPrefix; + /** * Initializes an address instance from a string representation. * @@ -384,6 +391,25 @@ inline bool IPAddr::IsLoopback() const && (in6.s6_addr[14] == 0) && (in6.s6_addr[15] == 1)); } +inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const + { + v->family = GetFamily(); + + switch ( v->family ) { + + case IPv4: + CopyIPv4(&v->in.in4); + return; + + case IPv6: + CopyIPv6(&v->in.in6); + return; + + // Can't be reached. + abort(); + } + } + /** * Returns a hash key for a given ConnID. Passes ownership to caller. */ @@ -459,7 +485,7 @@ public: */ uint8_t Length() const { - return prefix.GetFamily() == IPAddr::IPv4 ? length - 96 : length; + return prefix.GetFamily() == IPv4 ? length - 96 : length; } /** @@ -516,6 +542,15 @@ public: return new HashKey(&key, sizeof(key)); } + /** Converts the prefix into the type used internally by the + * inter-thread communication. + */ + void ConvertToThreadingValue(threading::Value::subnet_t* v) const + { + v->length = length; + prefix.ConvertToThreadingValue(&v->prefix); + } + unsigned int MemoryAllocation() const { return padded_sizeof(*this); } /** diff --git a/src/NetVar.cc b/src/NetVar.cc index 7285a8433c..f9bd06413b 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -213,11 +213,6 @@ int sig_max_group_size; int enable_syslog; -int use_connection_compressor; -int cc_handle_resets; -int cc_handle_only_syns; -int cc_instantiate_on_data; - TableType* irc_join_list; RecordType* irc_join_info; TableVal* irc_servers; @@ -527,12 +522,6 @@ void init_net_var() gap_report_freq = opt_internal_double("gap_report_freq"); - use_connection_compressor = - opt_internal_int("use_connection_compressor"); - cc_handle_resets = opt_internal_int("cc_handle_resets"); - cc_handle_only_syns = opt_internal_int("cc_handle_only_syns"); - cc_instantiate_on_data = opt_internal_int("cc_instantiate_on_data"); - irc_join_info = internal_type("irc_join_info")->AsRecordType(); irc_join_list = internal_type("irc_join_list")->AsTableType(); irc_servers = internal_val("irc_servers")->AsTableVal(); diff --git a/src/NetVar.h b/src/NetVar.h index 488d842aec..acdafaea4c 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -216,11 +216,6 @@ extern int sig_max_group_size; extern int enable_syslog; -extern int use_connection_compressor; -extern int cc_handle_resets; -extern int cc_handle_only_syns; -extern int cc_instantiate_on_data; - extern TableType* irc_join_list; extern RecordType* irc_join_info; extern TableVal* irc_servers; diff --git a/src/PIA.cc b/src/PIA.cc index 7417615566..9adb4ccab3 100644 --- a/src/PIA.cc +++ b/src/PIA.cc @@ -196,7 +196,7 @@ void PIA_TCP::FirstPacket(bool is_orig, const IP_Hdr* ip) ip4->ip_p = IPPROTO_TCP; // Cast to const so that it doesn't delete it. - ip4_hdr = new IP_Hdr((const struct ip*) ip4); + ip4_hdr = new IP_Hdr(ip4, false); } if ( is_orig ) diff --git a/src/PacketSort.cc b/src/PacketSort.cc index 67a0cf861f..d0e04a37ea 100644 --- a/src/PacketSort.cc +++ b/src/PacketSort.cc @@ -27,9 +27,9 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src, { const struct ip* ip = (const struct ip*) (pkt + hdr_size); if ( ip->ip_v == 4 ) - ip_hdr = new IP_Hdr(ip); + ip_hdr = new IP_Hdr(ip, false); else - ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip); + ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false); if ( ip_hdr->NextProto() == IPPROTO_TCP && // Note: can't sort fragmented packets diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 0d89e5ce99..4b8f527f2b 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -681,7 +681,7 @@ RemoteSerializer::PeerID RemoteSerializer::Connect(const IPAddr& ip, if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); - if ( ip.GetFamily() == IPAddr::IPv6 ) + if ( ip.GetFamily() == IPv6 ) Error("inter-Bro communication not supported over IPv6"); const uint32* bytes; @@ -1238,7 +1238,7 @@ bool RemoteSerializer::Listen(const IPAddr& ip, uint16 port, bool expect_ssl) if ( ! initialized ) reporter->InternalError("remote serializer not initialized"); - if ( ip.GetFamily() == IPAddr::IPv6 ) + if ( ip.GetFamily() == IPv6 ) Error("inter-Bro communication not supported over IPv6"); const uint32* bytes; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index a90bc83293..da12b1b679 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1082,7 +1082,7 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to) bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; - if ( v->AsSubNet().Prefix().GetFamily() == IPAddr::IPv4 && + if ( v->AsSubNet().Prefix().GetFamily() == IPv4 && is_v4_mask ) { mval->val = ntohl(*n); diff --git a/src/SerializationFormat.cc b/src/SerializationFormat.cc index af3d9b44c2..10dd4f29ea 100644 --- a/src/SerializationFormat.cc +++ b/src/SerializationFormat.cc @@ -250,9 +250,9 @@ bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag) } if ( n == 1 ) - *addr = IPAddr(IPAddr::IPv4, raw, IPAddr::Network); + *addr = IPAddr(IPv4, raw, IPAddr::Network); else - *addr = IPAddr(IPAddr::IPv6, raw, IPAddr::Network); + *addr = IPAddr(IPv6, raw, IPAddr::Network); return true; } @@ -269,6 +269,32 @@ bool BinarySerializationFormat::Read(IPPrefix* prefix, const char* tag) return true; } +bool BinarySerializationFormat::Read(struct in_addr* addr, const char* tag) + { + uint32_t* bytes = (uint32_t*) &addr->s_addr; + + if ( ! Read(&bytes[0], "addr4") ) + return false; + + bytes[0] = htonl(bytes[0]); + return true; + } + +bool BinarySerializationFormat::Read(struct in6_addr* addr, const char* tag) + { + uint32_t* bytes = (uint32_t*) &addr->s6_addr; + + for ( int i = 0; i < 4; ++i ) + { + if ( ! Read(&bytes[i], "addr6-part") ) + return false; + + bytes[i] = htonl(bytes[i]); + } + + return true; + } + bool BinarySerializationFormat::Write(char v, const char* tag) { DBG_LOG(DBG_SERIAL, "Write char %s [%s]", fmt_bytes(&v, 1), tag); @@ -362,6 +388,29 @@ bool BinarySerializationFormat::Write(const IPPrefix& prefix, const char* tag) return Write(prefix.Prefix(), "prefix") && Write(prefix.Length(), "width"); } +bool BinarySerializationFormat::Write(const struct in_addr& addr, const char* tag) + { + const uint32_t* bytes = (uint32_t*) &addr.s_addr; + + if ( ! Write(ntohl(bytes[0]), "addr4") ) + return false; + + return true; + } + +bool BinarySerializationFormat::Write(const struct in6_addr& addr, const char* tag) + { + const uint32_t* bytes = (uint32_t*) &addr.s6_addr; + + for ( int i = 0; i < 4; ++i ) + { + if ( ! Write(ntohl(bytes[i]), "addr6-part") ) + return false; + } + + return true; + } + bool BinarySerializationFormat::WriteOpenTag(const char* tag) { return true; @@ -464,6 +513,18 @@ bool XMLSerializationFormat::Read(IPPrefix* prefix, const char* tag) return false; } +bool XMLSerializationFormat::Read(struct in_addr* addr, const char* tag) + { + reporter->InternalError("no reading of xml"); + return false; + } + +bool XMLSerializationFormat::Read(struct in6_addr* addr, const char* tag) + { + reporter->InternalError("no reading of xml"); + return false; + } + bool XMLSerializationFormat::Write(char v, const char* tag) { return WriteElem(tag, "char", &v, 1); @@ -556,6 +617,18 @@ bool XMLSerializationFormat::Write(const IPPrefix& prefix, const char* tag) return false; } +bool XMLSerializationFormat::Write(const struct in_addr& addr, const char* tag) + { + reporter->InternalError("XML output of in_addr not implemented"); + return false; + } + +bool XMLSerializationFormat::Write(const struct in6_addr& addr, const char* tag) + { + reporter->InternalError("XML output of in6_addr not implemented"); + return false; + } + bool XMLSerializationFormat::WriteEncodedString(const char* s, int len) { while ( len-- ) diff --git a/src/SerializationFormat.h b/src/SerializationFormat.h index f5eb77c608..f270b61bae 100644 --- a/src/SerializationFormat.h +++ b/src/SerializationFormat.h @@ -9,6 +9,9 @@ using namespace std; #include "util.h" +class IPAddr; +class IPPrefix; + // Abstract base class. class SerializationFormat { public: @@ -30,6 +33,8 @@ public: virtual bool Read(string* s, const char* tag) = 0; virtual bool Read(IPAddr* addr, const char* tag) = 0; virtual bool Read(IPPrefix* prefix, const char* tag) = 0; + virtual bool Read(struct in_addr* addr, const char* tag) = 0; + virtual bool Read(struct in6_addr* addr, const char* tag) = 0; // Returns number of raw bytes read since last call to StartRead(). int BytesRead() const { return bytes_read; } @@ -54,6 +59,8 @@ public: virtual bool Write(const string& s, const char* tag) = 0; virtual bool Write(const IPAddr& addr, const char* tag) = 0; virtual bool Write(const IPPrefix& prefix, const char* tag) = 0; + virtual bool Write(const struct in_addr& addr, const char* tag) = 0; + virtual bool Write(const struct in6_addr& addr, const char* tag) = 0; virtual bool WriteOpenTag(const char* tag) = 0; virtual bool WriteCloseTag(const char* tag) = 0; @@ -96,6 +103,8 @@ public: virtual bool Read(string* s, const char* tag); virtual bool Read(IPAddr* addr, const char* tag); virtual bool Read(IPPrefix* prefix, const char* tag); + virtual bool Read(struct in_addr* addr, const char* tag); + virtual bool Read(struct in6_addr* addr, const char* tag); virtual bool Write(int v, const char* tag); virtual bool Write(uint16 v, const char* tag); virtual bool Write(uint32 v, const char* tag); @@ -109,6 +118,8 @@ public: virtual bool Write(const string& s, const char* tag); virtual bool Write(const IPAddr& addr, const char* tag); virtual bool Write(const IPPrefix& prefix, const char* tag); + virtual bool Write(const struct in_addr& addr, const char* tag); + virtual bool Write(const struct in6_addr& addr, const char* tag); virtual bool WriteOpenTag(const char* tag); virtual bool WriteCloseTag(const char* tag); virtual bool WriteSeparator(); @@ -133,6 +144,8 @@ public: virtual bool Write(const string& s, const char* tag); virtual bool Write(const IPAddr& addr, const char* tag); virtual bool Write(const IPPrefix& prefix, const char* tag); + virtual bool Write(const struct in_addr& addr, const char* tag); + virtual bool Write(const struct in6_addr& addr, const char* tag); virtual bool WriteOpenTag(const char* tag); virtual bool WriteCloseTag(const char* tag); virtual bool WriteSeparator(); @@ -150,6 +163,8 @@ public: virtual bool Read(string* s, const char* tag); virtual bool Read(IPAddr* addr, const char* tag); virtual bool Read(IPPrefix* prefix, const char* tag); + virtual bool Read(struct in_addr* addr, const char* tag); + virtual bool Read(struct in6_addr* addr, const char* tag); private: // Encodes non-printable characters. diff --git a/src/Serializer.h b/src/Serializer.h index 45575f7fa0..cd1199a340 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -415,7 +415,7 @@ public: } const IP_Hdr IP() const - { return IP_Hdr((struct ip *) (pkt + hdr_size)); } + { return IP_Hdr((struct ip *) (pkt + hdr_size), true); } void Describe(ODesc* d) const; diff --git a/src/Sessions.cc b/src/Sessions.cc index 908d091ace..04b877dfe0 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -27,7 +27,6 @@ #include "InterConn.h" #include "Discard.h" #include "RuleMatcher.h" -#include "ConnCompressor.h" #include "DPM.h" #include "PacketSort.h" @@ -275,13 +274,13 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, const struct ip* ip = (const struct ip*) (pkt + hdr_size); if ( ip->ip_v == 4 ) { - IP_Hdr ip_hdr(ip); + IP_Hdr ip_hdr(ip, false); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } else if ( ip->ip_v == 6 ) { - IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size)); + IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false); DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); } @@ -510,7 +509,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, id.src_addr = ip_hdr->SrcAddr(); id.dst_addr = ip_hdr->DstAddr(); Dictionary* d = 0; - bool pass_to_conn_compressor = false; switch ( proto ) { case IPPROTO_TCP: @@ -520,7 +518,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, id.dst_port = tp->th_dport; id.is_one_way = 0; d = &tcp_conns; - pass_to_conn_compressor = ip4 && use_connection_compressor; break; } @@ -563,45 +560,40 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, // FIXME: The following is getting pretty complex. Need to split up // into separate functions. - if ( pass_to_conn_compressor ) - conn = conn_compressor->NextPacket(t, h, ip_hdr, hdr, pkt); + conn = (Connection*) d->Lookup(h); + if ( ! conn ) + { + conn = NewConn(h, t, &id, data, proto); + if ( conn ) + d->Insert(h, conn); + } else { - conn = (Connection*) d->Lookup(h); - if ( ! conn ) + // We already know that connection. + int consistent = CheckConnectionTag(conn); + if ( consistent < 0 ) { + delete h; + return; + } + + if ( ! consistent || conn->IsReuse(t, data) ) + { + if ( consistent ) + conn->Event(connection_reused, 0); + + Remove(conn); conn = NewConn(h, t, &id, data, proto); if ( conn ) d->Insert(h, conn); } else - { - // We already know that connection. - int consistent = CheckConnectionTag(conn); - if ( consistent < 0 ) - { - delete h; - return; - } - - if ( ! consistent || conn->IsReuse(t, data) ) - { - if ( consistent ) - conn->Event(connection_reused, 0); - - Remove(conn); - conn = NewConn(h, t, &id, data, proto); - if ( conn ) - d->Insert(h, conn); - } - else - delete h; - } - - if ( ! conn ) delete h; } + if ( ! conn ) + delete h; + if ( ! conn ) return; @@ -838,16 +830,7 @@ Connection* NetSessions::FindConnection(Val* v) Dictionary* d; if ( orig_portv->IsTCP() ) - { - if ( use_connection_compressor ) - { - Connection* conn = conn_compressor->Lookup(h); - delete h; - return conn; - } - else - d = &tcp_conns; - } + d = &tcp_conns; else if ( orig_portv->IsUDP() ) d = &udp_conns; else if ( orig_portv->IsICMP() ) @@ -900,17 +883,7 @@ void NetSessions::Remove(Connection* c) switch ( c->ConnTransport() ) { case TRANSPORT_TCP: - if ( use_connection_compressor && - conn_compressor->Remove(k) ) - // Note, if the Remove() returned false - // then the compressor doesn't know about - // this connection, which *should* mean that - // we never gave it the connection in the - // first place, and thus we should check - // the regular TCP table instead. - ; - - else if ( ! tcp_conns.RemoveEntry(k) ) + if ( ! tcp_conns.RemoveEntry(k) ) reporter->InternalError("connection missing"); break; @@ -957,13 +930,8 @@ void NetSessions::Insert(Connection* c) // reference the old key for already existing connections. case TRANSPORT_TCP: - if ( use_connection_compressor ) - old = conn_compressor->Insert(c); - else - { - old = (Connection*) tcp_conns.Remove(c->Key()); - tcp_conns.Insert(c->Key(), c); - } + old = (Connection*) tcp_conns.Remove(c->Key()); + tcp_conns.Insert(c->Key(), c); break; case TRANSPORT_UDP: @@ -995,9 +963,6 @@ void NetSessions::Insert(Connection* c) void NetSessions::Drain() { - if ( use_connection_compressor ) - conn_compressor->Drain(); - IterCookie* cookie = tcp_conns.InitForIteration(); Connection* tc; @@ -1110,10 +1075,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, conn->AppendAddl(fmt("tag=%s", conn->GetTimerMgr()->GetTag().c_str())); - // If the connection compressor is active, it takes care of the - // new_connection/connection_external events for TCP connections. - if ( new_connection && - (tproto != TRANSPORT_TCP || ! use_connection_compressor) ) + if ( new_connection ) { conn->Event(new_connection, 0); diff --git a/src/Stats.cc b/src/Stats.cc index f418e9cccc..a2e7496c5f 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -6,7 +6,6 @@ #include "Stats.h" #include "Scope.h" #include "cq.h" -#include "ConnCompressor.h" #include "DNS_Mgr.h" #include "Trigger.h" #include "threading/Manager.h" @@ -129,19 +128,6 @@ void ProfileLogger::Log() expensive ? sessions->ConnectionMemoryUsageConnVals() / 1024 : 0 )); - const ConnCompressor::Sizes& cs = conn_compressor->Size(); - - file->Write(fmt("%.6f ConnCompressor: pending=%d pending_in_mem=%d full_conns=%d pending+real=%d mem=%dK avg=%.1f/%.1f\n", - network_time, - cs.pending_valid, - cs.pending_in_mem, - cs.connections, - cs.hash_table_size, - cs.memory / 1024, - cs.memory / double(cs.pending_valid), - cs.memory / double(cs.pending_in_mem) - )); - SessionStats s; sessions->GetStats(s); diff --git a/src/Val.cc b/src/Val.cc index 0ee86304ed..a3cc54f8ec 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -606,7 +606,7 @@ ID* MutableVal::Bind() const ip = htonl(0x7f000001); // 127.0.0.1 safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", - IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(), + IPAddr(IPv4, &ip, IPAddr::Network)->AsString().c_str(), getpid()); #else safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid()); @@ -864,12 +864,12 @@ AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR) AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR) { // ### perhaps do gethostbyaddr here? - val.addr_val = new IPAddr(IPAddr::IPv4, &addr, IPAddr::Network); + val.addr_val = new IPAddr(IPv4, &addr, IPAddr::Network); } AddrVal::AddrVal(const uint32 addr[4]) : Val(TYPE_ADDR) { - val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network); + val.addr_val = new IPAddr(IPv6, addr, IPAddr::Network); } AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR) @@ -889,7 +889,7 @@ unsigned int AddrVal::MemoryAllocation() const Val* AddrVal::SizeVal() const { - if ( val.addr_val->GetFamily() == IPAddr::IPv4 ) + if ( val.addr_val->GetFamily() == IPv4 ) return new Val(32, TYPE_COUNT); else return new Val(128, TYPE_COUNT); @@ -933,13 +933,13 @@ SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET) SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET) { - IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network); + IPAddr a(IPv4, &addr, IPAddr::Network); val.subnet_val = new IPPrefix(a, width); } SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET) { - IPAddr a(IPAddr::IPv6, addr, IPAddr::Network); + IPAddr a(IPv6, addr, IPAddr::Network); val.subnet_val = new IPPrefix(a, width); } @@ -958,6 +958,16 @@ SubNetVal::~SubNetVal() delete val.subnet_val; } +const IPAddr& SubNetVal::Prefix() const + { + return val.subnet_val->Prefix(); + } + +int SubNetVal::Width() const + { + return val.subnet_val->Length(); + } + unsigned int SubNetVal::MemoryAllocation() const { return padded_sizeof(*this) + val.subnet_val->MemoryAllocation(); @@ -983,7 +993,7 @@ IPAddr SubNetVal::Mask() const uint32 m[4]; for ( unsigned int i = 0; i < 4; ++i ) m[i] = 0; - IPAddr rval(IPAddr::IPv6, m, IPAddr::Host); + IPAddr rval(IPv6, m, IPAddr::Host); return rval; } @@ -999,7 +1009,7 @@ IPAddr SubNetVal::Mask() const while ( ++mp < m + 4 ) *mp = 0; - IPAddr rval(IPAddr::IPv6, m, IPAddr::Host); + IPAddr rval(IPv6, m, IPAddr::Host); return rval; } diff --git a/src/Val.h b/src/Val.h index 36f32944c8..b3a8c845b2 100644 --- a/src/Val.h +++ b/src/Val.h @@ -513,10 +513,6 @@ protected: #define UDP_PORT_MASK 0x20000 #define ICMP_PORT_MASK 0x30000 -typedef enum { - TRANSPORT_UNKNOWN, TRANSPORT_TCP, TRANSPORT_UDP, TRANSPORT_ICMP, -} TransportProto; - class PortVal : public Val { public: // Constructors - both take the port number in host order. @@ -589,8 +585,8 @@ public: Val* SizeVal() const; - const IPAddr& Prefix() const { return val.subnet_val->Prefix(); } - int Width() const { return val.subnet_val->Length(); } + const IPAddr& Prefix() const; + int Width() const; IPAddr Mask() const; bool Contains(const IPAddr& addr) const; diff --git a/src/bro.bif b/src/bro.bif index ff06288940..684b888202 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1949,7 +1949,7 @@ function is_local_interface%(ip: addr%) : bool if ( ent ) { for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) - addrs.push_back(IPAddr(IPAddr::IPv4, (uint32*)ent->h_addr_list[len], + addrs.push_back(IPAddr(IPv4, (uint32*)ent->h_addr_list[len], IPAddr::Network)); } @@ -1958,7 +1958,7 @@ function is_local_interface%(ip: addr%) : bool if ( ent ) { for ( unsigned int len = 0; ent->h_addr_list[len]; ++len ) - addrs.push_back(IPAddr(IPAddr::IPv6, (uint32*)ent->h_addr_list[len], + addrs.push_back(IPAddr(IPv6, (uint32*)ent->h_addr_list[len], IPAddr::Network)); } @@ -2024,7 +2024,7 @@ function gethostname%(%) : string ## Returns: true if *a* is an IPv4 address, else false. function is_v4_addr%(a: addr%): bool %{ - if ( a->AsAddr().GetFamily() == IPAddr::IPv4 ) + if ( a->AsAddr().GetFamily() == IPv4 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -2037,7 +2037,7 @@ function is_v4_addr%(a: addr%): bool ## Returns: true if *a* is an IPv6 address, else false. function is_v6_addr%(a: addr%): bool %{ - if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPv6 ) return new Val(1, TYPE_BOOL); else return new Val(0, TYPE_BOOL); @@ -3522,7 +3522,7 @@ function lookup_location%(a: addr%) : geo_location } #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( geoip_v6 && a->AsAddr().GetFamily() == IPAddr::IPv6 ) + if ( geoip_v6 && a->AsAddr().GetFamily() == IPv6 ) { geoipv6_t ga; a->AsAddr().CopyIPv6(&ga); @@ -3534,7 +3534,7 @@ function lookup_location%(a: addr%) : geo_location else #endif - if ( geoip && a->AsAddr().GetFamily() == IPAddr::IPv4 ) + if ( geoip && a->AsAddr().GetFamily() == IPv4 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -3617,7 +3617,7 @@ function lookup_asn%(a: addr%) : count { // IPv6 support showed up in 1.4.5. #ifdef HAVE_GEOIP_COUNTRY_EDITION_V6 - if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPv6 ) { geoipv6_t ga; a->AsAddr().CopyIPv6(&ga); @@ -3626,7 +3626,7 @@ function lookup_asn%(a: addr%) : count else #endif - if ( a->AsAddr().GetFamily() == IPAddr::IPv4 ) + if ( a->AsAddr().GetFamily() == IPv4 ) { const uint32* bytes; a->AsAddr().GetBytes(&bytes); @@ -5353,7 +5353,7 @@ function preserve_prefix%(a: addr, width: count%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPv6 ) builtin_error("preserve_prefix() not supported for IPv6 addresses"); else { @@ -5382,7 +5382,7 @@ function preserve_subnet%(a: subnet%): any AnonymizeIPAddr* ip_anon = ip_anonymizer[PREFIX_PRESERVING_A50]; if ( ip_anon ) { - if ( a->AsSubNet().Prefix().GetFamily() == IPAddr::IPv6 ) + if ( a->AsSubNet().Prefix().GetFamily() == IPv6 ) builtin_error("preserve_subnet() not supported for IPv6 addresses"); else { @@ -5418,7 +5418,7 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr if ( anon_class < 0 || anon_class >= NUM_ADDR_ANONYMIZATION_CLASSES ) builtin_error("anonymize_addr(): invalid ip addr anonymization class"); - if ( a->AsAddr().GetFamily() == IPAddr::IPv6 ) + if ( a->AsAddr().GetFamily() == IPv6 ) { builtin_error("anonymize_addr() not supported for IPv6 addresses"); return 0; diff --git a/src/input/Manager.cc b/src/input/Manager.cc index a171ec8a8f..a647b3c945 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -1428,12 +1428,12 @@ int Manager::GetValueLength(const Value* val) { case TYPE_ADDR: { - switch ( val->val.addr_val->GetFamily() ) { - case IPAddr::IPv4: - length += 1*sizeof(uint32_t); + switch ( val->val.addr_val.family ) { + case IPv4: + length += sizeof(val->val.addr_val.in.in4); break; - case IPAddr::IPv6: - length += 4*sizeof(uint32_t); + case IPv6: + length += sizeof(val->val.addr_val.in.in6); break; default: assert(false); @@ -1444,12 +1444,12 @@ int Manager::GetValueLength(const Value* val) { case TYPE_SUBNET: { - switch ( val->val.addr_val->GetFamily() ) { - case IPAddr::IPv4: - length += 1*sizeof(uint32_t)+sizeof(uint8_t); + switch ( val->val.subnet_val.prefix.family ) { + case IPv4: + length += sizeof(val->val.subnet_val.prefix.in.in4)+sizeof(val->val.subnet_val.length); break; - case IPAddr::IPv6: - length += 4*sizeof(uint32_t)+sizeof(uint8_t); + case IPv6: + length += sizeof(val->val.subnet_val.prefix.in.in6)+sizeof(val->val.subnet_val.length); break; default: assert(false); @@ -1527,23 +1527,47 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) { case TYPE_ADDR: { - const uint32_t* bytes; - int len = val->val.addr_val->GetBytes(&bytes) * sizeof(uint32_t); - memcpy(data+startpos, (const char*) bytes, len); - return len; - break; - } + int length; + switch ( val->val.addr_val.family ) { + case IPv4: + length = sizeof(val->val.addr_val.in.in4); + memcpy(data + startpos, (const char*) &(val->val.addr_val.in.in4), length); + break; + case IPv6: + length = sizeof(val->val.addr_val.in.in6); + memcpy(data + startpos, (const char*) &(val->val.addr_val.in.in6), length); + break; + default: + assert(false); + } + + return length; - case TYPE_SUBNET: { - const uint32_t* bytes; - int len = val->val.subnet_val->Prefix().GetBytes(&bytes) * sizeof(uint32_t); - memcpy(data+startpos, (const char*) bytes, len); - uint8_t prefixlen = val->val.subnet_val->Length(); - memcpy(data+startpos+len, (const char*) &(prefixlen), sizeof(uint8_t) ); - len += sizeof(uint8_t); - return len; - break; } + break; + + case TYPE_SUBNET: + { + int length; + switch ( val->val.subnet_val.prefix.family ) { + case IPv4: + length = sizeof(val->val.addr_val.in.in4); + memcpy(data + startpos, (const char*) &(val->val.subnet_val.prefix.in.in4), length); + break; + case IPv6: + length += sizeof(val->val.addr_val.in.in6); + memcpy(data + startpos, (const char*) &(val->val.subnet_val.prefix.in.in4), length); + break; + default: + assert(false); + } + int lengthlength = sizeof(val->val.subnet_val.length); + memcpy(data + startpos + length , (const char*) &(val->val.subnet_val.length), lengthlength); + length += lengthlength; + return length; + + } + break; case TYPE_TABLE: { int length = 0; @@ -1648,11 +1672,42 @@ Val* Manager::ValueToVal(const Value* val, BroType* request_type) { break; case TYPE_ADDR: - return new AddrVal(*(val->val.addr_val)); - break; + { + IPAddr* addr; + switch ( val->val.addr_val.family ) { + case IPv4: + addr = new IPAddr(val->val.addr_val.in.in4); + break; + case IPv6: + addr = new IPAddr(val->val.addr_val.in.in6); + break; + default: + assert(false); + } + AddrVal* addrval = new AddrVal(*addr); + delete addr; + return addrval; + + } case TYPE_SUBNET: - return new SubNetVal(*(val->val.subnet_val)); + { + IPAddr* addr; + switch ( val->val.subnet_val.prefix.family ) { + case IPv4: + addr = new IPAddr(val->val.subnet_val.prefix.in.in4); + break; + case IPv6: + addr = new IPAddr(val->val.subnet_val.prefix.in.in6); + break; + default: + assert(false); + } + SubNetVal* subnetval = new SubNetVal(*addr, val->val.subnet_val.length); + delete addr; + return subnetval; + + } break; case TYPE_TABLE: { diff --git a/src/input/ReaderBackend.cc b/src/input/ReaderBackend.cc index 8ddb6a2f42..5af02b1acc 100644 --- a/src/input/ReaderBackend.cc +++ b/src/input/ReaderBackend.cc @@ -273,5 +273,49 @@ bool ReaderBackend::DoHeartbeat(double network_time, double current_time) return true; } +TransportProto ReaderBackend::StringToProto(const string &proto) { + if ( proto == "unknown" ) { + return TRANSPORT_UNKNOWN; + } else if ( proto == "tcp" ) { + return TRANSPORT_TCP; + } else if ( proto == "udp" ) { + return TRANSPORT_UDP; + } else if ( proto == "icmp" ) { + return TRANSPORT_ICMP; + } + + Error(Fmt("Tried to parse invalid/unknown protocol: %s", proto.c_str())); + + return TRANSPORT_UNKNOWN; +} + + +// more or less verbose copy from IPAddr.cc -- which uses reporter +Value::addr_t ReaderBackend::StringToAddr(const string &s) { + Value::addr_t val; + + if ( s.find(':') == std::string::npos ) // IPv4. + { + val.family = IPv4; + + if ( inet_aton(s.c_str(), &(val.in.in4)) <= 0 ) { + Error(Fmt("Bad addres: %s", s.c_str())); + memset(&val.in.in4.s_addr, 0, sizeof(val.in.in4.s_addr)); + } + + + } + else + { + val.family = IPv6; + if ( inet_pton(AF_INET6, s.c_str(), val.in.in6.s6_addr) <=0 ) + { + Error(Fmt("Bad IP address: %s", s.c_str())); + memset(val.in.in6.s6_addr, 0, sizeof(val.in.in6.s6_addr)); + } + } + + return val; +} } diff --git a/src/input/ReaderBackend.h b/src/input/ReaderBackend.h index 141c17c188..e167f8ff47 100644 --- a/src/input/ReaderBackend.h +++ b/src/input/ReaderBackend.h @@ -267,6 +267,20 @@ protected: */ virtual bool DoHeartbeat(double network_time, double current_time); + /** + * Utility function for Readers - convert a string into a TransportProto + * + * @param proto the transport protocol + */ + TransportProto StringToProto(const string &proto); + + /** + * Utility function for Readers - convert a string into a Value::addr_t + * + * @param addr containing an ipv4 or ipv6 address + */ + threading::Value::addr_t StringToAddr(const string &addr); + private: // Frontend that instantiated us. This object must not be access from // this class, it's running in a different thread! diff --git a/src/input/readers/Ascii.cc b/src/input/readers/Ascii.cc index 71a79cc06d..ab26442524 100644 --- a/src/input/readers/Ascii.cc +++ b/src/input/readers/Ascii.cc @@ -245,23 +245,6 @@ bool Ascii::GetLine(string& str) { return false; } -TransportProto Ascii::StringToProto(const string &proto) { - if ( proto == "unknown" ) { - return TRANSPORT_UNKNOWN; - } else if ( proto == "tcp" ) { - return TRANSPORT_TCP; - } else if ( proto == "udp" ) { - return TRANSPORT_UDP; - } else if ( proto == "icmp" ) { - return TRANSPORT_ICMP; - } - - //assert(false); - - reporter->Error("Tried to parse invalid/unknown protocol: %s", proto.c_str()); - - return TRANSPORT_UNKNOWN; -} Value* Ascii::EntryToVal(string s, FieldMapping field) { @@ -309,20 +292,22 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { break; case TYPE_SUBNET: { - int pos = s.find("/"); + size_t pos = s.find("/"); + if ( pos == s.npos ) { + Error(Fmt("Invalid value for subnet: %s", s.c_str())); + return false; + } int width = atoi(s.substr(pos+1).c_str()); string addr = s.substr(0, pos); - IPAddr a(addr); - val->val.subnet_val = new IPPrefix(a, width); - + val->val.subnet_val.prefix = StringToAddr(addr); + val->val.subnet_val.length = width; + } break; - } - case TYPE_ADDR: { - val->val.addr_val = new IPAddr(s); + case TYPE_ADDR: + val->val.addr_val = StringToAddr(s); break; - } case TYPE_TABLE: case TYPE_VECTOR: diff --git a/src/input/readers/Ascii.h b/src/input/readers/Ascii.h index d2376e4fe1..3bb0e91853 100644 --- a/src/input/readers/Ascii.h +++ b/src/input/readers/Ascii.h @@ -67,8 +67,6 @@ private: bool HasFilter(int id); - TransportProto StringToProto(const string &proto); - bool ReadHeader(bool useCached); threading::Value* EntryToVal(string s, FieldMapping type); diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index ca9ec1c3c4..0753296cb4 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -862,11 +862,11 @@ threading::Value* Manager::ValToLogVal(Val* val, BroType* ty) break; case TYPE_SUBNET: - lval->val.subnet_val = new IPPrefix(val->AsSubNet()); + val->AsSubNet().ConvertToThreadingValue(&lval->val.subnet_val); break; case TYPE_ADDR: - lval->val.addr_val = new IPAddr(val->AsAddr()); + val->AsAddr().ConvertToThreadingValue(&lval->val.addr_val); break; case TYPE_DOUBLE: diff --git a/src/logging/WriterBackend.cc b/src/logging/WriterBackend.cc index f4e48ebaef..7c71c09604 100644 --- a/src/logging/WriterBackend.cc +++ b/src/logging/WriterBackend.cc @@ -242,4 +242,40 @@ bool WriterBackend::DoHeartbeat(double network_time, double current_time) return true; } +string WriterBackend::Render(const threading::Value::addr_t& addr) const + { + if ( addr.family == IPv4 ) + { + char s[INET_ADDRSTRLEN]; + + if ( inet_ntop(AF_INET, &addr.in.in4, s, INET_ADDRSTRLEN) == NULL ) + return ""; + else + return s; + } + else + { + char s[INET6_ADDRSTRLEN]; + + if ( inet_ntop(AF_INET6, &addr.in.in6, s, INET6_ADDRSTRLEN) == NULL ) + return ""; + else + return s; + } + } + +string WriterBackend::Render(const threading::Value::subnet_t& subnet) const + { + char l[16]; + + if ( subnet.prefix.family == IPv4 ) + modp_uitoa10(subnet.length - 96, l); + else + modp_uitoa10(subnet.length, l); + + string s = Render(subnet.prefix) + "/" + l; + + return s; + } + diff --git a/src/logging/WriterBackend.h b/src/logging/WriterBackend.h index f9653d6b69..efb3b5d95e 100644 --- a/src/logging/WriterBackend.h +++ b/src/logging/WriterBackend.h @@ -158,6 +158,21 @@ public: bool FinishedRotation(string new_name, string old_name, double open, double close, bool terminating); + /** Helper method to render an IP address as a string. + * + * @param addr The address. + * + * @return An ASCII representation of the address. + */ + string Render(const threading::Value::addr_t& addr) const; + + /** Helper method to render an subnet value as a string. + * + * @param addr The address. + * + * @return An ASCII representation of the address. + */ + string Render(const threading::Value::subnet_t& subnet) const; protected: /** diff --git a/src/logging/writers/Ascii.cc b/src/logging/writers/Ascii.cc index e5bfc205be..0759e60a82 100644 --- a/src/logging/writers/Ascii.cc +++ b/src/logging/writers/Ascii.cc @@ -177,11 +177,11 @@ bool Ascii::DoWriteOne(ODesc* desc, Value* val, const Field* field) break; case TYPE_SUBNET: - desc->Add(*val->val.subnet_val); + desc->Add(Render(val->val.subnet_val)); break; case TYPE_ADDR: - desc->Add(*val->val.addr_val); + desc->Add(Render(val->val.addr_val)); break; case TYPE_TIME: diff --git a/src/main.cc b/src/main.cc index 8205b6de0b..8dc7acd72b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -43,7 +43,6 @@ extern "C" void OPENSSL_add_all_algorithms_conf(void); #include "PersistenceSerializer.h" #include "EventRegistry.h" #include "Stats.h" -#include "ConnCompressor.h" #include "DPM.h" #include "BroDoc.h" #include "Brofiler.h" @@ -101,7 +100,6 @@ int do_notice_analysis = 0; int rule_bench = 0; int generate_documentation = 0; SecondaryPath* secondary_path = 0; -ConnCompressor* conn_compressor = 0; extern char version[]; char* command_line_policy = 0; vector params; @@ -305,7 +303,6 @@ void terminate_bro() delete state_serializer; delete event_registry; delete secondary_path; - delete conn_compressor; delete remote_serializer; delete dpm; delete log_mgr; @@ -834,8 +831,6 @@ int main(int argc, char** argv) delete [] script_rule_files; - conn_compressor = new ConnCompressor(); - if ( g_policy_debug ) // ### Add support for debug command file. dbg_init_debugger(0); diff --git a/src/net_util.cc b/src/net_util.cc index f78246c634..5e403a349f 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -162,8 +162,8 @@ const char* fmt_conn_id(const IPAddr& src_addr, uint32 src_port, const char* fmt_conn_id(const uint32* src_addr, uint32 src_port, const uint32* dst_addr, uint32 dst_port) { - IPAddr src(IPAddr::IPv6, src_addr, IPAddr::Network); - IPAddr dst(IPAddr::IPv6, dst_addr, IPAddr::Network); + IPAddr src(IPv6, src_addr, IPAddr::Network); + IPAddr dst(IPv6, dst_addr, IPAddr::Network); return fmt_conn_id(src, src_port, dst, dst_port); } diff --git a/src/net_util.h b/src/net_util.h index 8787340328..f61340869a 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -5,6 +5,13 @@ #include "config.h" +// Define first. +typedef enum { + TRANSPORT_UNKNOWN, TRANSPORT_TCP, TRANSPORT_UDP, TRANSPORT_ICMP, +} TransportProto; + +typedef enum { IPv4, IPv6 } IPFamily; + #include #include @@ -21,7 +28,6 @@ #include #include "util.h" -#include "IPAddr.h" #ifdef HAVE_NETINET_IP6_H #include @@ -58,6 +64,8 @@ inline int seq_delta(uint32 a, uint32 b) return int(a-b); } +class IPAddr; + // Returns the ones-complement checksum of a chunk of b short-aligned bytes. extern int ones_complement_checksum(const void* p, int b, uint32 sum); extern int ones_complement_checksum(const IPAddr& a, uint32 sum); diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 472d10139a..1b8b8925cf 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -106,9 +106,12 @@ void Manager::Process() Message* msg = t->RetrieveOut(); - if ( msg->Process() ) //&& network_time ) // FIXME: ask robin again if he needs this. makes input interface not work in bro_init. - did_process = true; + if ( msg->Process() ) + { + //if ( network_time ) //&& network_time ) // FIXME: ask robin again if he needs this. makes input interface not work in bro_init. + did_process = true; + } else { string s = msg->Name() + " failed, terminating thread " + t->Name() + " (in ThreadManager)"; diff --git a/src/threading/SerialTypes.cc b/src/threading/SerialTypes.cc index e496139125..78556e5271 100644 --- a/src/threading/SerialTypes.cc +++ b/src/threading/SerialTypes.cc @@ -32,12 +32,6 @@ Value::~Value() && present ) delete val.string_val; - if ( type == TYPE_ADDR && present ) - delete val.addr_val; - - if ( type == TYPE_SUBNET && present ) - delete val.subnet_val; - if ( type == TYPE_TABLE && present ) { for ( int i = 0; i < val.set_val.size; i++ ) @@ -132,8 +126,8 @@ bool Value::Read(SerializationFormat* fmt) if ( ! (fmt->Read(&val.port_val.port, "port") && fmt->Read(&proto, "proto") ) ) { return false; } - - switch (proto) { + + switch ( proto ) { case 0: val.port_val.proto = TRANSPORT_UNKNOWN; break; @@ -149,20 +143,55 @@ bool Value::Read(SerializationFormat* fmt) default: return false; } + return true; } - - case TYPE_SUBNET: - { - val.subnet_val = new IPPrefix; - return fmt->Read(val.subnet_val, "subnet"); - } - case TYPE_ADDR: { - val.addr_val = new IPAddr; - return fmt->Read(val.addr_val, "addr"); + char family; + + if ( ! fmt->Read(&family, "addr-family") ) + return false; + + switch ( family ) { + case 4: + val.addr_val.family = IPv4; + return fmt->Read(&val.addr_val.in.in4, "addr-in4"); + + case 6: + val.addr_val.family = IPv6; + return fmt->Read(&val.addr_val.in.in6, "addr-in6"); + + } + + // Can't be reached. + abort(); + } + + case TYPE_SUBNET: + { + char length; + char family; + + if ( ! (fmt->Read(&length, "subnet-len") && fmt->Read(&family, "subnet-family")) ) + return false; + + switch ( family ) { + case 4: + val.subnet_val.length = (uint8_t)length; + val.subnet_val.prefix.family = IPv4; + return fmt->Read(&val.subnet_val.prefix.in.in4, "subnet-in4"); + + case 6: + val.subnet_val.length = (uint8_t)length; + val.subnet_val.prefix.family = IPv6; + return fmt->Read(&val.subnet_val.prefix.in.in6, "subnet-in6"); + + } + + // Can't be reached. + abort(); } case TYPE_DOUBLE: @@ -241,13 +270,44 @@ bool Value::Write(SerializationFormat* fmt) const return fmt->Write(val.uint_val, "uint"); case TYPE_PORT: - return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto"); - - case TYPE_SUBNET: - return fmt->Write(*val.subnet_val, "subnet"); + return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto"); case TYPE_ADDR: - return fmt->Write(*val.addr_val, "addr"); + { + switch ( val.addr_val.family ) { + case IPv4: + return fmt->Write((char)4, "addr-family") + && fmt->Write(val.addr_val.in.in4, "addr-in4"); + + case IPv6: + return fmt->Write((char)6, "addr-family") + && fmt->Write(val.addr_val.in.in6, "addr-in6"); + break; + } + + // Can't be reached. + abort(); + } + + case TYPE_SUBNET: + { + if ( ! fmt->Write((char)val.subnet_val.length, "subnet-length") ) + return false; + + switch ( val.subnet_val.prefix.family ) { + case IPv4: + return fmt->Write((char)4, "subnet-family") + && fmt->Write(val.subnet_val.prefix.in.in4, "subnet-in4"); + + case IPv6: + return fmt->Write((char)6, "subnet-family") + && fmt->Write(val.subnet_val.prefix.in.in6, "subnet-in6"); + break; + } + + // Can't be reached. + abort(); + } case TYPE_DOUBLE: case TYPE_TIME: diff --git a/src/threading/SerialTypes.h b/src/threading/SerialTypes.h index 6f569fb2d2..aa1aedbd9d 100644 --- a/src/threading/SerialTypes.h +++ b/src/threading/SerialTypes.h @@ -2,10 +2,13 @@ #ifndef THREADING_SERIALIZATIONTYPES_H #define THREADING_SERIALIZATIONTYPES_H -#include "../RemoteSerializer.h" - using namespace std; +#include "Type.h" +#include "net_util.h" + +class SerializationFormat; + namespace threading { /** @@ -64,6 +67,16 @@ struct Value { typedef set_t vec_t; struct port_t { bro_uint_t port; TransportProto proto; }; + struct addr_t { + IPFamily family; + union { + struct in_addr in4; + struct in6_addr in6; + } in; + }; + + struct subnet_t { addr_t prefix; uint8_t length; }; + /** * This union is a subset of BroValUnion, including only the types we * can log directly. See IsCompatibleType(). @@ -75,8 +88,8 @@ struct Value { double double_val; set_t set_val; vec_t vector_val; - IPAddr* addr_val; - IPPrefix* subnet_val; + addr_t addr_val; + subnet_t subnet_val; string* string_val; } val; @@ -122,6 +135,7 @@ struct Value { static bool IsCompatibleType(BroType* t, bool atomic_only=false); private: +friend class ::IPAddr; Value(const Value& other) { } // Disabled. }; diff --git a/testing/btest/Baseline/core.conn-uid/output.cc b/testing/btest/Baseline/core.conn-uid/output.cc deleted file mode 100644 index c77eda4f04..0000000000 --- a/testing/btest/Baseline/core.conn-uid/output.cc +++ /dev/null @@ -1,43 +0,0 @@ -[orig_h=141.142.220.202, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], UWkUyAuUGXf -[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp], arKYeMETxOg -[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], k6kgXLOoSKl -[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh -[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal -[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 -[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 -[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 -[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 -[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 -[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq -[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb -[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], UfGkYA2HI2g -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl -[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], BWaU4aSuwkc -[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], 10XodEwRycf -[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp], zno26fFZkrh -[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], v5rgkJBig5l -[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp], eWZCH7OONC1 -[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], 0Pwk3ntf8O3 -[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], 0HKorjr8Zp7 diff --git a/testing/btest/Baseline/core.conn-uid/output.cc2 b/testing/btest/Baseline/core.conn-uid/output.cc2 deleted file mode 100644 index c77eda4f04..0000000000 --- a/testing/btest/Baseline/core.conn-uid/output.cc2 +++ /dev/null @@ -1,43 +0,0 @@ -[orig_h=141.142.220.202, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], UWkUyAuUGXf -[orig_h=fe80::217:f2ff:fed7:cf65, orig_p=5353/udp, resp_h=ff02::fb, resp_p=5353/udp], arKYeMETxOg -[orig_h=141.142.220.50, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], k6kgXLOoSKl -[orig_h=141.142.220.118, orig_p=35634/tcp, resp_h=208.80.152.2, resp_p=80/tcp], nQcgTWjvg4c -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=48649/tcp, resp_h=208.80.152.118, resp_p=80/tcp], j4u32Pc5bif -[orig_h=141.142.220.118, orig_p=43927/udp, resp_h=141.142.2.2, resp_p=53/udp], TEfuqmmG4bh -[orig_h=141.142.220.118, orig_p=37676/udp, resp_h=141.142.2.2, resp_p=53/udp], FrJExwHcSal -[orig_h=141.142.220.118, orig_p=40526/udp, resp_h=141.142.2.2, resp_p=53/udp], 5OKnoww6xl4 -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=32902/udp, resp_h=141.142.2.2, resp_p=53/udp], fRFu0wcOle6 -[orig_h=141.142.220.118, orig_p=59816/udp, resp_h=141.142.2.2, resp_p=53/udp], qSsw6ESzHV4 -[orig_h=141.142.220.118, orig_p=59714/udp, resp_h=141.142.2.2, resp_p=53/udp], iE6yhOq3SF -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=58206/udp, resp_h=141.142.2.2, resp_p=53/udp], qCaWGmzFtM5 -[orig_h=141.142.220.118, orig_p=38911/udp, resp_h=141.142.2.2, resp_p=53/udp], 70MGiRM1Qf4 -[orig_h=141.142.220.118, orig_p=59746/udp, resp_h=141.142.2.2, resp_p=53/udp], h5DsfNtYzi1 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=45000/udp, resp_h=141.142.2.2, resp_p=53/udp], c4Zw9TmAE05 -[orig_h=141.142.220.118, orig_p=48479/udp, resp_h=141.142.2.2, resp_p=53/udp], EAr0uf4mhq -[orig_h=141.142.220.118, orig_p=48128/udp, resp_h=141.142.2.2, resp_p=53/udp], GvmoxJFXdTa -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=56056/udp, resp_h=141.142.2.2, resp_p=53/udp], slFea8xwSmb -[orig_h=141.142.220.118, orig_p=55092/udp, resp_h=141.142.2.2, resp_p=53/udp], UfGkYA2HI2g -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.118, orig_p=49997/tcp, resp_h=208.80.152.3, resp_p=80/tcp], VW0XPVINV8a -[orig_h=141.142.220.118, orig_p=49996/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 3PKsZ2Uye21 -[orig_h=141.142.220.118, orig_p=49998/tcp, resp_h=208.80.152.3, resp_p=80/tcp], GSxOnSLghOa -[orig_h=141.142.220.118, orig_p=50000/tcp, resp_h=208.80.152.3, resp_p=80/tcp], Tw8jXtpTGu6 -[orig_h=141.142.220.118, orig_p=49999/tcp, resp_h=208.80.152.3, resp_p=80/tcp], P654jzLoe3a -[orig_h=141.142.220.118, orig_p=50001/tcp, resp_h=208.80.152.3, resp_p=80/tcp], 0Q4FH8sESw5 -[orig_h=141.142.220.118, orig_p=35642/tcp, resp_h=208.80.152.2, resp_p=80/tcp], i2rO3KD1Syg -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl -[orig_h=141.142.220.235, orig_p=6705/tcp, resp_h=173.192.163.128, resp_p=80/tcp], 2cx26uAvUPl -[orig_h=141.142.220.44, orig_p=5353/udp, resp_h=224.0.0.251, resp_p=5353/udp], BWaU4aSuwkc -[orig_h=141.142.220.226, orig_p=137/udp, resp_h=141.142.220.255, resp_p=137/udp], 10XodEwRycf -[orig_h=fe80::3074:17d5:2052:c324, orig_p=65373/udp, resp_h=ff02::1:3, resp_p=5355/udp], zno26fFZkrh -[orig_h=141.142.220.226, orig_p=55131/udp, resp_h=224.0.0.252, resp_p=5355/udp], v5rgkJBig5l -[orig_h=fe80::3074:17d5:2052:c324, orig_p=54213/udp, resp_h=ff02::1:3, resp_p=5355/udp], eWZCH7OONC1 -[orig_h=141.142.220.226, orig_p=55671/udp, resp_h=224.0.0.252, resp_p=5355/udp], 0Pwk3ntf8O3 -[orig_h=141.142.220.238, orig_p=56641/udp, resp_h=141.142.220.255, resp_p=137/udp], 0HKorjr8Zp7 diff --git a/testing/btest/Baseline/istate.broccoli-ipv6/bro..stdout b/testing/btest/Baseline/istate.broccoli-ipv6/bro..stdout new file mode 100644 index 0000000000..0a7bac52c5 --- /dev/null +++ b/testing/btest/Baseline/istate.broccoli-ipv6/bro..stdout @@ -0,0 +1,9 @@ +handshake done with peer +bro_addr(1.2.3.4) +bro_subnet(10.0.0.0/16) +bro_addr(2607:f8b0:4009:802::1014) +bro_subnet(2607:f8b0::/32) +broccoli_addr(1.2.3.4) +broccoli_subnet(10.0.0.0/16) +broccoli_addr(2607:f8b0:4009:802::1014) +broccoli_subnet(2607:f8b0::/32) diff --git a/testing/btest/Baseline/istate.broccoli-ipv6/broccoli..stdout b/testing/btest/Baseline/istate.broccoli-ipv6/broccoli..stdout new file mode 100644 index 0000000000..481778c98a --- /dev/null +++ b/testing/btest/Baseline/istate.broccoli-ipv6/broccoli..stdout @@ -0,0 +1,6 @@ +Connected to Bro instance at: localhost:47757 +Received bro_addr(1.2.3.4) +Received bro_subnet(10.0.0.0/16) +Received bro_addr(2607:f8b0:4009:802::1014) +Received bro_subnet(2607:f8b0::/32) +Terminating diff --git a/testing/btest/Baseline/istate.pybroccoli/bro..stdout b/testing/btest/Baseline/istate.pybroccoli/bro..stdout index 1e70711932..70ca69dd98 100644 --- a/testing/btest/Baseline/istate.pybroccoli/bro..stdout +++ b/testing/btest/Baseline/istate.pybroccoli/bro..stdout @@ -1,14 +1,16 @@ ==== atomic -10 2 -1313624487.48817 +1330035434.516896 2.0 mins F 1.5 Servus 5555/tcp 6.7.6.5 +2001:db8:85a3::8a2e:370:7334 192.168.0.0/16 +2001:db8:85a3::/48 ==== record [a=42, b=6.6.7.7] 42, 6.6.7.7 diff --git a/testing/btest/Baseline/istate.pybroccoli/python..stdout.filtered b/testing/btest/Baseline/istate.pybroccoli/python..stdout.filtered index 864a4eb627..5d98e2d759 100644 --- a/testing/btest/Baseline/istate.pybroccoli/python..stdout.filtered +++ b/testing/btest/Baseline/istate.pybroccoli/python..stdout.filtered @@ -1,7 +1,7 @@ ==== atomic a 1 ==== -4L -4 42 42 -1313624487.4889 +1330035434.5180 60.0 True True 3.14 @@ -9,10 +9,12 @@ True True '12345/udp' 12345/udp '1.2.3.4' 1.2.3.4 '22.33.44.0/24' 22.33.44.0/24 +'2607:f8b0:4009:802::1014' 2607:f8b0:4009:802::1014 +'2607:f8b0::/32' 2607:f8b0::/32 ==== atomic a 2 ==== -10L -10 2 2 -1313624487.4882 +1330035434.5169 120.0 False False 1.5 @@ -20,10 +22,12 @@ False False '5555/tcp' 5555/tcp '6.7.6.5' 6.7.6.5 '192.168.0.0/16' 192.168.0.0/16 +'2001:db8:85a3::8a2e:370:7334' 2001:db8:85a3::8a2e:370:7334 +'2001:db8:85a3::/48' 2001:db8:85a3::/48 ==== atomic b 2 ==== -10L -10 2 - 1313624487.4882 + 1330035434.5169 120.0 False False 1.5 @@ -31,6 +35,8 @@ False False 5555/tcp 6.7.6.5 192.168.0.0/16 + 2001:db8:85a3::8a2e:370:7334 + 2001:db8:85a3::/48 ==== record 1 ==== 42L 42 diff --git a/testing/btest/analyzers/conn-size.bro b/testing/btest/analyzers/conn-size.bro index 0e413cc554..0ba7977cf5 100644 --- a/testing/btest/analyzers/conn-size.bro +++ b/testing/btest/analyzers/conn-size.bro @@ -1,2 +1,2 @@ -# @TEST-EXEC: bro -C -r ${TRACES}/conn-size.trace tcp udp icmp report_conn_size_analyzer=T use_connection_compressor=F +# @TEST-EXEC: bro -C -r ${TRACES}/conn-size.trace tcp udp icmp report_conn_size_analyzer=T # @TEST-EXEC: btest-diff conn.log diff --git a/testing/btest/core/conn-uid.bro b/testing/btest/core/conn-uid.bro index b2078bc9f5..52ff8fc4d3 100644 --- a/testing/btest/core/conn-uid.bro +++ b/testing/btest/core/conn-uid.bro @@ -9,17 +9,6 @@ # @TEST-EXEC: unset BRO_SEED_FILE && bro -C -r $TRACES/wikipedia.trace %INPUT >output2 # @TEST-EXEC: cat output output2 | sort | uniq -c | wc -l | sed 's/ //g' >counts # @TEST-EXEC: btest-diff counts -# -# Make sure it works without the connection compressor as well. -# -# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace %INPUT use_connection_compressor=F >output.cc -# @TEST-EXEC: btest-diff output.cc -# -# Make sure it works with the full connection compressor as well. -# -# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace %INPUT cc_handle_only_syns=F >output.cc2 -# @TEST-EXEC: btest-diff output.cc2 - event new_connection(c: connection) { diff --git a/testing/btest/istate/broccoli-ipv6.bro b/testing/btest/istate/broccoli-ipv6.bro new file mode 100644 index 0000000000..d567d58c0c --- /dev/null +++ b/testing/btest/istate/broccoli-ipv6.bro @@ -0,0 +1,13 @@ +# @TEST-REQUIRES: test -e $BUILD/aux/broccoli/src/libbroccoli.so || test -e $BUILD/aux/broccoli/src/libbroccoli.dylib +# +# @TEST-EXEC: btest-bg-run bro bro %INPUT $DIST/aux/broccoli/test/broccoli-v6addrs.bro +# @TEST-EXEC: btest-bg-run broccoli $BUILD/aux/broccoli/test/broccoli-v6addrs +# @TEST-EXEC: btest-bg-wait -k 20 +# @TEST-EXEC: btest-diff bro/.stdout +# @TEST-EXEC: btest-diff broccoli/.stdout + +event remote_connection_closed(p: event_peer) + { + terminate(); + } +