Merge branch 'mount-protocol' of https://github.com/dtrejod/bro

* 'mount-protocol' of https://github.com/dtrejod/bro:
  Add unit tests for new MOUNT events -- mount_proc_mnt, mount_proc_umnt, mount_proc_umnt_all, mount_proc_not_implemented.
  Add mount_proc_null, mount_proc_mnt, mount_proc_umnt, mount_proc_umnt_all, mount_proc_not_implemented, mount_reply_status.
This commit is contained in:
Jon Siwek 2018-02-05 13:29:39 -06:00
commit 35fa1261f3
13 changed files with 627 additions and 2 deletions

View file

@ -1,4 +1,12 @@
2.5-405 | 2018-02-05 13:29:39 -0600
* Add MOUNT3 protocol parser.
It's not activated by default. New events available: mount_proc_null,
mount_proc_mnt, mount_proc_umnt, mount_proc_umnt_all,
mount_proc_not_implemented, mount_reply_status. (Devin Trejo)
2.5-402 | 2018-02-05 10:43:59 -0600 2.5-402 | 2018-02-05 10:43:59 -0600
* Fix (unlikely) memory leak in nb_dns.c (Corelight) * Fix (unlikely) memory leak in nb_dns.c (Corelight)

9
NEWS
View file

@ -45,6 +45,15 @@ New Functionality
- HTTP now recognizes and skips upgraded/websocket connections. A new event, - HTTP now recognizes and skips upgraded/websocket connections. A new event,
http_connection_upgrade, is raised in such cases. http_connection_upgrade, is raised in such cases.
- Added a MOUNT3 protocol parser
- This is not enabled by default (no ports are registered and no
DPD signatures exist, so no connections will end up attaching the
new Mount analyzer). If it were to be activated by users, the
following events are available: mount_proc_null, mount_proc_mnt,
mount_proc_umnt, mount_proc_umnt_all, mount_proc_not_implemented,
mount_reply_status.
Changed Functionality Changed Functionality
--------------------- ---------------------

View file

@ -1 +1 @@
2.5-402 2.5-405

View file

