how to get the oldest entry out of table

hi everybody

is it possible to get the oldest entry out of a table?

for example, i want to get the earliest occurence of an event from a certain source ip. i have saved all occurences in a table like this:

> global test: table[addr, time] of count &write_expire=10min;

how can i get the oldest entry?

does a for-loop go through the table in a predictable way?

thanx for any help
christoph

is it possible to get the oldest entry out of a table?

For tables, I do not see a way other than iterating over all
entries. But perhaps you can use a combination of tables and
vectors; something like

         type entry: record {
              t: time;
              c: count;
         };

         global test: table[addr] of vector of entry;

Then you can keep the vector entries sorted by time.

does a for-loop go through the table in a predictable way?

No, for tables the order is derived from the internal hashing, i.e.
basically random.

Robin

hi

> is it possible to get the oldest entry out of a table?

For tables, I do not see a way other than iterating over all
entries. But perhaps you can use a combination of tables and
vectors; something like

         type entry: record {
              t: time;
              c: count;
         };

         global test: table[addr] of vector of entry;

Then you can keep the vector entries sorted by time.

is vector a new type which is not documented in the bro ref manual?
however, what you suggest doesn't solve my problem, because i have no
chance to expire and delete each entry in the table individually. i can only
delete all entries of one addr at the same time with the expire
attribut for tables.

thanx
christoph

Hi Christoph,

is vector a new type which is not documented in the bro ref manual?

not really new, but not well documented either. Check the CHANGES file.

however, what you suggest doesn't solve my problem, because i have no
chance to expire and delete each entry in the table individually. i can only
delete all entries of one addr at the same time with the expire
attribut for tables.

Maybe we could help you better if you explained your problem setting a
bit. It sounds like what you'd like to have is a priority queue instead
of a basic table with expiration timers?

Cheers,
Christian.

hi

Maybe we could help you better if you explained your problem setting a
bit. It sounds like what you'd like to have is a priority queue instead
of a basic table with expiration timers?

okay. let's say i want to measure the failed connection attempts rate of a
host.

therefore, i maintain a table which contains the occurences of these events
and a counter which holds the number of entries in the table per source
host:

global failed_attempts: table[addr, addr, time] of bool
&expire_create=1min &expire_func=decrease_counter;
global failed_attempt_counter: table[addr] of count &default=0;

event connection_attempt(c: connection){
  local srcIP = c$id$orig_h;
        local destIP = c$id$resp_h;

  failed_attempts[srcIP, destIP, network_time()]=T;
  ++failed_attempt_counter[srcIP];
  if (failed_attempt_counter[srcIP] > 100) {
    alarm fmt("more than 100 failed attempts of host %s in 1 minute",
srcIP);
  }
}

function decrease_counter(t: table[addr, addr, time], idx: any){
  local srcIP: addr;
  local destIP: addr;
  local stamp: time;
  [srcIP,destIP,time]=idx;
  --failed_attempt_counter[srcIP];
}

when a worm becomes active the infected host will possibly have 500 failed
attempts per second! the above solution can't give me this information.
therefore, it would be very nice to have the time of occurence of the oldest
entry in the table "failed_attempts" conserning a certain source IP. with
this information it would be possible to calculate how long it took until
the 100 failed attempts had happened.

sorry, my case is a bit complicated. i hope you understand what i mean.

thanx
christoph