diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 66dadfdb2d..243567e0e6 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -22,7 +22,7 @@ using threading::Value; using threading::Field; struct InputHash { - HashKey* valhash; + hash_t valhash; HashKey* idxkey; // does not need ref or whatever - if it is present here, it is also still present in the TableVal. }; @@ -776,11 +776,15 @@ int Manager::SendEntryTable(const ReaderFrontend* reader, const int id, const Va //reporter->Error("Hashing %d index fields", i->num_idx_fields); HashKey* idxhash = HashValues(filter->num_idx_fields, vals); - //reporter->Error("Result: %d", (uint64_t) idxhash->Hash()); + //reporter->Error("Result: %d\n", (uint64_t) idxhash->Hash()); //reporter->Error("Hashing %d val fields", i->num_val_fields); - HashKey* valhash = 0; - if ( filter->num_val_fields > 0 ) - valhash = HashValues(filter->num_val_fields, vals+filter->num_idx_fields); + + hash_t valhash = 0; + if ( filter->num_val_fields > 0 ) { + HashKey* valhashkey = HashValues(filter->num_val_fields, vals+filter->num_idx_fields); + valhash = valhashkey->Hash(); + delete(valhashkey); + } //reporter->Error("Result: %d", (uint64_t) valhash->Hash()); @@ -789,7 +793,7 @@ int Manager::SendEntryTable(const ReaderFrontend* reader, const int id, const Va InputHash *h = filter->lastDict->Lookup(idxhash); if ( h != 0 ) { // seen before - if ( filter->num_val_fields == 0 || h->valhash->Hash() == valhash->Hash() ) { + if ( filter->num_val_fields == 0 || h->valhash == valhash ) { // ok, exact duplicate filter->lastDict->Remove(idxhash); filter->currDict->Insert(idxhash, h); @@ -862,7 +866,7 @@ int Manager::SendEntryTable(const ReaderFrontend* reader, const int id, const Va if ( updated == true ) { assert(filter->num_val_fields > 0); // in that case, we need the old value to send the event (if we send an event). - oldval = filter->tab->Lookup(idxval); + oldval = filter->tab->Lookup(idxval, false); } //i->tab->Assign(idxval, valval); @@ -872,6 +876,8 @@ int Manager::SendEntryTable(const ReaderFrontend* reader, const int id, const Va return filter->num_val_fields + filter->num_idx_fields; } + if ( filter->event && updated ) + Ref(oldval); // otherwise it is no longer accessible after the assignment filter->tab->Assign(idxval, k, valval); InputHash* ih = new InputHash(); @@ -891,7 +897,6 @@ int Manager::SendEntryTable(const ReaderFrontend* reader, const int id, const Va assert ( filter->num_val_fields > 0 ); ev = new EnumVal(BifEnum::Input::EVENT_CHANGED, BifType::Enum::Input::Event); assert ( oldval != 0 ); - Ref(oldval); SendEvent(filter->event, 3, ev, predidx, oldval); } else { ev = new EnumVal(BifEnum::Input::EVENT_NEW, BifType::Enum::Input::Event); @@ -1468,7 +1473,7 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) { int length = 0; memcpy(data+startpos, (const void*) &(val->val.port_val.port), sizeof(val->val.port_val.port)); length += sizeof(val->val.port_val.port); - memcpy(data+startpos, (const void*) &(val->val.port_val.proto), sizeof(val->val.port_val.proto)); + memcpy(data+startpos+length, (const void*) &(val->val.port_val.proto), sizeof(val->val.port_val.proto)); length += sizeof(val->val.port_val.proto); return length; break; @@ -1500,7 +1505,7 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) { int length = 0; memcpy(data+startpos,(const char*) &(val->val.subnet_val.width), sizeof(val->val.subnet_val.width) ); length += sizeof(val->val.subnet_val.width); - memcpy(data+startpos, (const char*) &(val->val.subnet_val.net), sizeof(val->val.subnet_val.net) ); + memcpy(data+startpos+length, (const char*) &(val->val.subnet_val.net), sizeof(val->val.subnet_val.net) ); length += sizeof(val->val.subnet_val.net); return length; break; @@ -1508,7 +1513,8 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) { case TYPE_TABLE: { int length = 0; - for ( int i = 0; i < val->val.set_val.size; i++ ) { + int j = val->val.set_val.size; + for ( int i = 0; i < j; i++ ) { length += CopyValue(data, startpos+length, val->val.set_val.vals[i]); } return length; @@ -1531,6 +1537,7 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) { } reporter->InternalError("internal error"); + assert(false); return 0; } @@ -1550,13 +1557,16 @@ HashKey* Manager::HashValues(const int num_elements, const Value* const *vals) { if ( data == 0 ) { reporter->InternalError("Could not malloc?"); } + memset(data, 0, length); for ( int i = 0; i < num_elements; i++ ) { const Value* val = vals[i]; position += CopyValue(data, position, val); } + hash_t key = HashKey::HashBytes(data, length); + assert(position == length); - return new HashKey(data, length); + return new HashKey(data, length, key, true); } diff --git a/src/input/readers/Ascii.cc b/src/input/readers/Ascii.cc index b0b046b75b..d4b3d91e00 100644 --- a/src/input/readers/Ascii.cc +++ b/src/input/readers/Ascii.cc @@ -268,7 +268,7 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { if ( s.compare(unset_field) == 0 ) { // field is not set... return new Value(field.type, false); } - + switch ( field.type ) { case TYPE_ENUM: case TYPE_STRING: @@ -302,6 +302,7 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { break; case TYPE_PORT: + val->val.port_val.port = 0; val->val.port_val.port = atoi(s.c_str()); val->val.port_val.proto = TRANSPORT_UNKNOWN; break; @@ -312,19 +313,27 @@ Value* Ascii::EntryToVal(string s, FieldMapping field) { val->val.subnet_val.width = atoi(width.c_str()); string addr = s.substr(0, pos); s = addr; - // NOTE: dotted_to_addr BREAKS THREAD SAFETY! it uses reporter. - // Solve this some other time.... #ifdef BROv6 if ( s.find(':') != s.npos ) { - uint32* addr = dotted_to_addr6(s.c_str()); + uint32* addr = new uint32[4]; + if ( inet_pton(AF_INET6, s.c_str(), addr) <= 0 ) { + Error(Fmt("Bad IPv6 address: %s", s.c_str())); + val->val.subnet_val.net[0] = val->val.subnet_val.net[1] = val->val.subnet_val.net[2] = val->val.subnet_val.net[3] = 0; + } copy_addr(val->val.subnet_val.net, addr); delete addr; } else { val->val.subnet_val.net[0] = val->val.subnet_val.net[1] = val->val.subnet_val.net[2] = 0; - val->val.subnet_val.net[3] = dotted_to_addr(s.c_str()); + if ( inet_aton(s.c_str(), &(val->val.subnet_val.net[3])) <= 0 ) { + Error(Fmt("Bad addres: %s", s.c_str())); + val->val.subnet_val.net[3] = 0; + } } #else - val->val.subnet_val.net = dotted_to_addr(s.c_str()); + if ( inet_aton(s.c_str(), (in_addr*) &(val->val.subnet_val.net)) <= 0 ) { + Error(Fmt("Bad addres: %s", s.c_str())); + val->val.subnet_val.net = 0; + } #endif break; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.reread/out b/testing/btest/Baseline/scripts.base.frameworks.input.reread/out index 4234a5056d..9516cb2a92 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.reread/out +++ b/testing/btest/Baseline/scripts.base.frameworks.input.reread/out @@ -1,3 +1,19 @@ +============EVENT============ +Input::EVENT_NEW +[i=-42] +[b=T, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ +2, +4, +1, +3 +}, ss={ +CC, +AA, +BB +}, se={ + +}, vc=[10, 20, 30], ve=[]] +==========SERVERS============ { [-42] = [b=T, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ 2, @@ -12,6 +28,22 @@ BB }, vc=[10, 20, 30], ve=[]] } +============EVENT============ +Input::EVENT_NEW +[i=-43] +[b=T, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ +2, +4, +1, +3 +}, ss={ +CC, +AA, +BB +}, se={ + +}, vc=[10, 20, 30], ve=[]] +==========SERVERS============ { [-43] = [b=T, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ 2, @@ -38,6 +70,22 @@ BB }, vc=[10, 20, 30], ve=[]] } +============EVENT============ +Input::EVENT_CHANGED +[i=-43] +[b=T, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ +2, +4, +1, +3 +}, ss={ +CC, +AA, +BB +}, se={ + +}, vc=[10, 20, 30], ve=[]] +==========SERVERS============ { [-43] = [b=F, e=SSH::LOG, c=21, p=123/unknown, sn=10.0.0.0/24, a=1.2.3.4, d=3.14, t=1315801931.273616, iv=100.0, s=hurz, sc={ 2, diff --git a/testing/btest/scripts/base/frameworks/input/reread.bro b/testing/btest/scripts/base/frameworks/input/reread.bro index 5058f4a068..58df37af84 100644 --- a/testing/btest/scripts/base/frameworks/input/reread.bro +++ b/testing/btest/scripts/base/frameworks/input/reread.bro @@ -70,16 +70,25 @@ global outfile: file; global try: count; +event line(tpe: Input::Event, left: Idx, right: Val) { + print outfile, "============EVENT============"; + print outfile, tpe; + print outfile, left; + print outfile, right; +} + event bro_init() { outfile = open ("../out"); try = 0; # first read in the old stuff into the table... Input::create_stream(A::INPUT, [$source="../input.log", $mode=Input::REREAD]); - Input::add_tablefilter(A::INPUT, [$name="ssh", $idx=Idx, $val=Val, $destination=servers]); + Input::add_tablefilter(A::INPUT, [$name="ssh", $idx=Idx, $val=Val, $destination=servers, $ev=line]); } + event Input::update_finished(id: Input::ID) { + print outfile, "==========SERVERS============"; print outfile, servers; try = try + 1;