@ -2350,6 +2350,71 @@ export {
}; };
} # end export } # end export
module MOUNT3;
export {
## Record summarizing the general results and status of MOUNT3
## request/reply pairs.
##
## Note that when *rpc_stat* or *mount_stat* indicates not successful,
## the reply record passed to the corresponding event will be empty and
## contain uninitialized fields, so don't use it. Also note that time
# and duration values might not be fully accurate. For TCP, we record
# times when the corresponding chunk of data is delivered to the
# analyzer. Depending on the reassembler, this might be well after the
# first packet of the request was received.
#
# .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
# mount_proc_umntall mount_proc_export mount_proc_not_implemented
type info_t: record {
## The RPC status.
rpc_stat: rpc_status;
## The MOUNT status.
mnt_stat: status_t;
## The start time of the request.
req_start: time;
## The duration of the request.
req_dur: interval;
## The length in bytes of the request.
req_len: count;
## The start time of the reply.
rep_start: time;
## The duration of the reply.
rep_dur: interval;
## The length in bytes of the reply.
rep_len: count;
## The user id of the reply.
rpc_uid: count;
## The group id of the reply.
rpc_gid: count;
## The stamp of the reply.
rpc_stamp: count;
## The machine name of the reply.
rpc_machine_name: string;
## The auxiliary ids of the reply.
rpc_auxgids: index_vec;
};
## MOUNT *mnt* arguments.
##
## .. bro:see:: mount_proc_mnt
type dirmntargs_t : record {
dirname: string; ##< Name of directory to mount
};
## MOUNT lookup reply. If the mount failed, *dir_attr* may be set. If the
## mount succeeded, *fh* is always set.
##
## .. bro:see:: mount_proc_mnt
type mnt_reply_t: record {
dirfh: string &optional; ##< Dir handle
auth_flavors: vector of auth_flavor_t &optional; ##< Returned authentication flavors
};
} # end export
module Threading; module Threading;
export { export {

View file

@ -4,6 +4,6 @@ include(BroPlugin)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
bro_plugin_begin(Bro RPC) bro_plugin_begin(Bro RPC)
bro_plugin_cc(RPC.cc NFS.cc Portmap.cc XDR.cc Plugin.cc) bro_plugin_cc(RPC.cc NFS.cc MOUNT.cc Portmap.cc XDR.cc Plugin.cc)
bro_plugin_bif(events.bif) bro_plugin_bif(events.bif)
bro_plugin_end() bro_plugin_end()

View file

@ -0,0 +1,301 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <algorithm>
#include <vector>
#include "bro-config.h"
#include "NetVar.h"
#include "XDR.h"
#include "MOUNT.h"
#include "Event.h"
#include "events.bif.h"
using namespace analyzer::rpc;
int MOUNT_Interp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n)
{
if ( c->Program() != 100005 )
Weird(fmt("bad_RPC_program (%d)", c->Program()));
uint32 proc = c->Proc();
// The call arguments, depends on the call type obviously ...
Val *callarg = 0;
switch ( proc ) {
case BifEnum::MOUNT3::PROC_NULL:
break;
case BifEnum::MOUNT3::PROC_MNT:
callarg = mount3_dirmntargs(buf, n);
break;
case BifEnum::MOUNT3::PROC_UMNT:
callarg = mount3_dirmntargs(buf, n);
break;
case BifEnum::MOUNT3::PROC_UMNT_ALL:
callarg = mount3_dirmntargs(buf, n);
break;
default:
callarg = 0;
if ( proc < BifEnum::MOUNT3::PROC_END_OF_PROCS )
{
// We know the procedure but haven't implemented it.
// Otherwise DeliverRPC would complain about
// excess_RPC.
n = 0;
}
else
Weird(fmt("unknown_MOUNT_request(%u)", proc));
// Return 1 so that replies to unprocessed calls will still
// be processed, and the return status extracted.
return 1;
}
if ( ! buf )
{
// There was a parse error while trying to extract the call
// arguments. However, we don't know where exactly it
// happened and whether Vals where already allocated (e.g., a
// RecordVal was allocated but we failed to fill it). So we
// Unref() the call arguments, and we are fine.
Unref(callarg);
callarg = 0;
return 0;
}
c->AddVal(callarg); // It's save to AddVal(0).
return 1;
}
int MOUNT_Interp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status,
const u_char*& buf, int& n, double start_time,
double last_time, int reply_len)
{
EventHandlerPtr event = 0;
Val* reply = 0;
BifEnum::MOUNT3::status_t mount_status = BifEnum::MOUNT3::MNT3_OK;
bool rpc_success = ( rpc_status == BifEnum::RPC_SUCCESS );
// Reply always starts with the MOUNT status.
if ( rpc_success )
{
if ( n >= 4 )
mount_status = (BifEnum::MOUNT3::status_t)extract_XDR_uint32(buf, n);
else
mount_status = BifEnum::MOUNT3::MOUNT3ERR_UNKNOWN;
}
if ( mount_reply_status )
{
val_list* vl = event_common_vl(c, rpc_status, mount_status,
start_time, last_time, reply_len);
analyzer->ConnectionEvent(mount_reply_status, vl);
}
if ( ! rpc_success )
{
// We set the buffer to NULL, the function that extract the
// reply from the data stream will then return empty records.
//
buf = NULL;
n = 0;
}
switch ( c->Proc() ) {
case BifEnum::MOUNT3::PROC_NULL:
event = mount_proc_null;
break;
case BifEnum::MOUNT3::PROC_MNT:
reply = mount3_mnt_reply(buf, n, mount_status);
event = mount_proc_mnt;
break;
case BifEnum::MOUNT3::PROC_UMNT:
reply = 0;
n = 0;
mount_status = BifEnum::MOUNT3::MNT3_OK;
event = mount_proc_umnt;
break;
case BifEnum::MOUNT3::PROC_UMNT_ALL:
reply = 0;
n = 0;
mount_status = BifEnum::MOUNT3::MNT3_OK;
event = mount_proc_umnt;
break;
default:
if ( c->Proc() < BifEnum::MOUNT3::PROC_END_OF_PROCS )
{
// We know the procedure but haven't implemented it.
// Otherwise DeliverRPC would complain about
// excess_RPC.
n = 0;
reply = new EnumVal(c->Proc(), BifType::Enum::MOUNT3::proc_t);
event = mount_proc_not_implemented;
}
else
return 0;
}
if ( rpc_success && ! buf )
{
// There was a parse error. We have to unref the reply. (see
// also comments in RPC_BuildCall.
Unref(reply);
reply = 0;
return 0;
}
// Note: if reply == 0, it won't be added to the val_list for the
// event. While we can check for that on the policy layer it's kinda
// ugly, because it's contrary to the event prototype. But having
// this optional argument to the event is really helpful. Otherwise I
// have to let reply point to a RecordVal where all fields are
// optional and all are set to 0 ...
if ( event )
{
val_list* vl = event_common_vl(c, rpc_status, mount_status,
start_time, last_time, reply_len);
Val *request = c->TakeRequestVal();
if ( request )
vl->append(request);
if ( reply )
vl->append(reply);
analyzer->ConnectionEvent(event, vl);
}
else
Unref(reply);
return 1;
}
val_list* MOUNT_Interp::event_common_vl(RPC_CallInfo *c,
BifEnum::rpc_status rpc_status,
BifEnum::MOUNT3::status_t mount_status,
double rep_start_time,
double rep_last_time, int reply_len)
{
// Returns a new val_list that already has a conn_val, and mount3_info.
// These are the first parameters for each mount_* event ...
val_list *vl = new val_list;
vl->append(analyzer->BuildConnVal());
VectorVal* auxgids = new VectorVal(internal_type("index_vec")->AsVectorType());
for (size_t i = 0; i < c->AuxGIDs().size(); ++i)
{
auxgids->Assign(i, new Val(c->AuxGIDs()[i], TYPE_COUNT));
}
RecordVal* info = new RecordVal(BifType::Record::MOUNT3::info_t);
info->Assign(0, new EnumVal(rpc_status, BifType::Enum::rpc_status));
info->Assign(1, new EnumVal(mount_status, BifType::Enum::MOUNT3::status_t));
info->Assign(2, new Val(c->StartTime(), TYPE_TIME));
info->Assign(3, new Val(c->LastTime() - c->StartTime(), TYPE_INTERVAL));
info->Assign(4, new Val(c->RPCLen(), TYPE_COUNT));
info->Assign(5, new Val(rep_start_time, TYPE_TIME));
info->Assign(6, new Val(rep_last_time - rep_start_time, TYPE_INTERVAL));
info->Assign(7, new Val(reply_len, TYPE_COUNT));
info->Assign(8, new Val(c->Uid(), TYPE_COUNT));
info->Assign(9, new Val(c->Gid(), TYPE_COUNT));
info->Assign(10, new Val(c->Stamp(), TYPE_COUNT));
info->Assign(11, new StringVal(c->MachineName()));
info->Assign(12, auxgids);
vl->append(info);
return vl;
}
EnumVal* MOUNT_Interp::mount3_auth_flavor(const u_char*& buf, int& n)
{
BifEnum::MOUNT3::auth_flavor_t t = (BifEnum::MOUNT3::auth_flavor_t)extract_XDR_uint32(buf, n);
return new EnumVal(t, BifType::Enum::MOUNT3::auth_flavor_t);
}
StringVal* MOUNT_Interp::mount3_fh(const u_char*& buf, int& n)
{
int fh_n;
const u_char* fh = extract_XDR_opaque(buf, n, fh_n, 64);
if ( ! fh )
return 0;
return new StringVal(new BroString(fh, fh_n, 0));
}
StringVal* MOUNT_Interp::mount3_filename(const u_char*& buf, int& n)
{
int name_len;
const u_char* name = extract_XDR_opaque(buf, n, name_len);
if ( ! name )
return 0;
return new StringVal(new BroString(name, name_len, 0));
}
RecordVal* MOUNT_Interp::mount3_dirmntargs(const u_char*& buf, int& n)
{
RecordVal* dirmntargs = new RecordVal(BifType::Record::MOUNT3::dirmntargs_t);
dirmntargs->Assign(0, mount3_filename(buf, n));
return dirmntargs;
}
RecordVal* MOUNT_Interp::mount3_mnt_reply(const u_char*& buf, int& n,
BifEnum::MOUNT3::status_t status)
{
RecordVal* rep = new RecordVal(BifType::Record::MOUNT3::mnt_reply_t);
if ( status == BifEnum::MOUNT3::MNT3_OK )
{
rep->Assign(0, mount3_fh(buf,n));
int auth_flavors_count = extract_XDR_uint32(buf, n);
VectorType* enum_vector = new VectorType(base_type(TYPE_ENUM));
VectorVal* auth_flavors = new VectorVal(enum_vector);
Unref(enum_vector);
for (int i = 0; i < auth_flavors_count; i++)
{
auth_flavors->Assign(auth_flavors->Size(), mount3_auth_flavor(buf, n)); // authentication
}
rep->Assign(1, auth_flavors);
}
else
{
rep->Assign(0, 0);
rep->Assign(1, 0);
}
return rep;
}
MOUNT_Analyzer::MOUNT_Analyzer(Connection* conn)
: RPC_Analyzer("MOUNT", conn, new MOUNT_Interp(this))
{
orig_rpc = resp_rpc = 0;
}
void MOUNT_Analyzer::Init()
{
RPC_Analyzer::Init();
if ( Conn()->ConnTransport() == TRANSPORT_TCP )
{
orig_rpc = new Contents_RPC(Conn(), true, interp);
resp_rpc = new Contents_RPC(Conn(), false, interp);
AddSupportAnalyzer(orig_rpc);
AddSupportAnalyzer(resp_rpc);
}
}

