diff --git a/policy/bro.init b/policy/bro.init index b3f78f0689..03bdbc56ce 100644 --- a/policy/bro.init +++ b/policy/bro.init @@ -21,6 +21,7 @@ type conn_id: record { orig_p: port; resp_h: addr; resp_p: port; + uid: string; }; type icmp_conn: record { diff --git a/src/Conn.cc b/src/Conn.cc index 50afe41d0c..6cb24c3446 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -179,6 +179,8 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id) ++current_connections; ++total_connections; + uid = CalculateUID(); + TimerMgr::Tag* tag = current_iosrc->GetCurrentTag(); conn_timer_mgr = tag ? new TimerMgr::Tag(*tag) : 0; @@ -215,6 +217,43 @@ Connection::~Connection() --external_connections; } +uint64 Connection::uid_counter = 0; +uint64 Connection::uid_instance = 0; + +uint64 Connection::CalculateUID() + { + if ( uid_instance == 0 ) + { + // This is the first time we need a UID. Calculate the instance ID by + // hashing something likely to be unique. + struct { + char hostname[128]; + struct timeval time; + pid_t pid; + } unique; + + gethostname(unique.hostname, 128); + unique.hostname[sizeof(unique.hostname)-1] = '\0'; + gettimeofday(&unique.time, 0); + unique.pid = getpid(); + + uid_instance = HashKey::HashBytes(&unique, sizeof(unique)); + ++uid_instance; // Now it's larger than zero. + } + + // Now calculate the unique ID for this connection. + struct { + uint64 counter; + hash_t instance; + } key; + + key.counter = ++uid_counter; + key.instance = uid_instance; + + uint64_t h = HashKey::HashBytes(&key, sizeof(key)); + return h; + } + void Connection::Done() { finished = 1; @@ -346,6 +385,10 @@ RecordVal* Connection::BuildConnVal() id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type)); id_val->Assign(2, new AddrVal(resp_addr)); id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type)); + + char tmp[16]; + id_val->Assign(4, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); + conn_val->Assign(0, id_val); orig_endp = new RecordVal(endpoint); diff --git a/src/Conn.h b/src/Conn.h index bbe3c2b3f6..1da1f97b57 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -279,6 +279,8 @@ public: void AddHistory(char code) { history += code; } + uint64 CalculateUID(); + void DeleteTimer(double t); // Sets the root of the analyzer tree as well as the primary PIA. @@ -368,6 +370,11 @@ protected: string history; uint32 hist_seen; + uint64 uid; // Globally unique connection ID. + + static uint64 uid_counter; // Counter for uids. + static uint64 uid_instance; // Once computed instance ID. + TransportLayerAnalyzer* root_analyzer; PIA* primary_PIA; }; diff --git a/src/Hash.h b/src/Hash.h index fa1f00f91f..9d6809edc7 100644 --- a/src/Hash.h +++ b/src/Hash.h @@ -11,7 +11,7 @@ #define UHASH_KEY_SIZE 32 -typedef unsigned int hash_t; +typedef uint64 hash_t; typedef enum { HASH_KEY_INT, diff --git a/src/util.cc b/src/util.cc index d8390a866c..ee5552899c 100644 --- a/src/util.cc +++ b/src/util.cc @@ -340,6 +340,26 @@ int atoi_n(int len, const char* s, const char** end, int base, int& result) return 1; } +char* uitoa_n(uint64 value, char* str, int n, int base) + { + static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i = 0; + uint64 v; + char* p, *q; + char c; + + v = value; + + do { + str[i++] = dig[v % base]; + v /= base; + } while ( v && i < n ); + + str[i] = '\0'; + + return str; + } + int strstr_n(const int big_len, const u_char* big, const int little_len, const u_char* little) { diff --git a/src/util.h b/src/util.h index ab7cb3c6fe..df01e92af6 100644 --- a/src/util.h +++ b/src/util.h @@ -112,6 +112,7 @@ extern char* strcasestr(const char* s, const char* find); extern const char* strpbrk_n(size_t len, const char* s, const char* charset); extern int atoi_n(int len, const char* s, const char** end, int base, int& result); +extern char* uitoa_n(uint64 value, char* str, int n, int base); int strstr_n(const int big_len, const unsigned char* big, const int little_len, const unsigned char* little); extern int fputs(int len, const char* s, FILE* fp); @@ -151,9 +152,6 @@ extern void init_random_seed(uint32 seed, const char* load_file, extern uint64 rand64bit(); -#define UHASH_KEY_SIZE 32 -extern uint8 uhash_key[UHASH_KEY_SIZE]; - // Each event source that may generate events gets an internally unique ID. // This is always LOCAL for a local Bro. For remote event sources, it gets // assigned by the RemoteSerializer.