Branch data Line data Source code
1 : : // $Id: NFS.cc 6219 2008-10-01 05:39:07Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include "NetVar.h"
8 : : #include "XDR.h"
9 : : #include "NFS.h"
10 : : #include "Event.h"
11 : :
12 : : #define NFS_PROC_NULL 0
13 : : #define NFS_PROC_GETATTR 1
14 : : #define NFS_PROC_SETATTR 2
15 : : #define NFS_PROC_LOOKUP 3
16 : : #define NFS_PROC_READ 6
17 : : #define NFS_PROC_WRITE 7
18 : : #define NFS_PROC_FSSTAT 18
19 : :
20 : 0 : int NFS_Interp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n)
21 : : {
22 [ # # ]: 0 : if ( c->Program() != 100003 )
23 : 0 : Weird("bad_RPC_program");
24 : :
25 : 0 : uint32 proc = c->Proc();
26 [ # # # # # : 0 : switch ( proc ) {
# ]
27 : : case NFS_PROC_NULL:
28 : 0 : break;
29 : :
30 : : case NFS_PROC_GETATTR:
31 : : {
32 : 0 : Val* v = ExtractFH(buf, n);
33 [ # # ]: 0 : if ( ! v )
34 : 0 : return 0;
35 : 0 : c->AddVal(v);
36 : : }
37 : 0 : break;
38 : :
39 : : case NFS_PROC_LOOKUP:
40 : : {
41 : 0 : StringVal* fh = ExtractFH(buf, n);
42 : :
43 : : int name_len;
44 : 0 : const u_char* name = extract_XDR_opaque(buf, n, name_len);
45 : :
46 [ # # # # ]: 0 : if ( ! fh || ! name )
47 : 0 : return 0;
48 : :
49 : 0 : RecordVal* args = new RecordVal(nfs3_lookup_args);
50 : 0 : args->Assign(0, fh);
51 : 0 : args->Assign(1, new StringVal(new BroString(name, name_len, 0)));
52 : 0 : c->AddVal(args);
53 : : }
54 : 0 : break;
55 : :
56 : : case NFS_PROC_FSSTAT:
57 : : {
58 : 0 : Val* v = ExtractFH(buf, n);
59 [ # # ]: 0 : if ( ! v )
60 : 0 : return 0;
61 : 0 : c->AddVal(v);
62 : : }
63 : 0 : break;
64 : :
65 : : case NFS_PROC_READ:
66 : 0 : break;
67 : :
68 : : default:
69 : 0 : Weird(fmt("unknown_NFS_request(%u)", proc));
70 : :
71 : : // Return 1 so that replies to unprocessed calls will still
72 : : // be processed, and the return status extracted
73 : 0 : return 1;
74 : : }
75 : :
76 : 0 : return 1;
77 : : }
78 : :
79 : : int NFS_Interp::RPC_BuildReply(const RPC_CallInfo* c, int success,
80 : : const u_char*& buf, int& n,
81 : 0 : EventHandlerPtr& event, Val*& reply)
82 : : {
83 : 0 : reply = 0;
84 : 0 : uint32 status = 0;
85 [ # # ]: 0 : if ( success )
86 : : {
87 [ # # ]: 0 : if ( n >= 4 )
88 : 0 : status = extract_XDR_uint32(buf, n);
89 : : else
90 : 0 : status = 0xffffffff;
91 : : }
92 : :
93 [ # # ]: 0 : if ( nfs_reply_status )
94 : : {
95 : 0 : val_list* vl = new val_list;
96 : 0 : vl->append(analyzer->BuildConnVal());
97 : 0 : vl->append(new Val(status, TYPE_COUNT));
98 : 0 : analyzer->ConnectionEvent(nfs_reply_status, vl);
99 : : }
100 : :
101 [ # # # # : 0 : switch ( c->Proc() ) {
# ]
102 : : case NFS_PROC_NULL:
103 [ # # ]: 0 : event = success ? nfs_request_null : nfs_attempt_null;
104 : 0 : break;
105 : :
106 : : case NFS_PROC_GETATTR:
107 [ # # ]: 0 : if ( success )
108 : : {
109 [ # # ][ # # ]: 0 : if ( ! buf || status != 0 )
110 : 0 : return 0;
111 : :
112 : 0 : reply = ExtractAttrs(buf, n);
113 : 0 : event = nfs_request_getattr;
114 : : }
115 : : else
116 : 0 : event = nfs_attempt_getattr;
117 : :
118 : 0 : break;
119 : :
120 : : case NFS_PROC_LOOKUP:
121 [ # # ]: 0 : if ( success )
122 : : {
123 [ # # ][ # # ]: 0 : if ( ! buf || status != 0 )
124 : 0 : return 0;
125 : :
126 : 0 : RecordVal* r = new RecordVal(nfs3_lookup_reply);
127 : 0 : r->Assign(0, ExtractFH(buf, n));
128 : 0 : r->Assign(1, ExtractOptAttrs(buf, n));
129 : 0 : r->Assign(2, ExtractOptAttrs(buf, n));
130 : :
131 : 0 : reply = r;
132 : 0 : event = nfs_request_lookup;
133 : : }
134 : : else
135 : : {
136 : 0 : reply = ExtractOptAttrs(buf, n);
137 : 0 : event = nfs_attempt_lookup;
138 : : }
139 : :
140 : 0 : break;
141 : :
142 : : case NFS_PROC_FSSTAT:
143 [ # # ]: 0 : if ( success )
144 : : {
145 [ # # ][ # # ]: 0 : if ( ! buf || status != 0 )
146 : 0 : return 0;
147 : :
148 : 0 : RecordVal* r = new RecordVal(nfs3_fsstat);
149 : 0 : r->Assign(0, ExtractOptAttrs(buf, n));
150 : 0 : r->Assign(1, ExtractLongAsDouble(buf, n)); // tbytes
151 : 0 : r->Assign(2, ExtractLongAsDouble(buf, n)); // fbytes
152 : 0 : r->Assign(3, ExtractLongAsDouble(buf, n)); // abytes
153 : 0 : r->Assign(4, ExtractLongAsDouble(buf, n)); // tfiles
154 : 0 : r->Assign(5, ExtractLongAsDouble(buf, n)); // ffiles
155 : 0 : r->Assign(6, ExtractLongAsDouble(buf, n)); // afiles
156 : 0 : r->Assign(7, ExtractInterval(buf, n)); // invarsec
157 : :
158 : 0 : reply = r;
159 : 0 : event = nfs_request_fsstat;
160 : : }
161 : : else
162 : : {
163 : 0 : reply = ExtractOptAttrs(buf, n);
164 : 0 : event = nfs_attempt_fsstat;
165 : : }
166 : :
167 : 0 : break;
168 : :
169 : : default:
170 : 0 : return 0;
171 : : }
172 : :
173 : 0 : return 1;
174 : : }
175 : :
176 : 0 : StringVal* NFS_Interp::ExtractFH(const u_char*& buf, int& n)
177 : : {
178 : : int fh_n;
179 : 0 : const u_char* fh = extract_XDR_opaque(buf, n, fh_n, 64);
180 : :
181 [ # # ]: 0 : if ( ! fh )
182 : 0 : return 0;
183 : :
184 : 0 : return new StringVal(new BroString(fh, fh_n, 0));
185 : : }
186 : :
187 : 0 : RecordVal* NFS_Interp::ExtractAttrs(const u_char*& buf, int& n)
188 : : {
189 : 0 : RecordVal* attrs = new RecordVal(nfs3_attrs);
190 : 0 : attrs->Assign(0, ExtractCount(buf, n)); // file type
191 : 0 : attrs->Assign(1, ExtractCount(buf, n)); // mode
192 : 0 : attrs->Assign(2, ExtractCount(buf, n)); // nlink
193 : 0 : attrs->Assign(3, ExtractCount(buf, n)); // uid
194 : 0 : attrs->Assign(4, ExtractCount(buf, n)); // gid
195 : 0 : attrs->Assign(5, ExtractLongAsDouble(buf, n)); // size
196 : 0 : attrs->Assign(6, ExtractLongAsDouble(buf, n)); // used
197 : 0 : attrs->Assign(7, ExtractCount(buf, n)); // rdev1
198 : 0 : attrs->Assign(8, ExtractCount(buf, n)); // rdev2
199 : 0 : attrs->Assign(9, ExtractLongAsDouble(buf, n)); // fsid
200 : 0 : attrs->Assign(10, ExtractLongAsDouble(buf, n)); // fileid
201 : 0 : attrs->Assign(11, ExtractTime(buf, n)); // atime
202 : 0 : attrs->Assign(12, ExtractTime(buf, n)); // mtime
203 : 0 : attrs->Assign(13, ExtractTime(buf, n)); // ctime
204 : :
205 : 0 : return attrs;
206 : : }
207 : :
208 : 0 : RecordVal* NFS_Interp::ExtractOptAttrs(const u_char*& buf, int& n)
209 : : {
210 : 0 : int have_attrs = extract_XDR_uint32(buf, n);
211 : :
212 : 0 : RecordVal* opt_attrs = new RecordVal(nfs3_opt_attrs);
213 [ # # # # ]: 0 : if ( buf && have_attrs )
214 : 0 : opt_attrs->Assign(0, ExtractAttrs(buf, n));
215 : : else
216 : 0 : opt_attrs->Assign(0, 0);
217 : :
218 : 0 : return opt_attrs;
219 : : }
220 : :
221 : 0 : Val* NFS_Interp::ExtractCount(const u_char*& buf, int& n)
222 : : {
223 : 0 : return new Val(extract_XDR_uint32(buf, n), TYPE_COUNT);
224 : : }
225 : :
226 : 0 : Val* NFS_Interp::ExtractLongAsDouble(const u_char*& buf, int& n)
227 : : {
228 : 0 : return new Val(extract_XDR_uint64_as_double(buf, n), TYPE_DOUBLE);
229 : : }
230 : :
231 : 0 : Val* NFS_Interp::ExtractTime(const u_char*& buf, int& n)
232 : : {
233 : 0 : return new Val(extract_XDR_time(buf, n), TYPE_TIME);
234 : : }
235 : :
236 : 0 : Val* NFS_Interp::ExtractInterval(const u_char*& buf, int& n)
237 : : {
238 : 0 : return new IntervalVal(double(extract_XDR_uint32(buf, n)), 1.0);
239 : : }
240 : :
241 : 0 : void NFS_Interp::Event(EventHandlerPtr f, Val* request, int status, Val* reply)
242 : : {
243 [ # # ]: 0 : if ( ! f )
244 : : {
245 : 0 : Unref(request);
246 : 0 : Unref(reply);
247 : 0 : return;
248 : : }
249 : :
250 : 0 : val_list* vl = new val_list;
251 : :
252 : 0 : vl->append(analyzer->BuildConnVal());
253 [ # # ]: 0 : if ( status == RPC_SUCCESS )
254 : : {
255 [ # # ]: 0 : if ( request )
256 : 0 : vl->append(request);
257 [ # # ]: 0 : if ( reply )
258 : 0 : vl->append(reply);
259 : : }
260 : : else
261 : : {
262 : 0 : vl->append(new Val(status, TYPE_COUNT));
263 [ # # ]: 0 : if ( request )
264 : 0 : vl->append(request);
265 : : }
266 : :
267 : 0 : analyzer->ConnectionEvent(f, vl);
268 : : }
269 : :
270 : 0 : NFS_Analyzer::NFS_Analyzer(Connection* conn)
271 : 0 : : RPC_Analyzer(AnalyzerTag::NFS, conn, new NFS_Interp(this))
272 : : {
273 : 0 : orig_rpc = resp_rpc = 0;
274 : 0 : }
275 : :
276 : 0 : void NFS_Analyzer::Init()
277 : : {
278 : 0 : RPC_Analyzer::Init();
279 : :
280 [ # # ]: 0 : if ( Conn()->ConnTransport() == TRANSPORT_TCP )
281 : : {
282 : 0 : orig_rpc = new Contents_RPC(Conn(), true, interp);
283 : 0 : resp_rpc = new Contents_RPC(Conn(), false, interp);
284 : 0 : AddSupportAnalyzer(orig_rpc);
285 : 0 : AddSupportAnalyzer(resp_rpc);
286 : : }
287 [ + - ][ + - ]: 6 : }
|