View file

@ -0,0 +1,55 @@
// See the file "COPYING" in the main distribution directory for copyright.
#ifndef ANALYZER_PROTOCOL_RPC_MOUNT_H
#define ANALYZER_PROTOCOL_RPC_MOUNT_H
#include "RPC.h"
#include "XDR.h"
#include "Event.h"
namespace analyzer { namespace rpc {
class MOUNT_Interp : public RPC_Interpreter {
public:
MOUNT_Interp(analyzer::Analyzer* arg_analyzer) : RPC_Interpreter(arg_analyzer) { }
protected:
int RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n);
int RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status rpc_status,
const u_char*& buf, int& n, double start_time,
double last_time, int reply_len);
// Returns a new val_list that already has a conn_val, rpc_status and
// mount_status. These are the first parameters for each mount_* event
// ...
val_list* event_common_vl(RPC_CallInfo *c, BifEnum::rpc_status rpc_status,
BifEnum::MOUNT3::status_t mount_status,
double rep_start_time, double rep_last_time,
int reply_len);
// These methods parse the appropriate MOUNTv3 "type" out of buf. If
// there are any errors (i.e., buffer to short, etc), buf will be set
// to 0. However, the methods might still return an allocated Val * !
// So, you might want to Unref() the Val if buf is 0. Method names
// are based on the type names of RFC 1813.
EnumVal* mount3_auth_flavor(const u_char*& buf, int& n);
StringVal* mount3_fh(const u_char*& buf, int& n);
RecordVal* mount3_dirmntargs(const u_char*&buf, int &n);
StringVal* mount3_filename(const u_char*& buf, int& n);
RecordVal* mount3_mnt_reply(const u_char*& buf, int& n, BifEnum::MOUNT3::status_t status);
};
class MOUNT_Analyzer : public RPC_Analyzer {
public:
MOUNT_Analyzer(Connection* conn);
virtual void Init();
static analyzer::Analyzer* Instantiate(Connection* conn)
{ return new MOUNT_Analyzer(conn); }
};
} } // namespace analyzer::*
#endif

