diff --git a/src/input/readers/raw/Raw.cc b/src/input/readers/raw/Raw.cc index 259792cb3f..b50479ad0c 100644 --- a/src/input/readers/raw/Raw.cc +++ b/src/input/readers/raw/Raw.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include "Raw.h" #include "Plugin.h" @@ -298,6 +299,17 @@ bool Raw::OpenInput() Warning(Fmt("Init: cannot set close-on-exec for %s", fname.c_str())); } + if ( offset ) + { + int whence = ( offset > 0 ) ? SEEK_SET : SEEK_END; + if ( fseek(file, offset, whence) < 0 ) + { + char buf[256]; + strerror_r(errno, buf, sizeof(buf)); + Error(Fmt("Seek failed in init: %s", buf)); + } + } + return true; } @@ -377,6 +389,20 @@ bool Raw::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fie forcekill = true; } + it = info.config.find("offset"); // we want to be sure that our child is dead when we exit + if ( it != info.config.end() && ! execute && ( Info().mode == MODE_STREAM || Info().mode == MODE_MANUAL ) ) + { + string offset_s = it->second; + offset = strtoll(offset_s.c_str(), 0, 10); + if ( offset < 0 ) + offset++; // we want -1 to be the end of the file + } + else if ( it != info.config.end() ) + { + Error("Offset only is supported for MODE_STREAM and MODE_MANUAL; it is also not supported when executing a command"); + return false; + } + if ( num_fields != want_fields ) { Error(Fmt("Filter for raw reader contains wrong number of fields -- got %d, expected %d. " diff --git a/src/input/readers/raw/Raw.h b/src/input/readers/raw/Raw.h index 06568a6296..f08d22beca 100644 --- a/src/input/readers/raw/Raw.h +++ b/src/input/readers/raw/Raw.h @@ -65,6 +65,8 @@ private: bool forcekill; + int64_t offset; + int pipes[6]; pid_t childpid; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.offset/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.offset/out new file mode 100644 index 0000000000..3af2451db9 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.offset/out @@ -0,0 +1,2 @@ +fkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF +F diff --git a/testing/btest/scripts/base/frameworks/input/raw/offset.bro b/testing/btest/scripts/base/frameworks/input/raw/offset.bro new file mode 100644 index 0000000000..8161785fdd --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/offset.bro @@ -0,0 +1,45 @@ +# @TEST-EXEC: btest-bg-run bro bro -b %INPUT +# @TEST-EXEC: btest-bg-wait 5 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out + +@TEST-START-FILE input.log +sdfkh:KH;fdkncv;ISEUp34:Fkdj;YVpIODhfDF +@TEST-END-FILE + +redef exit_only_after_terminate = T; + +global outfile: file; +global try: count; + +module A; + +type Val: record { + s: string; +}; + +event line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + print outfile, s; + try = try + 1; + if ( try == 2 ) + { + Input::remove("input"); + close(outfile); + terminate(); + } + } + +event bro_init() + { + try = 0; + outfile = open("../out"); + local config_strings: table[string] of string = { + ["offset"] = "2", + }; + local config_strings_two: table[string] of string = { + ["offset"] = "-3", # 2 characters before end, last char is newline. + }; + + Input::add_event([$source="../input.log", $config=config_strings, $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F]); + Input::add_event([$source="../input.log", $config=config_strings_two, $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input2", $fields=Val, $ev=line, $want_record=F]); + }