mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 03:58:20 +00:00
extend and refactor several fields
This commit is contained in:
parent
19fd5f66e8
commit
411908a102
8 changed files with 209 additions and 178 deletions
|
@ -1,4 +1,3 @@
|
||||||
# Generated by binpac_quickstart
|
|
||||||
|
|
||||||
include(BroPlugin)
|
include(BroPlugin)
|
||||||
|
|
||||||
|
@ -6,7 +5,6 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI
|
||||||
|
|
||||||
bro_plugin_begin(Bro NTP)
|
bro_plugin_begin(Bro NTP)
|
||||||
bro_plugin_cc(NTP.cc Plugin.cc)
|
bro_plugin_cc(NTP.cc Plugin.cc)
|
||||||
bro_plugin_bif(types.bif)
|
bro_plugin_bif(types.bif events.bif)
|
||||||
bro_plugin_bif(events.bif)
|
|
||||||
bro_plugin_pac(ntp.pac ntp-analyzer.pac ntp-mode7.pac ntp-protocol.pac)
|
bro_plugin_pac(ntp.pac ntp-analyzer.pac ntp-mode7.pac ntp-protocol.pac)
|
||||||
bro_plugin_end()
|
bro_plugin_end()
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// Generated by binpac_quickstart
|
|
||||||
|
|
||||||
#include "NTP.h"
|
#include "NTP.h"
|
||||||
|
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
|
@ -9,12 +7,9 @@
|
||||||
using namespace analyzer::NTP;
|
using namespace analyzer::NTP;
|
||||||
|
|
||||||
NTP_Analyzer::NTP_Analyzer(Connection* c)
|
NTP_Analyzer::NTP_Analyzer(Connection* c)
|
||||||
|
|
||||||
: analyzer::Analyzer("NTP", c)
|
: analyzer::Analyzer("NTP", c)
|
||||||
|
|
||||||
{
|
{
|
||||||
interp = new binpac::NTP::NTP_Conn(this);
|
interp = new binpac::NTP::NTP_Conn(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTP_Analyzer::~NTP_Analyzer()
|
NTP_Analyzer::~NTP_Analyzer()
|
||||||
|
@ -24,9 +19,7 @@ NTP_Analyzer::~NTP_Analyzer()
|
||||||
|
|
||||||
void NTP_Analyzer::Done()
|
void NTP_Analyzer::Done()
|
||||||
{
|
{
|
||||||
|
|
||||||
Analyzer::Done();
|
Analyzer::Done();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTP_Analyzer::DeliverPacket(int len, const u_char* data,
|
void NTP_Analyzer::DeliverPacket(int len, const u_char* data,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// Generated by binpac_quickstart
|
|
||||||
|
|
||||||
#ifndef ANALYZER_PROTOCOL_NTP_NTP_H
|
#ifndef ANALYZER_PROTOCOL_NTP_NTP_H
|
||||||
#define ANALYZER_PROTOCOL_NTP_NTP_H
|
#define ANALYZER_PROTOCOL_NTP_NTP_H
|
||||||
|
|
||||||
|
@ -12,27 +10,21 @@
|
||||||
|
|
||||||
namespace analyzer { namespace NTP {
|
namespace analyzer { namespace NTP {
|
||||||
|
|
||||||
class NTP_Analyzer
|
class NTP_Analyzer : public analyzer::Analyzer {
|
||||||
|
|
||||||
: public analyzer::Analyzer {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NTP_Analyzer(Connection* conn);
|
explicit NTP_Analyzer(Connection* conn);
|
||||||
virtual ~NTP_Analyzer();
|
~NTP_Analyzer() override;
|
||||||
|
|
||||||
// Overriden from Analyzer.
|
// Overriden from Analyzer.
|
||||||
virtual void Done();
|
void Done() override;
|
||||||
|
void DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
|
uint64 seq, const IP_Hdr* ip, int caplen) override;
|
||||||
|
|
||||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
uint64 seq, const IP_Hdr* ip, int caplen);
|
|
||||||
|
|
||||||
|
|
||||||
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
|
|
||||||
{ return new NTP_Analyzer(conn); }
|
{ return new NTP_Analyzer(conn); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
binpac::NTP::NTP_Conn* interp;
|
binpac::NTP::NTP_Conn* interp;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // namespace analyzer::*
|
} } // namespace analyzer::*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by binpac_quickstart
|
// See the file in the main distribution directory for copyright.
|
||||||
|
|
||||||
#include "plugin/Plugin.h"
|
#include "plugin/Plugin.h"
|
||||||
|
|
||||||
|
@ -11,12 +11,11 @@ class Plugin : public plugin::Plugin {
|
||||||
public:
|
public:
|
||||||
plugin::Configuration Configure()
|
plugin::Configuration Configure()
|
||||||
{
|
{
|
||||||
AddComponent(new ::analyzer::Component("NTP",
|
AddComponent(new ::analyzer::Component("NTP", ::analyzer::NTP::NTP_Analyzer::Instantiate));
|
||||||
::analyzer::NTP::NTP_Analyzer::InstantiateAnalyzer));
|
|
||||||
|
|
||||||
plugin::Configuration config;
|
plugin::Configuration config;
|
||||||
config.name = "Bro::NTP";
|
config.name = "Bro::NTP";
|
||||||
config.description = "Network Time Protocol analyzer";
|
config.description = "NTP analyzer";
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
} plugin;
|
} plugin;
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
## Generated for NTP time synchronization messages
|
## Generated for all NTP messages. Different from many other of Bro's events,
|
||||||
|
## this one is generated for both client-side and server-side messages.
|
||||||
##
|
##
|
||||||
## For more information about NTP, refer to :rfc:`5905`
|
## See `Wikipedia <http://en.wikipedia.org/wiki/Network_Time_Protocol>`__ for
|
||||||
|
## more information about the NTP protocol.
|
||||||
##
|
##
|
||||||
## c: The connection
|
## c: The connection record describing the corresponding UDP flow.
|
||||||
##
|
##
|
||||||
## msg: The NTP message record
|
## is_orig:
|
||||||
|
##
|
||||||
|
## msg: The parsed NTP message.
|
||||||
|
##
|
||||||
|
## .. zeek:see::
|
||||||
##
|
##
|
||||||
event ntp_message%(c: connection, is_orig: bool, msg: NTP::Message%);
|
event ntp_message%(c: connection, is_orig: bool, msg: NTP::Message%);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
%extern{
|
%extern{
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#define FRAC_16 pow(2,-16)
|
#define FRAC_16 pow(2,-16)
|
||||||
|
@ -28,64 +29,103 @@ Val* proc_ntp_timestamp(const NTP_Time* t)
|
||||||
%}
|
%}
|
||||||
|
|
||||||
refine flow NTP_Flow += {
|
refine flow NTP_Flow += {
|
||||||
function proc_ntp_association(msg: NTP_Association): bool
|
|
||||||
%{
|
|
||||||
RecordVal* rv = new RecordVal(BifType::Record::NTP::Message);
|
|
||||||
rv->Assign(0, new Val(${msg.version}, TYPE_COUNT));
|
|
||||||
rv->Assign(1, new Val(${msg.mode}, TYPE_COUNT));
|
|
||||||
rv->Assign(2, new Val(${msg.stratum}, TYPE_COUNT));
|
|
||||||
rv->Assign(3, new Val(pow(2, ${msg.poll}), TYPE_INTERVAL));
|
|
||||||
rv->Assign(4, new Val(pow(2, ${msg.precision}), TYPE_INTERVAL));
|
|
||||||
|
|
||||||
rv->Assign(5, proc_ntp_short(${msg.root_delay}));
|
# This builds the standard msg record
|
||||||
rv->Assign(6, proc_ntp_short(${msg.root_dispersion}));
|
function BuildNTPStdMsg(nsm: NTP_std_msg): BroVal
|
||||||
switch ( ${msg.stratum} )
|
%{
|
||||||
|
RecordVal* rv = new RecordVal(BifType::Record::NTP::std);
|
||||||
|
|
||||||
|
rv->Assign(0, new Val(${nsm.stratum}, TYPE_COUNT));
|
||||||
|
rv->Assign(1, new Val(pow(2, ${nsm.poll}), TYPE_INTERVAL));
|
||||||
|
rv->Assign(2, new Val(pow(2, ${nsm.precision}), TYPE_INTERVAL));
|
||||||
|
rv->Assign(3, proc_ntp_short(${nsm.root_delay}));
|
||||||
|
rv->Assign(4, proc_ntp_short(${nsm.root_dispersion}));
|
||||||
|
|
||||||
|
switch ( ${nsm.stratum} )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
// unknown stratum => kiss code
|
// unknown stratum => kiss code
|
||||||
rv->Assign(7, bytestring_to_val(${msg.reference_id}));
|
rv->Assign(7, bytestring_to_val(${nsm.reference_id}));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// reference clock => ref clock string
|
// reference clock => ref clock string
|
||||||
rv->Assign(8, bytestring_to_val(${msg.reference_id}));
|
rv->Assign(8, bytestring_to_val(${nsm.reference_id}));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// TODO: Check for v4/v6
|
// TODO: Check for v4/v6
|
||||||
const uint8* d = ${msg.reference_id}.data();
|
const uint8* d = ${nsm.reference_id}.data();
|
||||||
rv->Assign(9, new AddrVal(IPAddr(IPv4, (const uint32*) d, IPAddr::Network)));
|
rv->Assign(9, new AddrVal(IPAddr(IPv4, (const uint32*) d, IPAddr::Network)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv->Assign(11, proc_ntp_timestamp(${msg.reference_ts}));
|
rv->Assign(9, proc_ntp_timestamp(${nsm.reference_ts}));
|
||||||
rv->Assign(12, proc_ntp_timestamp(${msg.origin_ts}));
|
rv->Assign(10, proc_ntp_timestamp(${nsm.origin_ts}));
|
||||||
rv->Assign(13, proc_ntp_timestamp(${msg.receive_ts}));
|
rv->Assign(11, proc_ntp_timestamp(${nsm.receive_ts}));
|
||||||
rv->Assign(14, proc_ntp_timestamp(${msg.transmit_ts}));
|
rv->Assign(12, proc_ntp_timestamp(${nsm.transmit_ts}));
|
||||||
|
|
||||||
rv->Assign(17, new Val((uint32) ${msg.extensions}->size(), TYPE_COUNT));
|
rv->Assign(15, new Val((uint32) ${nsm.extensions}->size(), TYPE_COUNT));
|
||||||
|
|
||||||
BifEvent::generate_ntp_message(connection()->bro_analyzer(),
|
return rv;
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
is_orig(), rv);
|
|
||||||
return true;
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function proc_ntp_mode6(msg: NTP_Mode6): bool
|
# This builds the control msg record
|
||||||
|
function BuildNTPControlMsg(ncm: NTP_control_msg): BroVal
|
||||||
%{
|
%{
|
||||||
BifEvent::generate_ntp_mode6_message(connection()->bro_analyzer(),
|
RecordVal* rv = new RecordVal(BifType::Record::NTP::control);
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
is_orig(), ${msg.opcode});
|
rv->Assign(0, new Val(${ncm.OpCode}, TYPE_COUNT));
|
||||||
return true;
|
rv->Assign(1, new Val(${ncm.R}, TYPE_BOOL));
|
||||||
|
rv->Assign(2, new Val(${ncm.E}, TYPE_BOOL));
|
||||||
|
rv->Assign(3, new Val(${ncm.M}, TYPE_BOOL));
|
||||||
|
rv->Assign(4, new Val(${ncm.sequence}, TYPE_COUNT));
|
||||||
|
rv->Assign(5, new Val(${ncm.status}, TYPE_COUNT));
|
||||||
|
rv->Assign(6, new Val(${ncm.association_id}, TYPE_COUNT));
|
||||||
|
rv->Assign(7, new Val(${ncm.offs}, TYPE_COUNT));
|
||||||
|
rv->Assign(8, new Val(${ncm.c}, TYPE_COUNT));
|
||||||
|
rv->Assign(9, bytestring_to_val(${ncm.data}));
|
||||||
|
|
||||||
|
return rv;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function proc_ntp_mode7(msg: NTP_Mode7): bool
|
# This builds the mode7 msg record
|
||||||
|
function BuildNTPMode7Msg(m7: NTP_mode7_msg): BroVal
|
||||||
%{
|
%{
|
||||||
BifEvent::generate_ntp_mode7_message(connection()->bro_analyzer(),
|
RecordVal* rv = new RecordVal(BifType::Record::NTP::mode7);
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
is_orig(), ${msg.request_code});
|
rv->Assign(0, new Val(${m7.request_code}, TYPE_COUNT));
|
||||||
|
rv->Assign(1, new Val(${m7.auth_bit}, TYPE_BOOL));
|
||||||
|
rv->Assign(2, new Val(${m7.sequence}, TYPE_COUNT));
|
||||||
|
rv->Assign(3, new Val(${m7.implementation}, TYPE_COUNT));
|
||||||
|
rv->Assign(4, new Val(${m7.error_code}, TYPE_COUNT));
|
||||||
|
rv->Assign(5, bytestring_to_val(${m7.data}));
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
function proc_ntp_message(msg: NTP_PDU): bool
|
||||||
|
%{
|
||||||
|
|
||||||
|
RecordVal* rv = new RecordVal(BifType::Record::NTP::Message);
|
||||||
|
|
||||||
|
rv->Assign(0, new Val(${msg.version}, TYPE_COUNT));
|
||||||
|
rv->Assign(1, new Val(${msg.mode}, TYPE_COUNT));
|
||||||
|
|
||||||
|
// The standard record
|
||||||
|
if ( ${msg.mode}>0 && ${msg.mode}<6 ) {
|
||||||
|
rv->Assign(2, BuildNTPStdMsg(${msg.std}));
|
||||||
|
} else if ( ${msg.mode}==6 ) {
|
||||||
|
rv->Assign(3, BuildNTPControlMsg(${msg.control}));
|
||||||
|
} else if ( ${msg.mode}==7 ) {
|
||||||
|
rv->Assign(4, BuildNTPMode7Msg(${msg.mode7}));
|
||||||
|
}
|
||||||
|
|
||||||
|
BifEvent::generate_ntp_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), is_orig(), rv);
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr NTP_Association += &let {
|
refine typeattr NTP_PDU += &let {
|
||||||
proc: bool = $context.flow.proc_ntp_association(this);
|
proc: bool = $context.flow.proc_ntp_message(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,32 @@
|
||||||
|
|
||||||
|
# This is the common part in the header format.
|
||||||
|
# See RFC 5905 for details
|
||||||
type NTP_PDU(is_orig: bool) = record {
|
type NTP_PDU(is_orig: bool) = record {
|
||||||
|
# The first byte of the NTP header contains the leap indicator,
|
||||||
|
# the version and the mode
|
||||||
first_byte : uint8;
|
first_byte : uint8;
|
||||||
|
|
||||||
# Modes 1-5 are standard NTP time sync
|
# Modes 1-5 are standard NTP time sync
|
||||||
mode_chk_1 : case (mode>=1 && mode<=5) of {
|
standard_modes : case (mode>=1 && mode<=5) of {
|
||||||
true -> msg: NTP_Association(first_byte, mode, version);
|
true -> std : NTP_std_msg;
|
||||||
false -> unk: empty;
|
false -> emp : empty;
|
||||||
} &requires(version);
|
};
|
||||||
|
modes_6_7 : case (mode) of {
|
||||||
mode_chk_2 : case (mode) of {
|
# mode 6 is for control messages (format is different from modes 6-7)
|
||||||
6 -> ctl_msg : NTP_Mode6(first_byte, version) &restofdata;
|
6 -> control : NTP_control_msg;
|
||||||
7 -> mode_7 : NTP_Mode7(first_byte, version) &restofdata;
|
# mode 7 is reserved or private (and implementation dependent). For example used for some commands such as MONLIST
|
||||||
|
7 -> mode7 : NTP_mode7_msg;
|
||||||
default -> unknown : bytestring &restofdata;
|
default -> unknown : bytestring &restofdata;
|
||||||
} &requires(version);
|
};
|
||||||
|
|
||||||
} &let {
|
} &let {
|
||||||
mode: uint8 = (first_byte & 0x7); # Bytes 6-8 of 8-byte value
|
leap: uint8 = (first_byte & 0xc0)>>6; # First 2 bits of 8-bits value
|
||||||
version: uint8 = (first_byte & 0x38) >> 3; # Bytes 3-5 of 8-byte value
|
version: uint8 = (first_byte & 0x38)>>3; # Bits 3-5 of 8-bits value
|
||||||
} &byteorder=bigendian;
|
mode: uint8 = (first_byte & 0x07); # Bits 6-8 of 8-bits value
|
||||||
|
} &byteorder=bigendian &exportsourcedata;
|
||||||
|
|
||||||
type NTP_Association(first_byte: uint8, mode: uint8, version: uint8) = record {
|
# This is the most common type of message, corresponding to modes 1-5
|
||||||
|
# This kind of msg are used for normal operation of syncronization
|
||||||
|
# See RFC 5905 for details
|
||||||
|
type NTP_std_msg = record {
|
||||||
stratum : uint8;
|
stratum : uint8;
|
||||||
poll : int8;
|
poll : int8;
|
||||||
precision : int8;
|
precision : int8;
|
||||||
|
@ -31,19 +39,33 @@ type NTP_Association(first_byte: uint8, mode: uint8, version: uint8) = record {
|
||||||
origin_ts : NTP_Time;
|
origin_ts : NTP_Time;
|
||||||
receive_ts : NTP_Time;
|
receive_ts : NTP_Time;
|
||||||
transmit_ts : NTP_Time;
|
transmit_ts : NTP_Time;
|
||||||
|
|
||||||
extensions : Extension_Field[] &until($input.length() <= 18);
|
extensions : Extension_Field[] &until($input.length() <= 18);
|
||||||
have_mac : case (offsetof(have_mac) < length) of {
|
have_mac : case (offsetof(have_mac) < length) of {
|
||||||
true -> mac : NTP_MAC;
|
true -> mac : NTP_MAC;
|
||||||
false -> nil : empty;
|
false -> nil : empty;
|
||||||
} &requires(length);
|
} &requires(length);
|
||||||
} &let {
|
} &let {
|
||||||
leap: bool = (first_byte & 0xc0); # First 2 bytes of 8-byte value
|
|
||||||
leap_61: bool = (leap & 0x40) > 0; # leap_indicator == 1
|
|
||||||
leap_59: bool = (leap & 0x80) > 0; # leap_indicator == 2
|
|
||||||
leap_unk: bool = (leap & 0xc0) > 0; # leap_indicator == 3
|
|
||||||
length = sourcedata.length();
|
length = sourcedata.length();
|
||||||
} &exportsourcedata;
|
} &byteorder=bigendian &exportsourcedata;
|
||||||
|
|
||||||
|
# This format is for mode==6, control msg
|
||||||
|
# See RFC 1119 for details
|
||||||
|
type NTP_control_msg = record {
|
||||||
|
second_byte : uint8;
|
||||||
|
sequence : uint16;
|
||||||
|
status : uint16; #TODO: this must be further specified
|
||||||
|
association_id : uint16;
|
||||||
|
offs : uint16;
|
||||||
|
c : uint16;
|
||||||
|
data : bytestring &restofdata;
|
||||||
|
#auth : #TODO
|
||||||
|
} &let {
|
||||||
|
R: bool = (second_byte & 0x80) > 0; # First bit of 8-bits value
|
||||||
|
E: bool = (second_byte & 0x40) > 0; # Second bit of 8-bits value
|
||||||
|
M: bool = (second_byte & 0x20) > 0; # Third bit of 8-bits value
|
||||||
|
OpCode: uint8 = (second_byte & 0x1F); # Last 5 bits of 8-bits value
|
||||||
|
} &byteorder=bigendian &exportsourcedata;
|
||||||
|
|
||||||
|
|
||||||
type NTP_MAC = record {
|
type NTP_MAC = record {
|
||||||
key_id: uint32;
|
key_id: uint32;
|
||||||
|
@ -65,23 +87,3 @@ type NTP_Time = record {
|
||||||
seconds: uint32;
|
seconds: uint32;
|
||||||
fractions: uint32;
|
fractions: uint32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# From RFC 1305, Appendix B:
|
|
||||||
type NTP_Mode6(first_byte: uint8, version: uint8) = record {
|
|
||||||
rem_op : uint8;
|
|
||||||
sequence: uint16;
|
|
||||||
status : uint16;
|
|
||||||
assoc_id: uint16;
|
|
||||||
offset : uint16;
|
|
||||||
count : uint16;
|
|
||||||
data : bytestring &length=count;
|
|
||||||
pad : padding[pad_length];
|
|
||||||
opt_auth: bytestring &restofdata;
|
|
||||||
} &let {
|
|
||||||
response_bit: bool = (rem_op & 0x80) > 0;
|
|
||||||
error_bit : bool = (rem_op & 0x40) > 0;
|
|
||||||
more_bit : bool = (rem_op & 0x20) > 0;
|
|
||||||
opcode : uint8 = (rem_op & 0x1f);
|
|
||||||
pad_length : uint8 = (count % 32 == 0) ? 0 : 32 - (count % 32);
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module NTP;
|
module NTP;
|
||||||
|
|
||||||
|
type NTP::std: record;
|
||||||
|
type NTP::control: record;
|
||||||
|
type NTP::mode7: record;
|
||||||
type NTP::Message: record;
|
type NTP::Message: record;
|
||||||
|
|
||||||
module GLOBAL;
|
|
Loading…
Add table
Add a link
Reference in a new issue