View file

@ -5,6 +5,7 @@
#include "RPC.h" #include "RPC.h"
#include "NFS.h" #include "NFS.h"
#include "MOUNT.h"
#include "Portmap.h" #include "Portmap.h"
namespace plugin { namespace plugin {
@ -15,6 +16,7 @@ public:
plugin::Configuration Configure() plugin::Configuration Configure()
{ {
AddComponent(new ::analyzer::Component("NFS", ::analyzer::rpc::NFS_Analyzer::Instantiate)); AddComponent(new ::analyzer::Component("NFS", ::analyzer::rpc::NFS_Analyzer::Instantiate));
AddComponent(new ::analyzer::Component("MOUNT", ::analyzer::rpc::MOUNT_Analyzer::Instantiate));
AddComponent(new ::analyzer::Component("Portmapper", ::analyzer::rpc::Portmapper_Analyzer::Instantiate)); AddComponent(new ::analyzer::Component("Portmapper", ::analyzer::rpc::Portmapper_Analyzer::Instantiate));
AddComponent(new ::analyzer::Component("Contents_RPC", 0)); AddComponent(new ::analyzer::Component("Contents_RPC", 0));
AddComponent(new ::analyzer::Component("Contents_NFS", 0)); AddComponent(new ::analyzer::Component("Contents_NFS", 0));

View file

@ -765,3 +765,118 @@ event rpc_call%(c: connection, xid: count, prog: count, ver: count, proc: count,
## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload ## call to :bro:see:`Analyzer::register_for_ports` or a DPD payload
## signature. ## signature.
event rpc_reply%(c: connection, xid: count, status: rpc_status, reply_len: count%); event rpc_reply%(c: connection, xid: count, status: rpc_status, reply_len: count%);
## Generated for MOUNT3 request/reply dialogues of type *null*. The event is
## generated once we have either seen both the request and its corresponding
## reply, or an unanswered request has timed out.
## MOUNT is a service running on top of RPC.
##
## c: The RPC connection.
##
## info: Reports the status of the dialogue, along with some meta information.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_proc_null%(c: connection, info: MOUNT3::info_t%);
## Generated for MOUNT3 request/reply dialogues of type *mnt*. The event is
## generated once we have either seen both the request and its corresponding
## reply, or an unanswered request has timed out.
## MOUNT is a service running on top of RPC.
##
## c: The RPC connection.
##
## info: Reports the status of the dialogue, along with some meta information.
##
## req: The arguments passed in the request.
##
## rep: The response returned in the reply. The values may not be valid if the
## request was unsuccessful.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_proc_mnt%(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t, rep: MOUNT3::mnt_reply_t%);
## Generated for MOUNT3 request/reply dialogues of type *umnt*. The event is
## generated once we have either seen both the request and its corresponding
## reply, or an unanswered request has timed out.
## MOUNT is a service running on top of RPC.
##
## c: The RPC connection.
##
## info: Reports the status of the dialogue, along with some meta information.
##
## req: The arguments passed in the request.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_proc_umnt%(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t%);
## Generated for MOUNT3 request/reply dialogues of type *umnt_all*. The event is
## generated once we have either seen both the request and its corresponding
## reply, or an unanswered request has timed out.
## MOUNT is a service running on top of RPC.
##
## c: The RPC connection.
##
## info: Reports the status of the dialogue, along with some meta information.
##
## req: The arguments passed in the request.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_proc_umnt_all%(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t%);
## Generated for MOUNT3 request/reply dialogues of a type that Bro's MOUNTv3
## analyzer does not implement.
##
## c: The RPC connection.
##
## info: Reports the status of the dialogue, along with some meta information.
##
## proc: The procedure called that Bro does not implement.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_proc_not_implemented%(c: connection, info: MOUNT3::info_t, proc: MOUNT3::proc_t%);
## Generated for each MOUNT3 reply message received, reporting just the
## status included.
##
## n: The connection.
##
## info: Reports the status included in the reply.
##
## .. bro:see:: mount_proc_mnt mount_proc_dump mount_proc_umnt
## mount_proc_umntall mount_proc_export mount_proc_not_implemented
##
## .. todo:: Bro's current default configuration does not activate the protocol
## analyzer that generates this event; the corresponding script has not yet
## been ported to Bro 2.x. To still enable this event, one needs to
## register a port for it or add a DPD payload signature.
event mount_reply_status%(n: connection, info: MOUNT3::info_t%);

View file

@ -13,6 +13,43 @@ enum rpc_status %{
RPC_UNKNOWN_ERROR, RPC_UNKNOWN_ERROR,
%} %}
module MOUNT3;
enum proc_t %{ # MOUNT3 procedures
PROC_NULL = 0, # done
PROC_MNT = 1, # done
PROC_DUMP = 2, # not implemented
PROC_UMNT = 3, # done
PROC_UMNT_ALL = 4, # done
PROC_EXPORT = 5, # not implemented
PROC_END_OF_PROCS = 6, # not implemented
%}
enum status_t %{ # MOUNT3 return status
MNT3_OK = 0,
MNT3ERR_PERM = 1,
MNT3ERR_NOENT = 2,
MNT3ERR_IO = 5,
MNT3ERR_ACCES = 13,
MNT3ERR_NOTDIR = 20,
MNT3ERR_INVAL = 22,
MNT3ERR_NAMETOOLONG = 63,
MNT3ERR_NOTSUPP = 10004,
MNT3ERR_SERVERFAULT = 10006,
MOUNT3ERR_UNKNOWN = 0xffffffff,
%}
enum auth_flavor_t %{ # MOUNT3 auth flavors
AUTH_NULL = 0,
AUTH_UNIX = 1,
AUTH_SHORT = 2,
AUTH_DES = 3,
%}
type info_t: record;
type mnt_reply_t: record;
type dirmntargs_t: record;
module NFS3; module NFS3;
enum proc_t %{ # NFSv3 procedures enum proc_t %{ # NFSv3 procedures

View file

@ -0,0 +1,2 @@
mount_proc_mnt: [id=[orig_h=10.111.131.18, orig_p=765/udp, resp_h=10.111.131.132, resp_p=20048/udp], orig=[size=144, state=1, num_pkts=2, num_bytes_ip=200, flow_label=0, l2_addr=00:50:56:b2:4e:d3], resp=[size=84, state=1, num_pkts=1, num_bytes_ip=52, flow_label=0, l2_addr=00:50:56:b2:78:69], start_time=1514568131.621984, duration=0.000553, service={\x0a\x0a}, history=Dd, uid=CHhAvVGS1DHFjwGM9, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>]\x0a\x09[rpc_stat=RPC_SUCCESS, mnt_stat=MOUNT3::MNT3_OK, req_start=1514568131.62212, req_dur=0.0, req_len=96, rep_start=1514568131.622537, rep_dur=0.0, rep_len=52, rpc_uid=0, rpc_gid=0, rpc_stamp=19078341, rpc_machine_name=pddevbal802, rpc_auxgids=[0, 5, 10, 24]]\x0a\x09[dirname=/pddevbal801]\x0a\x09[dirfh=\x01\x00\x06\x00\xea,\xbbJ\x9e\xf7I\x95\xa56V(\xce\xda`\xa2, auth_flavors=[MOUNT3::AUTH_UNIX]]\x0a
mount_proc_umnt: [id=[orig_h=10.111.131.18, orig_p=1016/udp, resp_h=10.111.131.132, resp_p=20048/udp], orig=[size=92, state=1, num_pkts=1, num_bytes_ip=120, flow_label=0, l2_addr=00:50:56:b2:4e:d3], resp=[size=24, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0, l2_addr=00:50:56:b2:78:69], start_time=1514568131.665918, duration=0.000266, service={\x0a\x0a}, history=Dd, uid=ClEkJM2Vm5giqnMf4h, tunnel=<uninitialized>, vlan=<uninitialized>, inner_vlan=<uninitialized>]\x0a\x09[rpc_stat=RPC_SUCCESS, mnt_stat=MOUNT3::MNT3_OK, req_start=1514568131.665918, req_dur=0.0, req_len=84, rep_start=1514568131.666184, rep_dur=0.0, rep_len=16, rpc_uid=0, rpc_gid=0, rpc_stamp=1514568131, rpc_machine_name=pddevbal802, rpc_auxgids=[0]]\x0a\x09[dirname=/pddevbal801]\x0a

Binary file not shown.

View file

@ -0,0 +1,31 @@
# @TEST-EXEC: bro -b -r $TRACES/mount/mount_base.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
global mount_ports: set[port] = { 635/tcp, 635/udp, 20048/tcp, 20048/udp } &redef;
redef ignore_checksums = T;
event bro_init()
{
Analyzer::register_for_ports(Analyzer::ANALYZER_MOUNT, mount_ports);
Analyzer::enable_analyzer(Analyzer::ANALYZER_MOUNT);
}
event mount_proc_mnt(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t, rep: MOUNT3::mnt_reply_t)
{
print(fmt("mount_proc_mnt: %s\n\t%s\n\t%s\n\t%s\n", c, info, req, rep));
}
event mount_proc_umnt(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t)
{
print(fmt("mount_proc_umnt: %s\n\t%s\n\t%s\n", c, info, req));
}
event mount_proc_umnt_all(c: connection, info: MOUNT3::info_t, req: MOUNT3::dirmntargs_t)
{
print(fmt("mount_proc_umnt_all: %s\n\t%s\n\t%s\n", c, info, req));
}
event mount_proc_not_implemented(c: connection, info: MOUNT3::info_t, proc: MOUNT3::proc_t)
{
print(fmt("mount_proc_not_implemented: %s\n\t%s\n\t%s\n", c, info, proc));
}