Initial import of svn+ssh:://svn.icir.org/bro/trunk/bro as of r7088

This commit is contained in:
Robin Sommer 2010-09-27 20:42:30 -07:00
commit 61757ac78b
1383 changed files with 380824 additions and 0 deletions

287
src/NFS.cc Normal file
View file

@ -0,0 +1,287 @@
// $Id: NFS.cc 6219 2008-10-01 05:39:07Z vern $
//
// See the file "COPYING" in the main distribution directory for copyright.
#include "config.h"
#include "NetVar.h"
#include "XDR.h"
#include "NFS.h"
#include "Event.h"
#define NFS_PROC_NULL 0
#define NFS_PROC_GETATTR 1
#define NFS_PROC_SETATTR 2
#define NFS_PROC_LOOKUP 3
#define NFS_PROC_READ 6
#define NFS_PROC_WRITE 7
#define NFS_PROC_FSSTAT 18
int NFS_Interp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n)
{
if ( c->Program() != 100003 )
Weird("bad_RPC_program");
uint32 proc = c->Proc();
switch ( proc ) {
case NFS_PROC_NULL:
break;
case NFS_PROC_GETATTR:
{
Val* v = ExtractFH(buf, n);
if ( ! v )
return 0;
c->AddVal(v);
}
break;
case NFS_PROC_LOOKUP:
{
StringVal* fh = ExtractFH(buf, n);
int name_len;
const u_char* name = extract_XDR_opaque(buf, n, name_len);
if ( ! fh || ! name )
return 0;
RecordVal* args = new RecordVal(nfs3_lookup_args);
args->Assign(0, fh);
args->Assign(1, new StringVal(new BroString(name, name_len, 0)));
c->AddVal(args);
}
break;
case NFS_PROC_FSSTAT:
{
Val* v = ExtractFH(buf, n);
if ( ! v )
return 0;
c->AddVal(v);
}
break;
case NFS_PROC_READ:
break;
default:
Weird(fmt("unknown_NFS_request(%u)", proc));
// Return 1 so that replies to unprocessed calls will still
// be processed, and the return status extracted
return 1;
}
return 1;
}
int NFS_Interp::RPC_BuildReply(const RPC_CallInfo* c, int success,
const u_char*& buf, int& n,
EventHandlerPtr& event, Val*& reply)
{
reply = 0;
uint32 status = 0;
if ( success )
{
if ( n >= 4 )
status = extract_XDR_uint32(buf, n);
else
status = 0xffffffff;
}
if ( nfs_reply_status )
{
val_list* vl = new val_list;
vl->append(analyzer->BuildConnVal());
vl->append(new Val(status, TYPE_COUNT));
analyzer->ConnectionEvent(nfs_reply_status, vl);
}
switch ( c->Proc() ) {
case NFS_PROC_NULL:
event = success ? nfs_request_null : nfs_attempt_null;
break;
case NFS_PROC_GETATTR:
if ( success )
{
if ( ! buf || status != 0 )
return 0;
reply = ExtractAttrs(buf, n);
event = nfs_request_getattr;
}
else
event = nfs_attempt_getattr;
break;
case NFS_PROC_LOOKUP:
if ( success )
{
if ( ! buf || status != 0 )
return 0;
RecordVal* r = new RecordVal(nfs3_lookup_reply);
r->Assign(0, ExtractFH(buf, n));
r->Assign(1, ExtractOptAttrs(buf, n));
r->Assign(2, ExtractOptAttrs(buf, n));
reply = r;
event = nfs_request_lookup;
}
else
{
reply = ExtractOptAttrs(buf, n);
event = nfs_attempt_lookup;
}
break;
case NFS_PROC_FSSTAT:
if ( success )
{
if ( ! buf || status != 0 )
return 0;
RecordVal* r = new RecordVal(nfs3_fsstat);
r->Assign(0, ExtractOptAttrs(buf, n));
r->Assign(1, ExtractLongAsDouble(buf, n)); // tbytes
r->Assign(2, ExtractLongAsDouble(buf, n)); // fbytes
r->Assign(3, ExtractLongAsDouble(buf, n)); // abytes
r->Assign(4, ExtractLongAsDouble(buf, n)); // tfiles
r->Assign(5, ExtractLongAsDouble(buf, n)); // ffiles
r->Assign(6, ExtractLongAsDouble(buf, n)); // afiles
r->Assign(7, ExtractInterval(buf, n)); // invarsec
reply = r;
event = nfs_request_fsstat;
}
else
{
reply = ExtractOptAttrs(buf, n);
event = nfs_attempt_fsstat;
}
break;
default:
return 0;
}
return 1;
}
StringVal* NFS_Interp::ExtractFH(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));
}
RecordVal* NFS_Interp::ExtractAttrs(const u_char*& buf, int& n)
{
RecordVal* attrs = new RecordVal(nfs3_attrs);
attrs->Assign(0, ExtractCount(buf, n)); // file type
attrs->Assign(1, ExtractCount(buf, n)); // mode
attrs->Assign(2, ExtractCount(buf, n)); // nlink
attrs->Assign(3, ExtractCount(buf, n)); // uid
attrs->Assign(4, ExtractCount(buf, n)); // gid
attrs->Assign(5, ExtractLongAsDouble(buf, n)); // size
attrs->Assign(6, ExtractLongAsDouble(buf, n)); // used
attrs->Assign(7, ExtractCount(buf, n)); // rdev1
attrs->Assign(8, ExtractCount(buf, n)); // rdev2
attrs->Assign(9, ExtractLongAsDouble(buf, n)); // fsid
attrs->Assign(10, ExtractLongAsDouble(buf, n)); // fileid
attrs->Assign(11, ExtractTime(buf, n)); // atime
attrs->Assign(12, ExtractTime(buf, n)); // mtime
attrs->Assign(13, ExtractTime(buf, n)); // ctime
return attrs;
}
RecordVal* NFS_Interp::ExtractOptAttrs(const u_char*& buf, int& n)
{
int have_attrs = extract_XDR_uint32(buf, n);
RecordVal* opt_attrs = new RecordVal(nfs3_opt_attrs);
if ( buf && have_attrs )
opt_attrs->Assign(0, ExtractAttrs(buf, n));
else
opt_attrs->Assign(0, 0);
return opt_attrs;
}
Val* NFS_Interp::ExtractCount(const u_char*& buf, int& n)
{
return new Val(extract_XDR_uint32(buf, n), TYPE_COUNT);
}
Val* NFS_Interp::ExtractLongAsDouble(const u_char*& buf, int& n)
{
return new Val(extract_XDR_uint64_as_double(buf, n), TYPE_DOUBLE);
}
Val* NFS_Interp::ExtractTime(const u_char*& buf, int& n)
{
return new Val(extract_XDR_time(buf, n), TYPE_TIME);
}
Val* NFS_Interp::ExtractInterval(const u_char*& buf, int& n)
{
return new IntervalVal(double(extract_XDR_uint32(buf, n)), 1.0);
}
void NFS_Interp::Event(EventHandlerPtr f, Val* request, int status, Val* reply)
{
if ( ! f )
{
Unref(request);
Unref(reply);
return;
}
val_list* vl = new val_list;
vl->append(analyzer->BuildConnVal());
if ( status == RPC_SUCCESS )
{
if ( request )
vl->append(request);
if ( reply )
vl->append(reply);
}
else
{
vl->append(new Val(status, TYPE_COUNT));
if ( request )
vl->append(request);
}
analyzer->ConnectionEvent(f, vl);
}
NFS_Analyzer::NFS_Analyzer(Connection* conn)
: RPC_Analyzer(AnalyzerTag::NFS, conn, new NFS_Interp(this))
{
orig_rpc = resp_rpc = 0;
}
void NFS_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);
}
}