00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include "NetVar.h"
00025 #include "XDR.h"
00026 #include "NFS.h"
00027 #include "Event.h"
00028
00029 #define NFS_PROC_NULL 0
00030 #define NFS_PROC_GETATTR 1
00031 #define NFS_PROC_SETATTR 2
00032 #define NFS_PROC_LOOKUP 3
00033 #define NFS_PROC_READ 6
00034 #define NFS_PROC_WRITE 7
00035 #define NFS_PROC_FSSTAT 18
00036
00037 int NFS_Interp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n)
00038 {
00039 if ( c->Program() != 100003 )
00040 Weird("bad_RPC_program");
00041
00042 uint32 proc = c->Proc();
00043 switch ( proc ) {
00044 case NFS_PROC_NULL:
00045 break;
00046
00047 case NFS_PROC_GETATTR:
00048 {
00049 Val* v = ExtractFH(buf, n);
00050 if ( ! v )
00051 return 0;
00052 c->AddVal(v);
00053 }
00054 break;
00055
00056 case NFS_PROC_LOOKUP:
00057 {
00058 StringVal* fh = ExtractFH(buf, n);
00059
00060 int name_len;
00061 const u_char* name = extract_XDR_opaque(buf, n, name_len);
00062
00063 if ( ! fh || ! name )
00064 return 0;
00065
00066 RecordVal* args = new RecordVal(nfs3_lookup_args);
00067 args->Assign(0, fh);
00068 args->Assign(1, new StringVal(new BroString(name, name_len, 0)));
00069 c->AddVal(args);
00070 }
00071 break;
00072
00073 case NFS_PROC_FSSTAT:
00074 {
00075 Val* v = ExtractFH(buf, n);
00076 if ( ! v )
00077 return 0;
00078 c->AddVal(v);
00079 }
00080 break;
00081
00082 case NFS_PROC_READ:
00083 break;
00084
00085 default:
00086 Weird(fmt("unknown_NFS_request(%u)", proc));
00087
00088
00089
00090 return 1;
00091 }
00092
00093 return 1;
00094 }
00095
00096 int NFS_Interp::RPC_BuildReply(const RPC_CallInfo* c, int success,
00097 const u_char*& buf, int& n,
00098 EventHandlerPtr& event, Val*& reply)
00099 {
00100 reply = 0;
00101 uint32 status = 0;
00102 if ( success )
00103 {
00104 if ( n >= 4 )
00105 status = extract_XDR_uint32(buf, n);
00106 else
00107 status = 0xffffffff;
00108 }
00109
00110 if ( nfs_reply_status )
00111 {
00112 val_list* vl = new val_list;
00113 vl->append(Conn()->BuildConnVal());
00114 vl->append(new Val(status, TYPE_COUNT));
00115 Conn()->ConnectionEvent(nfs_reply_status, vl);
00116 }
00117
00118 switch ( c->Proc() ) {
00119 case NFS_PROC_NULL:
00120 event = success ? nfs_request_null : nfs_attempt_null;
00121 break;
00122
00123 case NFS_PROC_GETATTR:
00124 if ( success )
00125 {
00126 if ( ! buf || status != 0 )
00127 return 0;
00128
00129 reply = ExtractAttrs(buf, n);
00130 event = nfs_request_getattr;
00131 }
00132 else
00133 event = nfs_attempt_getattr;
00134
00135 break;
00136
00137 case NFS_PROC_LOOKUP:
00138 if ( success )
00139 {
00140 if ( ! buf || status != 0 )
00141 return 0;
00142
00143 RecordVal* r = new RecordVal(nfs3_lookup_reply);
00144 r->Assign(0, ExtractFH(buf, n));
00145 r->Assign(1, ExtractOptAttrs(buf, n));
00146 r->Assign(2, ExtractOptAttrs(buf, n));
00147
00148 reply = r;
00149 event = nfs_request_lookup;
00150 }
00151 else
00152 {
00153 reply = ExtractOptAttrs(buf, n);
00154 event = nfs_attempt_lookup;
00155 }
00156
00157 break;
00158
00159 case NFS_PROC_FSSTAT:
00160 if ( success )
00161 {
00162 if ( ! buf || status != 0 )
00163 return 0;
00164
00165 RecordVal* r = new RecordVal(nfs3_fsstat);
00166 r->Assign(0, ExtractOptAttrs(buf, n));
00167 r->Assign(1, ExtractLongAsDouble(buf, n));
00168 r->Assign(2, ExtractLongAsDouble(buf, n));
00169 r->Assign(3, ExtractLongAsDouble(buf, n));
00170 r->Assign(4, ExtractLongAsDouble(buf, n));
00171 r->Assign(5, ExtractLongAsDouble(buf, n));
00172 r->Assign(6, ExtractLongAsDouble(buf, n));
00173 r->Assign(7, ExtractInterval(buf, n));
00174
00175 reply = r;
00176 event = nfs_request_fsstat;
00177 }
00178 else
00179 {
00180 reply = ExtractOptAttrs(buf, n);
00181 event = nfs_attempt_fsstat;
00182 }
00183
00184 break;
00185
00186 default:
00187 return 0;
00188 }
00189
00190 return 1;
00191 }
00192
00193 StringVal* NFS_Interp::ExtractFH(const u_char*& buf, int& n)
00194 {
00195 int fh_n;
00196 const u_char* fh = extract_XDR_opaque(buf, n, fh_n, 64);
00197
00198 if ( ! fh )
00199 return 0;
00200
00201 return new StringVal(new BroString(fh, fh_n, 0));
00202 }
00203
00204 RecordVal* NFS_Interp::ExtractAttrs(const u_char*& buf, int& n)
00205 {
00206 RecordVal* attrs = new RecordVal(nfs3_attrs);
00207 attrs->Assign(0, ExtractCount(buf, n));
00208 attrs->Assign(1, ExtractCount(buf, n));
00209 attrs->Assign(2, ExtractCount(buf, n));
00210 attrs->Assign(3, ExtractCount(buf, n));
00211 attrs->Assign(4, ExtractCount(buf, n));
00212 attrs->Assign(5, ExtractLongAsDouble(buf, n));
00213 attrs->Assign(6, ExtractLongAsDouble(buf, n));
00214 attrs->Assign(7, ExtractCount(buf, n));
00215 attrs->Assign(8, ExtractCount(buf, n));
00216 attrs->Assign(9, ExtractLongAsDouble(buf, n));
00217 attrs->Assign(10, ExtractLongAsDouble(buf, n));
00218 attrs->Assign(11, ExtractTime(buf, n));
00219 attrs->Assign(12, ExtractTime(buf, n));
00220 attrs->Assign(13, ExtractTime(buf, n));
00221
00222 return attrs;
00223 }
00224
00225 RecordVal* NFS_Interp::ExtractOptAttrs(const u_char*& buf, int& n)
00226 {
00227 int have_attrs = extract_XDR_uint32(buf, n);
00228
00229 if ( buf && have_attrs )
00230 return ExtractAttrs(buf, n);
00231
00232 else
00233 return 0;
00234 }
00235
00236 Val* NFS_Interp::ExtractCount(const u_char*& buf, int& n)
00237 {
00238 return new Val(extract_XDR_uint32(buf, n), TYPE_COUNT);
00239 }
00240
00241 Val* NFS_Interp::ExtractLongAsDouble(const u_char*& buf, int& n)
00242 {
00243 return new Val(extract_XDR_uint64_as_double(buf, n), TYPE_DOUBLE);
00244 }
00245
00246 Val* NFS_Interp::ExtractTime(const u_char*& buf, int& n)
00247 {
00248 return new Val(extract_XDR_time(buf, n), TYPE_TIME);
00249 }
00250
00251 Val* NFS_Interp::ExtractInterval(const u_char*& buf, int& n)
00252 {
00253 return new IntervalVal(double(extract_XDR_uint32(buf, n)), 1.0);
00254 }
00255
00256 void NFS_Interp::Event(EventHandlerPtr f, Val* request, int status, Val* reply)
00257 {
00258 if ( ! f )
00259 {
00260 Unref(request);
00261 Unref(reply);
00262 return;
00263 }
00264
00265 val_list* vl = new val_list;
00266
00267 vl->append(conn->BuildConnVal());
00268 if ( status == RPC_SUCCESS )
00269 {
00270 if ( request )
00271 vl->append(request);
00272 if ( reply )
00273 vl->append(reply);
00274 }
00275 else
00276 {
00277 vl->append(new Val(status, TYPE_COUNT));
00278 if ( request )
00279 vl->append(request);
00280 }
00281
00282 conn->ConnectionEvent(f, vl);
00283 }
00284
00285 NFS_Conn::NFS_Conn(NetSessions* s, HashKey* k, double t,
00286 const ConnID* id, const struct tcphdr* tp)
00287 : TCP_Connection(s, k, t, id, tp)
00288 {
00289 interp = new NFS_Interp(this);
00290 orig_rpc = resp_rpc = 0;
00291 }
00292
00293 void NFS_Conn::BuildEndpoints()
00294 {
00295 orig_rpc = new TCP_Contents_RPC(interp, orig);
00296 resp_rpc = new TCP_Contents_RPC(interp, resp);
00297
00298 orig->AddContentsProcessor(orig_rpc);
00299 resp->AddContentsProcessor(resp_rpc);
00300 }
00301
00302 NFS_Conn::~NFS_Conn()
00303 {
00304 delete interp;
00305 }
00306
00307 void NFS_Conn::Done()
00308 {
00309 if ( orig_rpc->State() != RPC_COMPLETE &&
00310 (orig->state == TCP_CLOSED || orig->prev_state == TCP_CLOSED) &&
00311
00312
00313
00314 orig->Size() > 0 )
00315 Weird("partial_NFS_request");
00316
00317 interp->Timeout();
00318
00319 TCP_Connection::Done();
00320 }