/src/wireshark/epan/dissectors/packet-smb-pipe.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | XXX Fixme : shouldn't show [malformed frame] for long packets |
3 | | */ |
4 | | |
5 | | /* packet-smb-pipe.c |
6 | | * Routines for SMB named pipe packet dissection |
7 | | * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com> |
8 | | * significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and |
9 | | * Guy Harris 2001 |
10 | | * |
11 | | * Wireshark - Network traffic analyzer |
12 | | * By Gerald Combs <gerald@wireshark.org> |
13 | | * Copyright 1998 Gerald Combs |
14 | | * |
15 | | * Copied from packet-pop.c |
16 | | * |
17 | | * SPDX-License-Identifier: GPL-2.0-or-later |
18 | | */ |
19 | | |
20 | | #include "config.h" |
21 | | |
22 | | #include <epan/packet.h> |
23 | | #include <epan/exceptions.h> |
24 | | #include <epan/to_str.h> |
25 | | #include <epan/strutil.h> |
26 | | #include <epan/expert.h> |
27 | | #include <epan/reassemble.h> |
28 | | #include "packet-smb.h" |
29 | | #include "packet-smb-pipe.h" |
30 | | #include "packet-smb-browse.h" |
31 | | #include "packet-smb-common.h" |
32 | | #include "packet-windows-common.h" |
33 | | |
34 | | void proto_register_pipe_lanman(void); |
35 | | void proto_register_smb_pipe(void); |
36 | | |
37 | | static int proto_smb_pipe; |
38 | | static int hf_smb_pipe_function; |
39 | | static int hf_smb_pipe_priority; |
40 | | static int hf_smb_pipe_peek_available; |
41 | | static int hf_smb_pipe_peek_remaining; |
42 | | static int hf_smb_pipe_peek_status; |
43 | | static int hf_smb_pipe_getinfo_info_level; |
44 | | static int hf_smb_pipe_getinfo_output_buffer_size; |
45 | | static int hf_smb_pipe_getinfo_input_buffer_size; |
46 | | static int hf_smb_pipe_getinfo_maximum_instances; |
47 | | static int hf_smb_pipe_getinfo_current_instances; |
48 | | static int hf_smb_pipe_getinfo_pipe_name_length; |
49 | | static int hf_smb_pipe_getinfo_pipe_name; |
50 | | static int hf_smb_pipe_write_raw_bytes_written; |
51 | | static int hf_smb_pipe_fragments; |
52 | | static int hf_smb_pipe_fragment; |
53 | | static int hf_smb_pipe_fragment_overlap; |
54 | | static int hf_smb_pipe_fragment_overlap_conflict; |
55 | | static int hf_smb_pipe_fragment_multiple_tails; |
56 | | static int hf_smb_pipe_fragment_too_long_fragment; |
57 | | static int hf_smb_pipe_fragment_error; |
58 | | static int hf_smb_pipe_fragment_count; |
59 | | static int hf_smb_pipe_reassembled_in; |
60 | | static int hf_smb_pipe_reassembled_length; |
61 | | |
62 | | static int ett_smb_pipe; |
63 | | static int ett_smb_pipe_fragment; |
64 | | static int ett_smb_pipe_fragments; |
65 | | |
66 | | static const fragment_items smb_pipe_frag_items = { |
67 | | &ett_smb_pipe_fragment, |
68 | | &ett_smb_pipe_fragments, |
69 | | &hf_smb_pipe_fragments, |
70 | | &hf_smb_pipe_fragment, |
71 | | &hf_smb_pipe_fragment_overlap, |
72 | | &hf_smb_pipe_fragment_overlap_conflict, |
73 | | &hf_smb_pipe_fragment_multiple_tails, |
74 | | &hf_smb_pipe_fragment_too_long_fragment, |
75 | | &hf_smb_pipe_fragment_error, |
76 | | &hf_smb_pipe_fragment_count, |
77 | | NULL, |
78 | | &hf_smb_pipe_reassembled_length, |
79 | | /* Reassembled data field */ |
80 | | NULL, |
81 | | "fragments" |
82 | | }; |
83 | | |
84 | | static int proto_smb_lanman; |
85 | | static int hf_function_code; |
86 | | static int hf_param_desc; |
87 | | static int hf_return_desc; |
88 | | static int hf_aux_data_desc; |
89 | | static int hf_detail_level; |
90 | | static int hf_padding; |
91 | | static int hf_recv_buf_len; |
92 | | static int hf_send_buf_len; |
93 | | /* static int hf_continuation_from; */ |
94 | | static int hf_status; |
95 | | static int hf_convert; |
96 | | static int hf_param_no_descriptor; |
97 | | static int hf_data_no_descriptor; |
98 | | static int hf_data_no_recv_buffer; |
99 | | static int hf_ecount; |
100 | | static int hf_acount; |
101 | | static int hf_share; |
102 | | static int hf_share_name; |
103 | | static int hf_share_type; |
104 | | static int hf_share_comment; |
105 | | static int hf_share_permissions; |
106 | | static int hf_share_max_uses; |
107 | | static int hf_share_current_uses; |
108 | | static int hf_share_path; |
109 | | static int hf_share_password; |
110 | | static int hf_server; |
111 | | static int hf_server_name; |
112 | | static int hf_server_major; |
113 | | static int hf_server_minor; |
114 | | static int hf_server_comment; |
115 | | static int hf_abytes; |
116 | | static int hf_current_time; |
117 | | static int hf_msecs; |
118 | | static int hf_hour; |
119 | | static int hf_minute; |
120 | | static int hf_second; |
121 | | static int hf_hundredths; |
122 | | static int hf_tzoffset; |
123 | | static int hf_timeinterval; |
124 | | static int hf_day; |
125 | | static int hf_month; |
126 | | static int hf_year; |
127 | | static int hf_weekday; |
128 | | static int hf_enumeration_domain; |
129 | | static int hf_last_entry; |
130 | | static int hf_computer_name; |
131 | | static int hf_user_name; |
132 | | static int hf_group_name; |
133 | | static int hf_workstation_domain; |
134 | | static int hf_workstation_major; |
135 | | static int hf_workstation_minor; |
136 | | static int hf_logon_domain; |
137 | | static int hf_other_domains; |
138 | | static int hf_password; |
139 | | static int hf_workstation_name; |
140 | | static int hf_ustruct_size; |
141 | | static int hf_logon_code; |
142 | | static int hf_privilege_level; |
143 | | static int hf_operator_privileges; |
144 | | static int hf_num_logons; |
145 | | static int hf_bad_pw_count; |
146 | | static int hf_last_logon; |
147 | | static int hf_last_logoff; |
148 | | static int hf_logoff_time; |
149 | | static int hf_kickoff_time; |
150 | | static int hf_password_age; |
151 | | static int hf_password_can_change; |
152 | | static int hf_password_must_change; |
153 | | static int hf_script_path; |
154 | | static int hf_logoff_code; |
155 | | static int hf_duration; |
156 | | static int hf_comment; |
157 | | static int hf_user_comment; |
158 | | static int hf_full_name; |
159 | | static int hf_homedir; |
160 | | static int hf_parameters; |
161 | | static int hf_logon_server; |
162 | | static int hf_country_code; |
163 | | static int hf_workstations; |
164 | | static int hf_max_storage; |
165 | | static int hf_units_per_week; |
166 | | static int hf_logon_hours; |
167 | | static int hf_code_page; |
168 | | static int hf_new_password; |
169 | | static int hf_old_password; |
170 | | static int hf_reserved; |
171 | | static int hf_aux_data_struct_count; |
172 | | |
173 | | /* Generated from convert_proto_tree_add_text.pl */ |
174 | | static int hf_smb_pipe_stringz_param; |
175 | | static int hf_smb_pipe_string_param; |
176 | | static int hf_smb_pipe_bytes_param; |
177 | | static int hf_smb_pipe_byte_param; |
178 | | static int hf_smb_pipe_doubleword_param; |
179 | | static int hf_smb_pipe_word_param; |
180 | | |
181 | | static int ett_lanman; |
182 | | static int ett_lanman_unknown_entries; |
183 | | static int ett_lanman_unknown_entry; |
184 | | static int ett_lanman_shares; |
185 | | static int ett_lanman_share; |
186 | | static int ett_lanman_groups; |
187 | | static int ett_lanman_servers; |
188 | | static int ett_lanman_server; |
189 | | |
190 | | static expert_field ei_smb_pipe_bogus_netwkstauserlogon; |
191 | | static expert_field ei_smb_pipe_bad_type; |
192 | | |
193 | | /* |
194 | | * See |
195 | | * |
196 | | * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt |
197 | | * |
198 | | * among other documents. |
199 | | */ |
200 | | |
201 | | static const value_string status_vals[] = { |
202 | | { 0, "Success"}, |
203 | | { 5, "User has insufficient privilege"}, |
204 | | { 65, "Network access is denied"}, |
205 | | { 86, "The specified password is invalid"}, |
206 | | {SMBE_DOS_moredata, "Additional data is available"}, |
207 | | {2114, "Service is not running on the remote computer"}, |
208 | | {2123, "Supplied buffer is too small"}, |
209 | | {2141, "Server is not configured for transactions (IPC$ not shared)"}, |
210 | | {2212, "An error occurred while loading or running the logon script"}, |
211 | | {2214, "The logon was not validated by any server"}, |
212 | | {2217, "The logon server is running an older software version"}, |
213 | | {2221, "The user name was not found"}, |
214 | | {2226, "Operation not permitted on Backup Domain Controller"}, |
215 | | {2240, "The user is not allowed to logon from this computer"}, |
216 | | {2241, "The user is not allowed to logon at this time"}, |
217 | | {2242, "The user password has expired"}, |
218 | | {2243, "The password cannot be changed"}, |
219 | | {2246, "The password is too short"}, |
220 | | {0, NULL} |
221 | | }; |
222 | | |
223 | | static const value_string privilege_vals[] = { |
224 | | {0, "Guest"}, |
225 | | {1, "User"}, |
226 | | {2, "Administrator"}, |
227 | | {0, NULL} |
228 | | }; |
229 | | |
230 | | static const value_string op_privilege_vals[] = { |
231 | | {0, "Print operator"}, |
232 | | {1, "Communications operator"}, |
233 | | {2, "Server operator"}, |
234 | | {3, "Accounts operator"}, |
235 | | {0, NULL} |
236 | | }; |
237 | | |
238 | | static const value_string weekday_vals[] = { |
239 | | {0, "Sunday"}, |
240 | | {1, "Monday"}, |
241 | | {2, "Tuesday"}, |
242 | | {3, "Wednesday"}, |
243 | | {4, "Thursday"}, |
244 | | {5, "Friday"}, |
245 | | {6, "Saturday"}, |
246 | | {0, NULL} |
247 | | }; |
248 | | |
249 | | static int |
250 | | add_word_param(tvbuff_t *tvb, int offset, int count _U_, |
251 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
252 | 0 | { |
253 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
254 | 0 | offset += 2; |
255 | 0 | return offset; |
256 | 0 | } |
257 | | |
258 | | static int |
259 | | add_dword_param(tvbuff_t *tvb, int offset, int count _U_, |
260 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
261 | 0 | { |
262 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
263 | 0 | offset += 4; |
264 | 0 | return offset; |
265 | 0 | } |
266 | | |
267 | | static int |
268 | | add_bytes_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_, |
269 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
270 | 0 | { |
271 | 0 | header_field_info *hfinfo; |
272 | |
|
273 | 0 | if (hf_index > 0) { |
274 | 0 | hfinfo = proto_registrar_get_nth(hf_index); |
275 | 0 | if ((hfinfo == NULL) || |
276 | 0 | ((hfinfo->type == FT_INT8 || hfinfo->type == FT_UINT8) |
277 | 0 | && (count != 1))) { |
278 | 0 | THROW(ReportedBoundsError); |
279 | 0 | } |
280 | 0 | switch (hfinfo->type) { |
281 | | |
282 | 0 | case FT_INT8: |
283 | 0 | case FT_UINT8: |
284 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, count, |
285 | 0 | ENC_LITTLE_ENDIAN); |
286 | 0 | break; |
287 | | |
288 | 0 | case FT_STRING: |
289 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, count, |
290 | 0 | ENC_ASCII|ENC_NA); /* XXX - code page? */ |
291 | 0 | break; |
292 | | |
293 | 0 | default: |
294 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, count, |
295 | 0 | ENC_NA); |
296 | 0 | break; |
297 | 0 | } |
298 | 0 | } else { |
299 | 0 | if (count == 1) { |
300 | 0 | proto_tree_add_item(tree, hf_smb_pipe_byte_param, tvb, offset, count, ENC_LITTLE_ENDIAN); |
301 | 0 | } else { |
302 | 0 | proto_tree_add_item(tree, hf_smb_pipe_bytes_param, tvb, offset, count, ENC_NA); |
303 | 0 | } |
304 | 0 | } |
305 | 0 | offset += count; |
306 | 0 | return offset; |
307 | 0 | } |
308 | | |
309 | | static int |
310 | | add_string_param_update_parent(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_, |
311 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
312 | 0 | { |
313 | 0 | proto_item *ti, *parent_ti; |
314 | 0 | const uint8_t *str; |
315 | |
|
316 | 0 | DISSECTOR_ASSERT(hf_index > 0); |
317 | 0 | ti = proto_tree_add_item_ret_string(tree, hf_index, tvb, offset, |
318 | 0 | count, ENC_ASCII|ENC_NA, pinfo->pool, &str); |
319 | | /* XXX - code page? */ |
320 | 0 | parent_ti = proto_item_get_parent(ti); |
321 | 0 | proto_item_append_text(parent_ti, ": %s", |
322 | 0 | format_text(pinfo->pool, str, strlen(str))); |
323 | 0 | offset += count; |
324 | 0 | return offset; |
325 | 0 | } |
326 | | |
327 | | static int |
328 | | add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_, |
329 | | proto_tree *tree _U_, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
330 | 0 | { |
331 | | /* |
332 | | * This is for parameters that have descriptor entries but that |
333 | | * are, in practice, just padding. |
334 | | */ |
335 | 0 | offset += count; |
336 | 0 | return offset; |
337 | 0 | } |
338 | | |
339 | | static void |
340 | | add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_, |
341 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
342 | 0 | { |
343 | 0 | if (hf_index > 0) { |
344 | 0 | proto_tree_add_string_format_value(tree, hf_index, tvb, offset, 0, "", "(Null pointer)"); |
345 | 0 | } else { |
346 | 0 | proto_tree_add_string_format_value(tree, hf_smb_pipe_string_param, tvb, offset, 0, "", "(Null pointer)"); |
347 | 0 | } |
348 | 0 | } |
349 | | |
350 | | static int |
351 | | add_string_param(tvbuff_t *tvb, int offset, int count _U_, |
352 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
353 | 0 | { |
354 | 0 | unsigned string_len; |
355 | |
|
356 | 0 | string_len = tvb_strsize(tvb, offset); |
357 | 0 | if (hf_index > 0) { |
358 | 0 | proto_tree_add_item(tree, hf_index, tvb, offset, string_len, |
359 | 0 | ENC_ASCII|ENC_NA); /* XXX - code page? */ |
360 | 0 | } else { |
361 | 0 | proto_tree_add_item(tree, hf_smb_pipe_string_param, tvb, offset, string_len, ENC_NA|ENC_ASCII); |
362 | 0 | } |
363 | 0 | offset += string_len; |
364 | 0 | return offset; |
365 | 0 | } |
366 | | |
367 | | static const char * |
368 | | get_stringz_pointer_value(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int convert, int *cptrp, |
369 | | int *lenp) |
370 | 0 | { |
371 | 0 | int cptr; |
372 | 0 | int string_len; |
373 | | |
374 | | /* pointer to string */ |
375 | 0 | cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert; |
376 | 0 | *cptrp = cptr; |
377 | | |
378 | | /* string */ |
379 | 0 | if (tvb_offset_exists(tvb, cptr) && |
380 | 0 | (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) { |
381 | 0 | string_len++; /* include the terminating '\0' */ |
382 | 0 | *lenp = string_len; |
383 | 0 | return tvb_format_text(scope, tvb, cptr, string_len - 1); |
384 | 0 | } else |
385 | 0 | return NULL; |
386 | 0 | } |
387 | | |
388 | | static int |
389 | | add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_, |
390 | | packet_info *pinfo, proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_) |
391 | 0 | { |
392 | 0 | int cptr; |
393 | 0 | const char *string; |
394 | 0 | int string_len; |
395 | |
|
396 | 0 | string = get_stringz_pointer_value(pinfo->pool, tvb, offset, convert, &cptr, |
397 | 0 | &string_len); |
398 | 0 | offset += 4; |
399 | | |
400 | | /* string */ |
401 | 0 | if (string != NULL) { |
402 | 0 | if (hf_index > 0) { |
403 | 0 | proto_tree_add_item(tree, hf_index, tvb, cptr, |
404 | 0 | string_len, ENC_ASCII|ENC_NA); /* XXX - code page? */ |
405 | 0 | } else { |
406 | 0 | proto_tree_add_item(tree, hf_smb_pipe_stringz_param, tvb, cptr, string_len, ENC_NA|ENC_ASCII); |
407 | 0 | } |
408 | 0 | } else { |
409 | 0 | if (hf_index > 0) { |
410 | 0 | proto_tree_add_string(tree, hf_index, tvb, 0, 0, |
411 | 0 | "<String goes past end of frame>"); |
412 | 0 | } else { |
413 | 0 | proto_tree_add_string(tree, hf_smb_pipe_stringz_param, tvb, 0, 0, |
414 | 0 | "<String goes past end of frame>"); |
415 | 0 | } |
416 | 0 | } |
417 | |
|
418 | 0 | return offset; |
419 | 0 | } |
420 | | |
421 | | static int |
422 | | add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count, |
423 | | packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_) |
424 | 0 | { |
425 | 0 | int cptr; |
426 | | |
427 | | /* pointer to byte array */ |
428 | 0 | cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert; |
429 | 0 | offset += 4; |
430 | | |
431 | | /* bytes */ |
432 | 0 | if (tvb_bytes_exist(tvb, cptr, count)) { |
433 | 0 | if (hf_index > 0) { |
434 | 0 | proto_tree_add_item(tree, hf_index, tvb, cptr, |
435 | 0 | count, ENC_NA); |
436 | 0 | } else { |
437 | 0 | proto_tree_add_item(tree, hf_smb_pipe_bytes_param, tvb, cptr, count, ENC_NA); |
438 | 0 | } |
439 | 0 | } else { |
440 | 0 | if (hf_index > 0) { |
441 | 0 | proto_tree_add_bytes_format_value(tree, hf_index, tvb, 0, 0, |
442 | 0 | NULL, "<Bytes go past end of frame>"); |
443 | 0 | } else { |
444 | 0 | proto_tree_add_bytes_format_value(tree, hf_smb_pipe_bytes_param, tvb, 0, 0, |
445 | 0 | NULL, "<Bytes go past end of frame>"); |
446 | 0 | } |
447 | 0 | } |
448 | |
|
449 | 0 | return offset; |
450 | 0 | } |
451 | | |
452 | | static int |
453 | | add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo, |
454 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info) |
455 | 0 | { |
456 | 0 | smb_transact_info_t *trp = NULL; |
457 | 0 | uint16_t level; |
458 | |
|
459 | 0 | if (smb_info->sip->extra_info_type == SMB_EI_TRI) |
460 | 0 | trp = (smb_transact_info_t *)smb_info->sip->extra_info; |
461 | |
|
462 | 0 | level = tvb_get_letohs(tvb, offset); |
463 | 0 | if (!pinfo->fd->visited) |
464 | 0 | if (trp) |
465 | 0 | trp->info_level = level; /* remember this for the response */ |
466 | |
|
467 | 0 | proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level); |
468 | 0 | offset += 2; |
469 | 0 | return offset; |
470 | 0 | } |
471 | | |
472 | | static int |
473 | | add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_, |
474 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
475 | 0 | { |
476 | 0 | uint16_t WParam; |
477 | |
|
478 | 0 | WParam = tvb_get_letohs(tvb, offset); |
479 | 0 | if (WParam == 0xffff) { /* -1 */ |
480 | 0 | proto_tree_add_uint_format_value(tree, hf_index, tvb, |
481 | 0 | offset, 2, WParam, |
482 | 0 | "No limit"); |
483 | 0 | } else { |
484 | 0 | proto_tree_add_uint(tree, hf_index, tvb, |
485 | 0 | offset, 2, WParam); |
486 | 0 | } |
487 | 0 | offset += 2; |
488 | 0 | return offset; |
489 | 0 | } |
490 | | |
491 | | static int |
492 | | add_server_type(tvbuff_t *tvb, int offset, int count _U_, |
493 | | packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
494 | 0 | { |
495 | 0 | offset = dissect_smb_server_type_flags( |
496 | 0 | tvb, offset, pinfo, tree, NULL, false); |
497 | 0 | return offset; |
498 | 0 | } |
499 | | |
500 | | static int |
501 | | add_server_type_info(tvbuff_t *tvb, int offset, int count _U_, |
502 | | packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
503 | 0 | { |
504 | 0 | offset = dissect_smb_server_type_flags( |
505 | 0 | tvb, offset, pinfo, tree, NULL, true); |
506 | 0 | return offset; |
507 | 0 | } |
508 | | |
509 | | static int |
510 | | add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_, |
511 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
512 | 0 | { |
513 | 0 | nstime_t nstime; |
514 | |
|
515 | 0 | nstime.secs = tvb_get_letohl(tvb, offset); |
516 | 0 | nstime.nsecs = 0; |
517 | 0 | proto_tree_add_time_format_value(tree, hf_index, tvb, offset, 4, |
518 | 0 | &nstime, "%s", |
519 | 0 | signed_time_secs_to_str(pinfo->pool, (int32_t) nstime.secs)); |
520 | 0 | offset += 4; |
521 | 0 | return offset; |
522 | 0 | } |
523 | | |
524 | | /* |
525 | | * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but- |
526 | | * it's-local-time-not-UTC time. |
527 | | */ |
528 | | static int |
529 | | add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index, |
530 | | const char *absent_name) |
531 | 0 | { |
532 | 0 | nstime_t nstime; |
533 | 0 | struct tm *tmp; |
534 | |
|
535 | 0 | nstime.secs = tvb_get_letohl(tvb, offset); |
536 | 0 | nstime.nsecs = 0; |
537 | | /* |
538 | | * Sigh. Sometimes it appears that -1 means "unknown", and |
539 | | * sometimes it appears that 0 means "unknown", for the last |
540 | | * logoff date/time. |
541 | | */ |
542 | 0 | if (nstime.secs == -1 || nstime.secs == 0) { |
543 | 0 | proto_tree_add_time_format_value(tree, hf_index, tvb, offset, 4, |
544 | 0 | &nstime, "%s", |
545 | 0 | absent_name); |
546 | 0 | } else { |
547 | | /* |
548 | | * Run it through "gmtime()" to break it down, and then |
549 | | * run it through "mktime()" to put it back together |
550 | | * as UTC. |
551 | | */ |
552 | 0 | tmp = gmtime(&nstime.secs); |
553 | 0 | if (tmp == NULL) { |
554 | | /* |
555 | | * Can't be represented. |
556 | | */ |
557 | 0 | proto_tree_add_time_format_value(tree, hf_index, tvb, |
558 | 0 | offset, 4, &nstime, "Not representable"); |
559 | 0 | } else { |
560 | 0 | tmp->tm_isdst = -1; /* we don't know if it's DST or not */ |
561 | 0 | nstime.secs = mktime(tmp); |
562 | 0 | proto_tree_add_time(tree, hf_index, tvb, offset, 4, |
563 | 0 | &nstime); |
564 | 0 | } |
565 | 0 | } |
566 | 0 | offset += 4; |
567 | 0 | return offset; |
568 | 0 | } |
569 | | |
570 | | static int |
571 | | add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_, |
572 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
573 | 0 | { |
574 | 0 | return add_abstime_common(tvb, offset, tree, hf_index, "Never"); |
575 | 0 | } |
576 | | |
577 | | static int |
578 | | add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_, |
579 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
580 | 0 | { |
581 | 0 | return add_abstime_common(tvb, offset, tree, hf_index, "Unknown"); |
582 | 0 | } |
583 | | |
584 | | static int |
585 | | add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_, |
586 | | proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
587 | 0 | { |
588 | 0 | uint16_t nlogons; |
589 | |
|
590 | 0 | nlogons = tvb_get_letohs(tvb, offset); |
591 | 0 | if (nlogons == 0xffff) /* -1 */ |
592 | 0 | proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, 2, |
593 | 0 | nlogons, "Unknown"); |
594 | 0 | else |
595 | 0 | proto_tree_add_uint(tree, hf_index, tvb, offset, 2, nlogons); |
596 | 0 | offset += 2; |
597 | 0 | return offset; |
598 | 0 | } |
599 | | |
600 | | static int |
601 | | add_max_storage(tvbuff_t *tvb, int offset, int count _U_, |
602 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_) |
603 | 0 | { |
604 | 0 | uint32_t max_storage; |
605 | |
|
606 | 0 | max_storage = tvb_get_letohl(tvb, offset); |
607 | 0 | if (max_storage == 0xffffffff) |
608 | 0 | proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4, |
609 | 0 | max_storage, "No limit"); |
610 | 0 | else |
611 | 0 | proto_tree_add_uint(tree, hf_index, tvb, offset, 4, max_storage); |
612 | 0 | offset += 4; |
613 | 0 | return offset; |
614 | 0 | } |
615 | | |
616 | | static int |
617 | | add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_, |
618 | | proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_) |
619 | 0 | { |
620 | 0 | int cptr; |
621 | | |
622 | | /* pointer to byte array */ |
623 | 0 | cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert; |
624 | 0 | offset += 4; |
625 | | |
626 | | /* bytes */ |
627 | 0 | if (tvb_bytes_exist(tvb, cptr, count)) { |
628 | 0 | if (count == 21) { |
629 | | /* |
630 | | * The logon hours should be exactly 21 bytes long. |
631 | | * |
632 | | * XXX - should actually carve up the bits; |
633 | | * we need the units per week to do that, though. |
634 | | */ |
635 | 0 | proto_tree_add_item(tree, hf_index, tvb, cptr, count, |
636 | 0 | ENC_NA); |
637 | 0 | } else { |
638 | 0 | proto_tree_add_bytes_format_value(tree, hf_index, tvb, |
639 | 0 | cptr, count, NULL, |
640 | 0 | "%s (wrong length, should be 21, is %d", |
641 | 0 | tvb_bytes_to_str(pinfo->pool, tvb, cptr, count), count); |
642 | 0 | } |
643 | 0 | } else { |
644 | 0 | proto_tree_add_bytes_format_value(tree, hf_index, tvb, 0, 0, |
645 | 0 | NULL, "<Bytes go past end of frame>"); |
646 | 0 | } |
647 | |
|
648 | 0 | return offset; |
649 | 0 | } |
650 | | |
651 | | static int |
652 | | add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_, |
653 | | proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
654 | 0 | { |
655 | 0 | int16_t tzoffset; |
656 | |
|
657 | 0 | tzoffset = tvb_get_letohs(tvb, offset); |
658 | 0 | if (tzoffset < 0) { |
659 | 0 | proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2, |
660 | 0 | tzoffset, "%s east of UTC", |
661 | 0 | signed_time_secs_to_str(pinfo->pool, -tzoffset*60)); |
662 | 0 | } else if (tzoffset > 0) { |
663 | 0 | proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2, |
664 | 0 | tzoffset, "%s west of UTC", |
665 | 0 | signed_time_secs_to_str(pinfo->pool, tzoffset*60)); |
666 | 0 | } else { |
667 | 0 | proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2, |
668 | 0 | tzoffset, "at UTC"); |
669 | 0 | } |
670 | 0 | offset += 2; |
671 | 0 | return offset; |
672 | 0 | } |
673 | | |
674 | | static int |
675 | | add_timeinterval(tvbuff_t *tvb, int offset, int count _U_, |
676 | | packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
677 | 0 | { |
678 | 0 | uint16_t timeinterval; |
679 | |
|
680 | 0 | timeinterval = tvb_get_letohs(tvb, offset); |
681 | 0 | proto_tree_add_uint_format_value(tree, hf_timeinterval, tvb, offset, 2, |
682 | 0 | timeinterval, "%f seconds", timeinterval*.0001); |
683 | 0 | offset += 2; |
684 | 0 | return offset; |
685 | 0 | } |
686 | | |
687 | | static int |
688 | | add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_, |
689 | | proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_) |
690 | 0 | { |
691 | 0 | if (count != 54) { |
692 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bogus_netwkstauserlogon, tvb, offset, count, "Bogus NetWkstaUserLogon parameters: length is %d, should be 54", count); |
693 | 0 | offset += count; |
694 | 0 | return offset; |
695 | 0 | } |
696 | | |
697 | | /* user name */ |
698 | 0 | proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, ENC_ASCII); |
699 | 0 | offset += 21; |
700 | | |
701 | | /* pad1 */ |
702 | 0 | offset += 1; |
703 | | |
704 | | /* password */ |
705 | 0 | proto_tree_add_item(tree, hf_password, tvb, offset, 15, ENC_ASCII); |
706 | 0 | offset += 15; |
707 | | |
708 | | /* pad2 */ |
709 | 0 | offset += 1; |
710 | | |
711 | | /* workstation name */ |
712 | 0 | proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, ENC_ASCII); |
713 | 0 | offset += 16; |
714 | 0 | return offset; |
715 | 0 | } |
716 | | |
717 | | /* |
718 | | * The following data structure describes the Remote API requests we |
719 | | * understand. |
720 | | * |
721 | | * Simply fill in the number and parameter information. |
722 | | * Try to keep them in order. |
723 | | * |
724 | | * We will extend this data structure as we try to decode more. |
725 | | */ |
726 | | |
727 | | /* |
728 | | * This is a pointer to a function to process an item. |
729 | | */ |
730 | | typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *, |
731 | | int, int, smb_info_t*); |
732 | | |
733 | | /* |
734 | | * Type of an item; determines what parameter strings are valid for |
735 | | * the item. |
736 | | */ |
737 | | typedef enum { |
738 | | PARAM_NONE, /* for the end-of-list stopper */ |
739 | | PARAM_WORD, /* 'W' or 'h' - 16-bit word */ |
740 | | PARAM_DWORD, /* 'D' or 'i' - 32-bit word */ |
741 | | PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */ |
742 | | PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */ |
743 | | } param_type_t; |
744 | | |
745 | | /* |
746 | | * This structure describes an item; "hf_index" points to the index |
747 | | * for the field corresponding to that item, "func" points to the |
748 | | * function to use to add that item to the tree, and "type" is the |
749 | | * type that the item is supposed to have. |
750 | | */ |
751 | | typedef struct { |
752 | | int *hf_index; |
753 | | item_func func; |
754 | | param_type_t type; |
755 | | } item_t; |
756 | | |
757 | | /* |
758 | | * This structure describes a list of items; each list of items |
759 | | * has a corresponding detail level. |
760 | | */ |
761 | | typedef struct { |
762 | | int level; |
763 | | const item_t *item_list; |
764 | | } item_list_t; |
765 | | |
766 | | struct lanman_desc { |
767 | | int lanman_num; |
768 | | const item_t *req; |
769 | | proto_item *(*req_data_item)(tvbuff_t *, packet_info *, |
770 | | proto_tree *, int); |
771 | | int *ett_req_data; |
772 | | const item_t *req_data; |
773 | | const item_t *req_aux_data; |
774 | | const item_t *resp; |
775 | | const char *resp_data_entry_list_label; |
776 | | int *ett_data_entry_list; |
777 | | proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *, |
778 | | int); |
779 | | int *ett_resp_data_element_item; |
780 | | const item_list_t *resp_data_list; |
781 | | const item_t *resp_aux_data; |
782 | | }; |
783 | | |
784 | | static int no_hf = -1; /* for padding crap */ |
785 | | |
786 | | static const item_t lm_params_req_netshareenum[] = { |
787 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
788 | | { &hf_recv_buf_len, add_word_param, PARAM_WORD }, |
789 | | { NULL, NULL, PARAM_NONE } |
790 | | }; |
791 | | |
792 | | static const item_t lm_params_resp_netshareenum[] = { |
793 | | { &hf_acount, add_word_param, PARAM_WORD }, |
794 | | { NULL, NULL, PARAM_NONE } |
795 | | }; |
796 | | |
797 | | /* |
798 | | * Create a subtree for a share. |
799 | | */ |
800 | | static proto_item * |
801 | | netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset) |
802 | 0 | { |
803 | 0 | return proto_tree_add_item(tree, hf_share, tvb, offset, -1, ENC_NA); |
804 | 0 | } |
805 | | |
806 | | static const item_t lm_null[] = { |
807 | | { NULL, NULL, PARAM_NONE } |
808 | | }; |
809 | | |
810 | | static const item_list_t lm_null_list[] = { |
811 | | { -1, lm_null } |
812 | | }; |
813 | | |
814 | | static const item_t lm_data_resp_netshareenum_1[] = { |
815 | | { &hf_share_name, add_string_param_update_parent, PARAM_BYTES }, |
816 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
817 | | { &hf_share_type, add_word_param, PARAM_WORD }, |
818 | | { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
819 | | { NULL, NULL, PARAM_NONE } |
820 | | }; |
821 | | |
822 | | static const item_list_t lm_data_resp_netshareenum[] = { |
823 | | { 1, lm_data_resp_netshareenum_1 }, |
824 | | { -1, lm_null } |
825 | | }; |
826 | | |
827 | | static const item_t lm_params_req_netsharegetinfo[] = { |
828 | | { &hf_share_name, add_string_param, PARAM_STRINGZ }, |
829 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
830 | | { NULL, NULL, PARAM_NONE } |
831 | | }; |
832 | | |
833 | | static const item_t lm_params_resp_netsharegetinfo[] = { |
834 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
835 | | { NULL, NULL, PARAM_NONE } |
836 | | }; |
837 | | |
838 | | static const item_t lm_data_resp_netsharegetinfo_0[] = { |
839 | | { &hf_share_name, add_bytes_param, PARAM_BYTES }, |
840 | | { NULL, NULL, PARAM_NONE } |
841 | | }; |
842 | | |
843 | | static const item_t lm_data_resp_netsharegetinfo_1[] = { |
844 | | { &hf_share_name, add_bytes_param, PARAM_BYTES }, |
845 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
846 | | { &hf_share_type, add_word_param, PARAM_WORD }, |
847 | | { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
848 | | { NULL, NULL, PARAM_NONE } |
849 | | }; |
850 | | |
851 | | static const item_t lm_data_resp_netsharegetinfo_2[] = { |
852 | | { &hf_share_name, add_bytes_param, PARAM_BYTES }, |
853 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
854 | | { &hf_share_type, add_word_param, PARAM_WORD }, |
855 | | { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
856 | | { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */ |
857 | | { &hf_share_max_uses, add_max_uses, PARAM_WORD }, |
858 | | { &hf_share_current_uses, add_word_param, PARAM_WORD }, |
859 | | { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ }, |
860 | | { &hf_share_password, add_bytes_param, PARAM_BYTES }, |
861 | | { NULL, NULL, PARAM_NONE } |
862 | | }; |
863 | | |
864 | | static const item_list_t lm_data_resp_netsharegetinfo[] = { |
865 | | { 0, lm_data_resp_netsharegetinfo_0 }, |
866 | | { 1, lm_data_resp_netsharegetinfo_1 }, |
867 | | { 2, lm_data_resp_netsharegetinfo_2 }, |
868 | | { -1, lm_null } |
869 | | }; |
870 | | |
871 | | static const item_t lm_params_req_netservergetinfo[] = { |
872 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
873 | | { NULL, NULL, PARAM_NONE } |
874 | | }; |
875 | | |
876 | | static const item_t lm_params_resp_netservergetinfo[] = { |
877 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
878 | | { NULL, NULL, PARAM_NONE } |
879 | | }; |
880 | | |
881 | | static const item_t lm_data_serverinfo_0[] = { |
882 | | { &hf_server_name, add_string_param_update_parent, PARAM_BYTES }, |
883 | | { NULL, NULL, PARAM_NONE } |
884 | | }; |
885 | | |
886 | | static const item_t lm_data_serverinfo_1[] = { |
887 | | { &hf_server_name, add_string_param_update_parent, PARAM_BYTES }, |
888 | | { &hf_server_major, add_bytes_param, PARAM_BYTES }, |
889 | | { &hf_server_minor, add_bytes_param, PARAM_BYTES }, |
890 | | { &no_hf, add_server_type, PARAM_DWORD }, |
891 | | { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
892 | | { NULL, NULL, PARAM_NONE } |
893 | | }; |
894 | | |
895 | | static const item_list_t lm_data_serverinfo[] = { |
896 | | { 0, lm_data_serverinfo_0 }, |
897 | | { 1, lm_data_serverinfo_1 }, |
898 | | { -1, lm_null } |
899 | | }; |
900 | | |
901 | | static const item_t lm_params_req_netusergetinfo[] = { |
902 | | { &hf_user_name, add_string_param, PARAM_STRINGZ }, |
903 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
904 | | { NULL, NULL, PARAM_NONE } |
905 | | }; |
906 | | |
907 | | static const item_t lm_params_resp_netusergetinfo[] = { |
908 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
909 | | { NULL, NULL, PARAM_NONE } |
910 | | }; |
911 | | |
912 | | static const item_t lm_data_resp_netusergetinfo_11[] = { |
913 | | { &hf_user_name, add_bytes_param, PARAM_BYTES }, |
914 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
915 | | { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
916 | | { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ }, |
917 | | { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ }, |
918 | | { &hf_privilege_level, add_word_param, PARAM_WORD }, |
919 | | { &hf_operator_privileges, add_dword_param, PARAM_DWORD }, |
920 | | { &hf_password_age, add_reltime, PARAM_DWORD }, |
921 | | { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ }, |
922 | | { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ }, |
923 | | { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD }, |
924 | | { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD }, |
925 | | { &hf_bad_pw_count, add_word_param, PARAM_WORD }, |
926 | | { &hf_num_logons, add_nlogons, PARAM_WORD }, |
927 | | { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ }, |
928 | | { &hf_country_code, add_word_param, PARAM_WORD }, |
929 | | { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ }, |
930 | | { &hf_max_storage, add_max_storage, PARAM_DWORD }, |
931 | | { &hf_units_per_week, add_word_param, PARAM_WORD }, |
932 | | { &hf_logon_hours, add_logon_hours, PARAM_BYTES }, |
933 | | { &hf_code_page, add_word_param, PARAM_WORD }, |
934 | | { NULL, NULL, PARAM_NONE } |
935 | | }; |
936 | | |
937 | | static const item_list_t lm_data_resp_netusergetinfo[] = { |
938 | | { 11, lm_data_resp_netusergetinfo_11 }, |
939 | | { -1, lm_null } |
940 | | }; |
941 | | |
942 | | static const item_t lm_params_req_netusergetgroups[] = { |
943 | | { &hf_user_name, add_string_param, PARAM_STRINGZ }, |
944 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
945 | | { NULL, NULL, PARAM_NONE } |
946 | | }; |
947 | | |
948 | | static const item_t lm_params_resp_netusergetgroups[] = { |
949 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
950 | | { NULL, NULL, PARAM_NONE } |
951 | | }; |
952 | | |
953 | | static const item_t lm_data_resp_netusergetgroups_0[] = { |
954 | | { &hf_group_name, add_bytes_param, PARAM_BYTES }, |
955 | | { NULL, NULL, PARAM_NONE } |
956 | | }; |
957 | | |
958 | | static const item_list_t lm_data_resp_netusergetgroups[] = { |
959 | | { 0, lm_data_resp_netusergetgroups_0 }, |
960 | | { -1, lm_null } |
961 | | }; |
962 | | |
963 | | /* |
964 | | * Has no detail level; make it the default. |
965 | | */ |
966 | | static const item_t lm_data_resp_netremotetod_nolevel[] = { |
967 | | { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD }, |
968 | | { &hf_msecs, add_dword_param, PARAM_DWORD }, |
969 | | { &hf_hour, add_bytes_param, PARAM_BYTES }, |
970 | | { &hf_minute, add_bytes_param, PARAM_BYTES }, |
971 | | { &hf_second, add_bytes_param, PARAM_BYTES }, |
972 | | { &hf_hundredths, add_bytes_param, PARAM_BYTES }, |
973 | | { &hf_tzoffset, add_tzoffset, PARAM_WORD }, |
974 | | { &hf_timeinterval, add_timeinterval, PARAM_WORD }, |
975 | | { &hf_day, add_bytes_param, PARAM_BYTES }, |
976 | | { &hf_month, add_bytes_param, PARAM_BYTES }, |
977 | | { &hf_year, add_word_param, PARAM_WORD }, |
978 | | { &hf_weekday, add_bytes_param, PARAM_BYTES }, |
979 | | { NULL, NULL, PARAM_NONE } |
980 | | }; |
981 | | |
982 | | static const item_list_t lm_data_resp_netremotetod[] = { |
983 | | { -1, lm_data_resp_netremotetod_nolevel }, |
984 | | }; |
985 | | |
986 | | static const item_t lm_params_req_netserverenum2[] = { |
987 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
988 | | { &no_hf, add_server_type_info, PARAM_DWORD }, |
989 | | { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ }, |
990 | | { NULL, NULL, PARAM_NONE } |
991 | | }; |
992 | | |
993 | | /* |
994 | | * Create a subtree for a server. |
995 | | */ |
996 | | static proto_item * |
997 | | netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset) |
998 | 0 | { |
999 | 0 | return proto_tree_add_item(tree, hf_server, tvb, offset, -1, ENC_NA); |
1000 | 0 | } |
1001 | | |
1002 | | static const item_t lm_params_resp_netserverenum2[] = { |
1003 | | { &hf_acount, add_word_param, PARAM_WORD }, |
1004 | | { NULL, NULL, PARAM_NONE } |
1005 | | }; |
1006 | | |
1007 | | |
1008 | | static const item_t lm_params_req_netserverenum3[] = { |
1009 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
1010 | | { &no_hf, add_server_type_info, PARAM_DWORD }, |
1011 | | { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ }, |
1012 | | { &hf_last_entry, add_string_param, PARAM_STRINGZ }, |
1013 | | { NULL, NULL, PARAM_NONE } |
1014 | | }; |
1015 | | |
1016 | | |
1017 | | static const item_t lm_params_req_netwkstagetinfo[] = { |
1018 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
1019 | | { NULL, NULL, PARAM_NONE } |
1020 | | }; |
1021 | | |
1022 | | static const item_t lm_params_resp_netwkstagetinfo[] = { |
1023 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
1024 | | { NULL, NULL, PARAM_NONE } |
1025 | | }; |
1026 | | |
1027 | | static const item_t lm_data_resp_netwkstagetinfo_10[] = { |
1028 | | { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ }, |
1029 | | { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ }, |
1030 | | { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ }, |
1031 | | { &hf_workstation_major, add_bytes_param, PARAM_BYTES }, |
1032 | | { &hf_workstation_minor, add_bytes_param, PARAM_BYTES }, |
1033 | | { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ }, |
1034 | | { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ }, |
1035 | | { NULL, NULL, PARAM_NONE } |
1036 | | }; |
1037 | | |
1038 | | static const item_list_t lm_data_resp_netwkstagetinfo[] = { |
1039 | | { 10, lm_data_resp_netwkstagetinfo_10 }, |
1040 | | { -1, lm_null } |
1041 | | }; |
1042 | | |
1043 | | static const item_t lm_params_req_netwkstauserlogon[] = { |
1044 | | { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ }, |
1045 | | { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ }, |
1046 | | { &hf_detail_level, add_detail_level, PARAM_WORD }, |
1047 | | { &no_hf, add_logon_args, PARAM_BYTES }, |
1048 | | { &hf_ustruct_size, add_word_param, PARAM_WORD }, |
1049 | | { NULL, NULL, PARAM_NONE } |
1050 | | }; |
1051 | | |
1052 | | static const item_t lm_params_resp_netwkstauserlogon[] = { |
1053 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
1054 | | { NULL, NULL, PARAM_NONE } |
1055 | | }; |
1056 | | |
1057 | | static const item_t lm_data_resp_netwkstauserlogon_1[] = { |
1058 | | { &hf_logon_code, add_word_param, PARAM_WORD }, |
1059 | | { &hf_user_name, add_bytes_param, PARAM_BYTES }, |
1060 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
1061 | | { &hf_privilege_level, add_word_param, PARAM_WORD }, |
1062 | | { &hf_operator_privileges, add_dword_param, PARAM_DWORD }, |
1063 | | { &hf_num_logons, add_nlogons, PARAM_WORD }, |
1064 | | { &hf_bad_pw_count, add_word_param, PARAM_WORD }, |
1065 | | { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD }, |
1066 | | { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD }, |
1067 | | { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD }, |
1068 | | { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD }, |
1069 | | { &hf_password_age, add_reltime, PARAM_DWORD }, |
1070 | | { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD }, |
1071 | | { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD }, |
1072 | | { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ }, |
1073 | | { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ }, |
1074 | | { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ }, |
1075 | | { &hf_reserved, add_dword_param, PARAM_DWORD }, |
1076 | | { NULL, NULL, PARAM_NONE } |
1077 | | }; |
1078 | | |
1079 | | static const item_list_t lm_data_resp_netwkstauserlogon[] = { |
1080 | | { 1, lm_data_resp_netwkstauserlogon_1 }, |
1081 | | { -1, lm_null } |
1082 | | }; |
1083 | | |
1084 | | static const item_t lm_params_req_netwkstauserlogoff[] = { |
1085 | | { &hf_user_name, add_bytes_param, PARAM_BYTES }, |
1086 | | { &no_hf, add_pad_param, PARAM_BYTES }, |
1087 | | { &hf_workstation_name, add_bytes_param, PARAM_BYTES }, |
1088 | | { NULL, NULL, PARAM_NONE } |
1089 | | }; |
1090 | | |
1091 | | static const item_t lm_params_resp_netwkstauserlogoff[] = { |
1092 | | { &hf_abytes, add_word_param, PARAM_WORD }, |
1093 | | { NULL, NULL, PARAM_NONE } |
1094 | | }; |
1095 | | |
1096 | | static const item_t lm_data_resp_netwkstauserlogoff_1[] = { |
1097 | | { &hf_logoff_code, add_word_param, PARAM_WORD }, |
1098 | | { &hf_duration, add_reltime, PARAM_DWORD }, |
1099 | | { &hf_num_logons, add_nlogons, PARAM_WORD }, |
1100 | | { NULL, NULL, PARAM_NONE } |
1101 | | }; |
1102 | | |
1103 | | static const item_list_t lm_data_resp_netwkstauserlogoff[] = { |
1104 | | { 1, lm_data_resp_netwkstauserlogoff_1 }, |
1105 | | { -1, lm_null } |
1106 | | }; |
1107 | | |
1108 | | static const item_t lm_params_req_samoemchangepassword[] = { |
1109 | | { &hf_user_name, add_string_param, PARAM_STRINGZ }, |
1110 | | { NULL, NULL, PARAM_NONE } |
1111 | | }; |
1112 | | |
1113 | | static const item_t lm_data_req_samoemchangepassword[] = { |
1114 | | { &hf_new_password, add_bytes_param, PARAM_BYTES }, |
1115 | | { &hf_old_password, add_bytes_param, PARAM_BYTES }, |
1116 | | { NULL, NULL, PARAM_NONE } |
1117 | | }; |
1118 | | |
1119 | | #define API_NetShareEnum 0 |
1120 | | #define API_NetShareGetInfo 1 |
1121 | | #define API_NetShareSetInfo 2 |
1122 | | #define API_NetShareAdd 3 |
1123 | | #define API_NetShareDel 4 |
1124 | | #define API_NetShareCheck 5 |
1125 | | #define API_NetSessionEnum 6 |
1126 | | #define API_NetSessionGetInfo 7 |
1127 | | #define API_NetSessionDel 8 |
1128 | | #define API_WconnectionEnum 9 |
1129 | | #define API_NetFileEnum 10 |
1130 | | #define API_NetFileGetInfo 11 |
1131 | | #define API_NetFileClose 12 |
1132 | | #define API_NetServerGetInfo 13 |
1133 | | #define API_NetServerSetInfo 14 |
1134 | | #define API_NetServerDiskEnum 15 |
1135 | | #define API_NetServerAdminCommand 16 |
1136 | | #define API_NetAuditOpen 17 |
1137 | | #define API_NetAuditClear 18 |
1138 | | #define API_NetErrorLogOpen 19 |
1139 | | #define API_NetErrorLogClear 20 |
1140 | | #define API_NetCharDevEnum 21 |
1141 | | #define API_NetCharDevGetInfo 22 |
1142 | | #define API_NetCharDevControl 23 |
1143 | | #define API_NetCharDevQEnum 24 |
1144 | | #define API_NetCharDevQGetInfo 25 |
1145 | | #define API_NetCharDevQSetInfo 26 |
1146 | | #define API_NetCharDevQPurge 27 |
1147 | | #define API_NetCharDevQPurgeSelf 28 |
1148 | | #define API_NetMessageNameEnum 29 |
1149 | | #define API_NetMessageNameGetInfo 30 |
1150 | | #define API_NetMessageNameAdd 31 |
1151 | | #define API_NetMessageNameDel 32 |
1152 | | #define API_NetMessageNameFwd 33 |
1153 | | #define API_NetMessageNameUnFwd 34 |
1154 | | #define API_NetMessageBufferSend 35 |
1155 | | #define API_NetMessageFileSend 36 |
1156 | | #define API_NetMessageLogFileSet 37 |
1157 | | #define API_NetMessageLogFileGet 38 |
1158 | | #define API_NetServiceEnum 39 |
1159 | | #define API_NetServiceInstall 40 |
1160 | | #define API_NetServiceControl 41 |
1161 | | #define API_NetAccessEnum 42 |
1162 | | #define API_NetAccessGetInfo 43 |
1163 | | #define API_NetAccessSetInfo 44 |
1164 | | #define API_NetAccessAdd 45 |
1165 | | #define API_NetAccessDel 46 |
1166 | | #define API_NetGroupEnum 47 |
1167 | | #define API_NetGroupAdd 48 |
1168 | | #define API_NetGroupDel 49 |
1169 | | #define API_NetGroupAddUser 50 |
1170 | | #define API_NetGroupDelUser 51 |
1171 | | #define API_NetGroupGetUsers 52 |
1172 | | #define API_NetUserEnum 53 |
1173 | | #define API_NetUserAdd 54 |
1174 | | #define API_NetUserDel 55 |
1175 | | #define API_NetUserGetInfo 56 |
1176 | | #define API_NetUserSetInfo 57 |
1177 | | #define API_NetUserPasswordSet 58 |
1178 | | #define API_NetUserGetGroups 59 |
1179 | | /*This line and number replaced a Dead Entry for 60 */ |
1180 | | /*This line and number replaced a Dead Entry for 61 */ |
1181 | | #define API_NetWkstaSetUID 62 |
1182 | | #define API_NetWkstaGetInfo 63 |
1183 | | #define API_NetWkstaSetInfo 64 |
1184 | | #define API_NetUseEnum 65 |
1185 | | #define API_NetUseAdd 66 |
1186 | | #define API_NetUseDel 67 |
1187 | | #define API_NetUseGetInfo 68 |
1188 | | #define API_WPrintQEnum 69 |
1189 | | #define API_WPrintQGetInfo 70 |
1190 | | #define API_WPrintQSetInfo 71 |
1191 | | #define API_WPrintQAdd 72 |
1192 | | #define API_WPrintQDel 73 |
1193 | | #define API_WPrintQPause 74 |
1194 | | #define API_WPrintQContinue 75 |
1195 | | #define API_WPrintJobEnum 76 |
1196 | | #define API_WPrintJobGetInfo 77 |
1197 | | #define API_WPrintJobSetInfo_OLD 78 |
1198 | | /* This line and number replaced a Dead Entry for 79 */ |
1199 | | /* This line and number replaced a Dead Entry for 80 */ |
1200 | | #define API_WPrintJobDel 81 |
1201 | | #define API_WPrintJobPause 82 |
1202 | | #define API_WPrintJobContinue 83 |
1203 | | #define API_WPrintDestEnum 84 |
1204 | | #define API_WPrintDestGetInfo 85 |
1205 | | #define API_WPrintDestControl 86 |
1206 | | #define API_NetProfileSave 87 |
1207 | | #define API_NetProfileLoad 88 |
1208 | | #define API_NetStatisticsGet 89 |
1209 | | #define API_NetStatisticsClear 90 |
1210 | | #define API_NetRemoteTOD 91 |
1211 | | #define API_WNetBiosEnum 92 |
1212 | | #define API_WNetBiosGetInfo 93 |
1213 | | #define API_NetServerEnum 94 |
1214 | | #define API_I_NetServerEnum 95 |
1215 | | #define API_NetServiceGetInfo 96 |
1216 | | /* This line and number replaced a Dead Entry for 97 */ |
1217 | | /* This line and number replaced a Dead Entry for 98 */ |
1218 | | /* This line and number replaced a Dead Entry for 99 */ |
1219 | | /* This line and number replaced a Dead Entry for 100 */ |
1220 | | /* This line and number replaced a Dead Entry for 101 */ |
1221 | | /* This line and number replaced a Dead Entry for 102 */ |
1222 | | #define API_WPrintQPurge 103 |
1223 | | #define API_NetServerEnum2 104 |
1224 | | #define API_NetAccessGetUserPerms 105 |
1225 | | #define API_NetGroupGetInfo 106 |
1226 | | #define API_NetGroupSetInfo 107 |
1227 | | #define API_NetGroupSetUsers 108 |
1228 | | #define API_NetUserSetGroups 109 |
1229 | | #define API_NetUserModalsGet 110 |
1230 | | #define API_NetUserModalsSet 111 |
1231 | | #define API_NetFileEnum2 112 |
1232 | | #define API_NetUserAdd2 113 |
1233 | | #define API_NetUserSetInfo2 114 |
1234 | | #define API_NetUserPasswordSet2 115 |
1235 | | #define API_I_NetServerEnum2 116 |
1236 | | #define API_NetConfigGet2 117 |
1237 | | #define API_NetConfigGetAll2 118 |
1238 | | #define API_NetGetDCName 119 |
1239 | | #define API_NetHandleGetInfo 120 |
1240 | | #define API_NetHandleSetInfo 121 |
1241 | | #define API_NetStatisticsGet2 122 |
1242 | | #define API_WBuildGetInfo 123 |
1243 | | #define API_NetFileGetInfo2 124 |
1244 | | #define API_NetFileClose2 125 |
1245 | | #define API_NetServerReqChallenge 126 |
1246 | | #define API_NetServerAuthenticate 127 |
1247 | | #define API_NetServerPasswordSet 128 |
1248 | | #define API_WNetAccountDeltas 129 |
1249 | | #define API_WNetAccountSync 130 |
1250 | | #define API_NetUserEnum2 131 |
1251 | | #define API_NetWkstaUserLogon 132 |
1252 | | #define API_NetWkstaUserLogoff 133 |
1253 | | #define API_NetLogonEnum 134 |
1254 | | #define API_NetErrorLogRead 135 |
1255 | | #define API_I_NetPathType 136 |
1256 | | #define API_I_NetPathCanonicalize 137 |
1257 | | #define API_I_NetPathCompare 138 |
1258 | | #define API_I_NetNameValidate 139 |
1259 | | #define API_I_NetNameCanonicalize 140 |
1260 | | #define API_I_NetNameCompare 141 |
1261 | | #define API_NetAuditRead 142 |
1262 | | #define API_WPrintDestAdd 143 |
1263 | | #define API_WPrintDestSetInfo 144 |
1264 | | #define API_WPrintDestDel 145 |
1265 | | #define API_NetUserValidate2 146 |
1266 | | #define API_WPrintJobSetInfo 147 |
1267 | | #define API_TI_NetServerDiskEnum 148 |
1268 | | #define API_TI_NetServerDiskGetInfo 149 |
1269 | | #define API_TI_FTVerifyMirror 150 |
1270 | | #define API_TI_FTAbortVerify 151 |
1271 | | #define API_TI_FTGetInfo 152 |
1272 | | #define API_TI_FTSetInfo 153 |
1273 | | #define API_TI_FTLockDisk 154 |
1274 | | #define API_TI_FTFixError 155 |
1275 | | #define API_TI_FTAbortFix 156 |
1276 | | #define API_TI_FTDiagnoseError 157 |
1277 | | #define API_TI_FTGetDriveStats 158 |
1278 | | /* This line and number replaced a Dead Entry for 159 */ |
1279 | | #define API_TI_FTErrorGetInfo 160 |
1280 | | /* This line and number replaced a Dead Entry for 161 */ |
1281 | | /* This line and number replaced a Dead Entry for 162 */ |
1282 | | #define API_NetAccessCheck 163 |
1283 | | #define API_NetAlertRaise 164 |
1284 | | #define API_NetAlertStart 165 |
1285 | | #define API_NetAlertStop 166 |
1286 | | #define API_NetAuditWrite 167 |
1287 | | #define API_NetIRemoteAPI 168 |
1288 | | #define API_NetServiceStatus 169 |
1289 | | #define API_I_NetServerRegister 170 |
1290 | | #define API_I_NetServerDeregister 171 |
1291 | | #define API_I_NetSessionEntryMake 172 |
1292 | | #define API_I_NetSessionEntryClear 173 |
1293 | | #define API_I_NetSessionEntryGetInfo 174 |
1294 | | #define API_I_NetSessionEntrySetInfo 175 |
1295 | | #define API_I_NetConnectionEntryMake 176 |
1296 | | #define API_I_NetConnectionEntryClear 177 |
1297 | | #define API_I_NetConnectionEntrySetInfo 178 |
1298 | | #define API_I_NetConnectionEntryGetInfo 179 |
1299 | | #define API_I_NetFileEntryMake 180 |
1300 | | #define API_I_NetFileEntryClear 181 |
1301 | | #define API_I_NetFileEntrySetInfo 182 |
1302 | | #define API_I_NetFileEntryGetInfo 183 |
1303 | | #define API_AltSrvMessageBufferSend 184 |
1304 | | #define API_AltSrvMessageFileSend 185 |
1305 | | #define API_wI_NetRplWkstaEnum 186 |
1306 | | #define API_wI_NetRplWkstaGetInfo 187 |
1307 | | #define API_wI_NetRplWkstaSetInfo 188 |
1308 | | #define API_wI_NetRplWkstaAdd 189 |
1309 | | #define API_wI_NetRplWkstaDel 190 |
1310 | | #define API_wI_NetRplProfileEnum 191 |
1311 | | #define API_wI_NetRplProfileGetInfo 192 |
1312 | | #define API_wI_NetRplProfileSetInfo 193 |
1313 | | #define API_wI_NetRplProfileAdd 194 |
1314 | | #define API_wI_NetRplProfileDel 195 |
1315 | | #define API_wI_NetRplProfileClone 196 |
1316 | | #define API_wI_NetRplBaseProfileEnum 197 |
1317 | | /* This line and number replaced a Dead Entry for 198 */ |
1318 | | /* This line and number replaced a Dead Entry for 199 */ |
1319 | | /* This line and number replaced a Dead Entry for 200 */ |
1320 | | #define API_WIServerSetInfo 201 |
1321 | | /* This line and number replaced a Dead Entry for 202 */ |
1322 | | /* This line and number replaced a Dead Entry for 203 */ |
1323 | | /* This line and number replaced a Dead Entry for 204 */ |
1324 | | #define API_WPrintDriverEnum 205 |
1325 | | #define API_WPrintQProcessorEnum 206 |
1326 | | #define API_WPrintPortEnum 207 |
1327 | | #define API_WNetWriteUpdateLog 208 |
1328 | | #define API_WNetAccountUpdate 209 |
1329 | | #define API_WNetAccountConfirmUpdate 210 |
1330 | | #define API_NetConfigSet 211 |
1331 | | #define API_WAccountsReplicate 212 |
1332 | | /* 213 is used by WfW */ |
1333 | | #define API_SamOEMChgPasswordUser2_P 214 |
1334 | | #define API_NetServerEnum3 215 |
1335 | | /* XXX - what about 216 through 249? */ |
1336 | | #define API_WPrintDriverGetInfo 250 |
1337 | | #define API_WPrintDriverSetInfo 251 |
1338 | | #define API_NetAliasAdd 252 |
1339 | | #define API_NetAliasDel 253 |
1340 | | #define API_NetAliasGetInfo 254 |
1341 | | #define API_NetAliasSetInfo 255 |
1342 | | #define API_NetAliasEnum 256 |
1343 | | #define API_NetUserGetLogonAsn 257 |
1344 | | #define API_NetUserSetLogonAsn 258 |
1345 | | #define API_NetUserGetAppSel 259 |
1346 | | #define API_NetUserSetAppSel 260 |
1347 | | #define API_NetAppAdd 261 |
1348 | | #define API_NetAppDel 262 |
1349 | | #define API_NetAppGetInfo 263 |
1350 | | #define API_NetAppSetInfo 264 |
1351 | | #define API_NetAppEnum 265 |
1352 | | #define API_NetUserDCDBInit 266 |
1353 | | #define API_NetDASDAdd 267 |
1354 | | #define API_NetDASDDel 268 |
1355 | | #define API_NetDASDGetInfo 269 |
1356 | | #define API_NetDASDSetInfo 270 |
1357 | | #define API_NetDASDEnum 271 |
1358 | | #define API_NetDASDCheck 272 |
1359 | | #define API_NetDASDCtl 273 |
1360 | | #define API_NetUserRemoteLogonCheck 274 |
1361 | | #define API_NetUserPasswordSet3 275 |
1362 | | #define API_NetCreateRIPLMachine 276 |
1363 | | #define API_NetDeleteRIPLMachine 277 |
1364 | | #define API_NetGetRIPLMachineInfo 278 |
1365 | | #define API_NetSetRIPLMachineInfo 279 |
1366 | | #define API_NetEnumRIPLMachine 280 |
1367 | | #define API_I_ShareAdd 281 |
1368 | | #define API_I_AliasEnum 282 |
1369 | | #define API_NetAccessApply 283 |
1370 | | #define API_WPrt16Query 284 |
1371 | | #define API_WPrt16Set 285 |
1372 | | #define API_NetUserDel100 286 |
1373 | | #define API_NetUserRemoteLogonCheck2 287 |
1374 | | #define API_WRemoteTODSet 294 |
1375 | | #define API_WPrintJobMoveAll 295 |
1376 | | #define API_W16AppParmAdd 296 |
1377 | | #define API_W16AppParmDel 297 |
1378 | | #define API_W16AppParmGet 298 |
1379 | | #define API_W16AppParmSet 299 |
1380 | | #define API_W16RIPLMachineCreate 300 |
1381 | | #define API_W16RIPLMachineGetInfo 301 |
1382 | | #define API_W16RIPLMachineSetInfo 302 |
1383 | | #define API_W16RIPLMachineEnum 303 |
1384 | | #define API_W16RIPLMachineListParmEnum 304 |
1385 | | #define API_W16RIPLMachClassGetInfo 305 |
1386 | | #define API_W16RIPLMachClassEnum 306 |
1387 | | #define API_W16RIPLMachClassCreate 307 |
1388 | | #define API_W16RIPLMachClassSetInfo 308 |
1389 | | #define API_W16RIPLMachClassDelete 309 |
1390 | | #define API_W16RIPLMachClassLPEnum 310 |
1391 | | #define API_W16RIPLMachineDelete 311 |
1392 | | #define API_W16WSLevelGetInfo 312 |
1393 | | #define API_NetServerNameAdd 313 |
1394 | | #define API_NetServerNameDel 314 |
1395 | | #define API_NetServerNameEnum 315 |
1396 | | #define API_I_WDASDEnum 316 |
1397 | | #define API_I_WDASDEnumTerminate 317 |
1398 | | #define API_I_WDASDSetInfo2 318 |
1399 | | |
1400 | | static const struct lanman_desc lmd[] = { |
1401 | | { API_NetShareEnum, |
1402 | | lm_params_req_netshareenum, |
1403 | | NULL, |
1404 | | NULL, |
1405 | | lm_null, |
1406 | | lm_null, |
1407 | | lm_params_resp_netshareenum, |
1408 | | "Available Shares", |
1409 | | &ett_lanman_shares, |
1410 | | netshareenum_share_entry, |
1411 | | &ett_lanman_share, |
1412 | | lm_data_resp_netshareenum, |
1413 | | lm_null }, |
1414 | | |
1415 | | { API_NetShareGetInfo, |
1416 | | lm_params_req_netsharegetinfo, |
1417 | | NULL, |
1418 | | NULL, |
1419 | | lm_null, |
1420 | | lm_null, |
1421 | | lm_params_resp_netsharegetinfo, |
1422 | | NULL, |
1423 | | NULL, |
1424 | | NULL, |
1425 | | NULL, |
1426 | | lm_data_resp_netsharegetinfo, |
1427 | | lm_null }, |
1428 | | |
1429 | | { API_NetServerGetInfo, |
1430 | | lm_params_req_netservergetinfo, |
1431 | | NULL, |
1432 | | NULL, |
1433 | | lm_null, |
1434 | | lm_null, |
1435 | | lm_params_resp_netservergetinfo, |
1436 | | NULL, |
1437 | | NULL, |
1438 | | NULL, |
1439 | | NULL, |
1440 | | lm_data_serverinfo, |
1441 | | lm_null }, |
1442 | | |
1443 | | { API_NetUserGetInfo, |
1444 | | lm_params_req_netusergetinfo, |
1445 | | NULL, |
1446 | | NULL, |
1447 | | lm_null, |
1448 | | lm_null, |
1449 | | lm_params_resp_netusergetinfo, |
1450 | | NULL, |
1451 | | NULL, |
1452 | | NULL, |
1453 | | NULL, |
1454 | | lm_data_resp_netusergetinfo, |
1455 | | lm_null }, |
1456 | | |
1457 | | { API_NetUserGetGroups, |
1458 | | lm_params_req_netusergetgroups, |
1459 | | NULL, |
1460 | | NULL, |
1461 | | lm_null, |
1462 | | lm_null, |
1463 | | lm_params_resp_netusergetgroups, |
1464 | | "Groups", |
1465 | | &ett_lanman_groups, |
1466 | | NULL, |
1467 | | NULL, |
1468 | | lm_data_resp_netusergetgroups, |
1469 | | lm_null }, |
1470 | | |
1471 | | { API_NetRemoteTOD, |
1472 | | lm_null, |
1473 | | NULL, |
1474 | | NULL, |
1475 | | lm_null, |
1476 | | lm_null, |
1477 | | lm_null, |
1478 | | NULL, |
1479 | | NULL, |
1480 | | NULL, |
1481 | | NULL, |
1482 | | lm_data_resp_netremotetod, |
1483 | | lm_null }, |
1484 | | |
1485 | | { API_NetServerEnum2, |
1486 | | lm_params_req_netserverenum2, |
1487 | | NULL, |
1488 | | NULL, |
1489 | | lm_null, |
1490 | | lm_null, |
1491 | | lm_params_resp_netserverenum2, |
1492 | | "Servers", |
1493 | | &ett_lanman_servers, |
1494 | | netserverenum2_server_entry, |
1495 | | &ett_lanman_server, |
1496 | | lm_data_serverinfo, |
1497 | | lm_null }, |
1498 | | |
1499 | | { API_NetWkstaGetInfo, |
1500 | | lm_params_req_netwkstagetinfo, |
1501 | | NULL, |
1502 | | NULL, |
1503 | | lm_null, |
1504 | | lm_null, |
1505 | | lm_params_resp_netwkstagetinfo, |
1506 | | NULL, |
1507 | | NULL, |
1508 | | NULL, |
1509 | | NULL, |
1510 | | lm_data_resp_netwkstagetinfo, |
1511 | | lm_null }, |
1512 | | |
1513 | | { API_NetWkstaUserLogon, |
1514 | | lm_params_req_netwkstauserlogon, |
1515 | | NULL, |
1516 | | NULL, |
1517 | | lm_null, |
1518 | | lm_null, |
1519 | | lm_params_resp_netwkstauserlogon, |
1520 | | NULL, |
1521 | | NULL, |
1522 | | NULL, |
1523 | | NULL, |
1524 | | lm_data_resp_netwkstauserlogon, |
1525 | | lm_null }, |
1526 | | |
1527 | | { API_NetWkstaUserLogoff, |
1528 | | lm_params_req_netwkstauserlogoff, |
1529 | | NULL, |
1530 | | NULL, |
1531 | | lm_null, |
1532 | | lm_null, |
1533 | | lm_params_resp_netwkstauserlogoff, |
1534 | | NULL, |
1535 | | NULL, |
1536 | | NULL, |
1537 | | NULL, |
1538 | | lm_data_resp_netwkstauserlogoff, |
1539 | | lm_null }, |
1540 | | |
1541 | | { API_SamOEMChgPasswordUser2_P, |
1542 | | lm_params_req_samoemchangepassword, |
1543 | | NULL, |
1544 | | NULL, |
1545 | | lm_data_req_samoemchangepassword, |
1546 | | lm_null, |
1547 | | lm_null, |
1548 | | NULL, |
1549 | | NULL, |
1550 | | NULL, |
1551 | | NULL, |
1552 | | lm_null_list, |
1553 | | lm_null }, |
1554 | | |
1555 | | { API_NetServerEnum3, |
1556 | | lm_params_req_netserverenum3, |
1557 | | NULL, |
1558 | | NULL, |
1559 | | lm_null, |
1560 | | lm_null, |
1561 | | lm_params_resp_netserverenum2, |
1562 | | "Servers", |
1563 | | &ett_lanman_servers, |
1564 | | netserverenum2_server_entry, |
1565 | | &ett_lanman_server, |
1566 | | lm_data_serverinfo, |
1567 | | lm_null }, |
1568 | | |
1569 | | { -1, |
1570 | | lm_null, |
1571 | | NULL, |
1572 | | NULL, |
1573 | | lm_null, |
1574 | | lm_null, |
1575 | | lm_null, |
1576 | | NULL, |
1577 | | NULL, |
1578 | | NULL, |
1579 | | &ett_lanman_unknown_entry, |
1580 | | lm_null_list, |
1581 | | lm_null } |
1582 | | }; |
1583 | | |
1584 | | static const struct lanman_desc * |
1585 | | find_lanman(int lanman_num) |
1586 | 0 | { |
1587 | 0 | int i; |
1588 | |
|
1589 | 0 | for (i = 0; lmd[i].lanman_num != -1; i++) { |
1590 | 0 | if (lmd[i].lanman_num == lanman_num) |
1591 | 0 | break; |
1592 | 0 | } |
1593 | 0 | return &lmd[i]; |
1594 | 0 | } |
1595 | | |
1596 | | static const unsigned char * |
1597 | | get_count(const unsigned char *desc, int *countp) |
1598 | 0 | { |
1599 | 0 | int count = 0; |
1600 | 0 | unsigned char c; |
1601 | |
|
1602 | 0 | if (!g_ascii_isdigit(*desc)) { |
1603 | 0 | *countp = 1; /* no count was supplied */ |
1604 | 0 | return desc; |
1605 | 0 | } |
1606 | | |
1607 | 0 | while ((c = *desc) != '\0' && g_ascii_isdigit(c)) { |
1608 | 0 | count = (count * 10) + c - '0'; |
1609 | 0 | desc++; |
1610 | 0 | } |
1611 | |
|
1612 | 0 | *countp = count; /* XXX - what if it's 0? */ |
1613 | 0 | return desc; |
1614 | 0 | } |
1615 | | |
1616 | | static int |
1617 | | dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo, |
1618 | | proto_tree *tree, const unsigned char *desc, const item_t *items, |
1619 | | bool *has_data_p, smb_info_t *smb_info) |
1620 | 0 | { |
1621 | 0 | unsigned c; |
1622 | 0 | uint16_t WParam; |
1623 | 0 | uint32_t LParam; |
1624 | 0 | unsigned string_len; |
1625 | 0 | int count; |
1626 | |
|
1627 | 0 | *has_data_p = false; |
1628 | 0 | while ((c = *desc++) != '\0') { |
1629 | 0 | switch (c) { |
1630 | | |
1631 | 0 | case 'W': |
1632 | | /* |
1633 | | * A 16-bit word value in the request. |
1634 | | */ |
1635 | 0 | if (items->func == NULL) { |
1636 | | /* |
1637 | | * We've run out of items in the table; |
1638 | | * fall back on the default. |
1639 | | */ |
1640 | 0 | offset = add_word_param(tvb, offset, 0, pinfo, |
1641 | 0 | tree, 0, hf_smb_pipe_word_param, smb_info); |
1642 | 0 | } else if (items->type != PARAM_WORD) { |
1643 | | /* |
1644 | | * Descriptor character is 'W', but this |
1645 | | * isn't a word parameter. |
1646 | | */ |
1647 | 0 | WParam = tvb_get_letohs(tvb, offset); |
1648 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
1649 | 0 | "%s: Value is %u (0x%04X), type is wrong (W)", |
1650 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1651 | 0 | hf_smb_pipe_word_param : *items->hf_index), |
1652 | 0 | WParam, WParam); |
1653 | 0 | offset += 2; |
1654 | 0 | items++; |
1655 | 0 | } else { |
1656 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
1657 | 0 | tree, 0, *items->hf_index, smb_info); |
1658 | 0 | items++; |
1659 | 0 | } |
1660 | 0 | break; |
1661 | | |
1662 | 0 | case 'D': |
1663 | | /* |
1664 | | * A 32-bit doubleword value in the request. |
1665 | | */ |
1666 | 0 | if (items->func == NULL) { |
1667 | | /* |
1668 | | * We've run out of items in the table; |
1669 | | * fall back on the default. |
1670 | | */ |
1671 | 0 | offset = add_dword_param(tvb, offset, 0, pinfo, |
1672 | 0 | tree, 0, hf_smb_pipe_doubleword_param, smb_info); |
1673 | 0 | } else if (items->type != PARAM_DWORD) { |
1674 | | /* |
1675 | | * Descriptor character is 'D', but this |
1676 | | * isn't a doubleword parameter. |
1677 | | */ |
1678 | 0 | LParam = tvb_get_letohl(tvb, offset); |
1679 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
1680 | 0 | "%s: Value is %u (0x%08X), type is wrong (D)", |
1681 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1682 | 0 | hf_smb_pipe_doubleword_param : *items->hf_index), |
1683 | 0 | LParam, LParam); |
1684 | 0 | offset += 4; |
1685 | 0 | items++; |
1686 | 0 | } else { |
1687 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
1688 | 0 | tree, 0, *items->hf_index, smb_info); |
1689 | 0 | items++; |
1690 | 0 | } |
1691 | 0 | break; |
1692 | | |
1693 | 0 | case 'b': |
1694 | | /* |
1695 | | * A byte or multi-byte value in the request. |
1696 | | */ |
1697 | 0 | desc = get_count(desc, &count); |
1698 | 0 | if (items->func == NULL) { |
1699 | | /* |
1700 | | * We've run out of items in the table; |
1701 | | * fall back on the default. |
1702 | | */ |
1703 | 0 | offset = add_bytes_param(tvb, offset, count, |
1704 | 0 | pinfo, tree, 0, -1, smb_info); |
1705 | 0 | } else if (items->type != PARAM_BYTES) { |
1706 | | /* |
1707 | | * Descriptor character is 'b', but this |
1708 | | * isn't a byte/bytes parameter. |
1709 | | */ |
1710 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count, |
1711 | 0 | "%s: Value is %s, type is wrong (b)", |
1712 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1713 | 0 | hf_smb_pipe_bytes_param : *items->hf_index), |
1714 | 0 | tvb_bytes_to_str(pinfo->pool, tvb, offset, count)); |
1715 | 0 | offset += count; |
1716 | 0 | items++; |
1717 | 0 | } else { |
1718 | 0 | offset = (*items->func)(tvb, offset, count, |
1719 | 0 | pinfo, tree, 0, *items->hf_index, smb_info); |
1720 | 0 | items++; |
1721 | 0 | } |
1722 | 0 | break; |
1723 | | |
1724 | 0 | case 'O': |
1725 | | /* |
1726 | | * A null pointer. |
1727 | | */ |
1728 | 0 | if (items->func == NULL) { |
1729 | | /* |
1730 | | * We've run out of items in the table; |
1731 | | * fall back on the default. |
1732 | | */ |
1733 | 0 | add_null_pointer_param(tvb, offset, 0, |
1734 | 0 | pinfo, tree, 0, -1, smb_info); |
1735 | 0 | } else { |
1736 | | /* |
1737 | | * If "*items->hf_index" is -1, this is |
1738 | | * a reserved must-be-null field; don't |
1739 | | * clutter the protocol tree by putting |
1740 | | * it in. |
1741 | | */ |
1742 | 0 | if (*items->hf_index > 0) { |
1743 | 0 | add_null_pointer_param(tvb, |
1744 | 0 | offset, 0, pinfo, tree, 0, |
1745 | 0 | *items->hf_index, smb_info); |
1746 | 0 | } |
1747 | 0 | items++; |
1748 | 0 | } |
1749 | 0 | break; |
1750 | | |
1751 | 0 | case 'z': |
1752 | | /* |
1753 | | * A null-terminated ASCII string. |
1754 | | */ |
1755 | 0 | if (items->func == NULL) { |
1756 | | /* |
1757 | | * We've run out of items in the table; |
1758 | | * fall back on the default. |
1759 | | */ |
1760 | 0 | offset = add_string_param(tvb, offset, 0, |
1761 | 0 | pinfo, tree, 0, -1, smb_info); |
1762 | 0 | } else if (items->type != PARAM_STRINGZ) { |
1763 | | /* |
1764 | | * Descriptor character is 'z', but this |
1765 | | * isn't a string parameter. |
1766 | | */ |
1767 | 0 | string_len = tvb_strsize(tvb, offset); |
1768 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, string_len, |
1769 | 0 | "%s: Value is %s, type is wrong (z)", |
1770 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1771 | 0 | hf_smb_pipe_string_param : *items->hf_index), |
1772 | 0 | tvb_format_text(pinfo->pool, tvb, offset, string_len)); |
1773 | 0 | offset += string_len; |
1774 | 0 | items++; |
1775 | 0 | } else { |
1776 | 0 | offset = (*items->func)(tvb, offset, 0, |
1777 | 0 | pinfo, tree, 0, *items->hf_index, smb_info); |
1778 | 0 | items++; |
1779 | 0 | } |
1780 | 0 | break; |
1781 | | |
1782 | 0 | case 'F': |
1783 | | /* |
1784 | | * One or more pad bytes. |
1785 | | */ |
1786 | 0 | desc = get_count(desc, &count); |
1787 | 0 | proto_tree_add_item(tree, hf_padding, tvb, offset, count, ENC_NA); |
1788 | 0 | offset += count; |
1789 | 0 | break; |
1790 | | |
1791 | 0 | case 'L': |
1792 | | /* |
1793 | | * 16-bit receive buffer length. |
1794 | | */ |
1795 | 0 | proto_tree_add_item(tree, hf_recv_buf_len, tvb, |
1796 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1797 | 0 | offset += 2; |
1798 | 0 | break; |
1799 | | |
1800 | 0 | case 's': |
1801 | | /* |
1802 | | * 32-bit send buffer offset. |
1803 | | * This appears not to be sent over the wire. |
1804 | | */ |
1805 | 0 | *has_data_p = true; |
1806 | 0 | break; |
1807 | | |
1808 | 0 | case 'T': |
1809 | | /* |
1810 | | * 16-bit send buffer length. |
1811 | | */ |
1812 | 0 | proto_tree_add_item(tree, hf_send_buf_len, tvb, |
1813 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1814 | 0 | offset += 2; |
1815 | 0 | break; |
1816 | | |
1817 | 0 | default: |
1818 | 0 | break; |
1819 | 0 | } |
1820 | 0 | } |
1821 | 0 | return offset; |
1822 | 0 | } |
1823 | | |
1824 | | static int |
1825 | | dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo, |
1826 | | proto_tree *tree, const unsigned char *desc, const item_t *items, |
1827 | | bool *has_data_p, bool *has_ent_count_p, uint16_t *ent_count_p, smb_info_t *smb_info) |
1828 | 0 | { |
1829 | 0 | unsigned c; |
1830 | 0 | uint16_t WParam; |
1831 | 0 | uint32_t LParam; |
1832 | 0 | int count; |
1833 | |
|
1834 | 0 | *has_data_p = false; |
1835 | 0 | *has_ent_count_p = false; |
1836 | 0 | while ((c = *desc++) != '\0') { |
1837 | 0 | switch (c) { |
1838 | | |
1839 | 0 | case 'r': |
1840 | | /* |
1841 | | * 32-bit receive buffer offset. |
1842 | | */ |
1843 | 0 | *has_data_p = true; |
1844 | 0 | break; |
1845 | | |
1846 | 0 | case 'g': |
1847 | | /* |
1848 | | * A byte or series of bytes is returned. |
1849 | | */ |
1850 | 0 | desc = get_count(desc, &count); |
1851 | 0 | if (items->func == NULL) { |
1852 | | /* |
1853 | | * We've run out of items in the table; |
1854 | | * fall back on the default. |
1855 | | */ |
1856 | 0 | offset = add_bytes_param(tvb, offset, count, |
1857 | 0 | pinfo, tree, 0, -1, smb_info); |
1858 | 0 | } else if (items->type != PARAM_BYTES) { |
1859 | | /* |
1860 | | * Descriptor character is 'b', but this |
1861 | | * isn't a byte/bytes parameter. |
1862 | | */ |
1863 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count, |
1864 | 0 | "%s: Value is %s, type is wrong (g)", |
1865 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1866 | 0 | hf_smb_pipe_bytes_param : *items->hf_index), |
1867 | 0 | tvb_bytes_to_str(pinfo->pool, tvb, offset, count)); |
1868 | 0 | offset += count; |
1869 | 0 | items++; |
1870 | 0 | } else { |
1871 | 0 | offset = (*items->func)(tvb, offset, count, |
1872 | 0 | pinfo, tree, 0, *items->hf_index, smb_info); |
1873 | 0 | items++; |
1874 | 0 | } |
1875 | 0 | break; |
1876 | | |
1877 | 0 | case 'h': |
1878 | | /* |
1879 | | * A 16-bit word is received. |
1880 | | */ |
1881 | 0 | if (items->func == NULL) { |
1882 | | /* |
1883 | | * We've run out of items in the table; |
1884 | | * fall back on the default. |
1885 | | */ |
1886 | 0 | offset = add_word_param(tvb, offset, 0, pinfo, |
1887 | 0 | tree, 0, hf_smb_pipe_word_param, smb_info); |
1888 | 0 | } else if (items->type != PARAM_WORD) { |
1889 | | /* |
1890 | | * Descriptor character is 'h', but this |
1891 | | * isn't a word parameter. |
1892 | | */ |
1893 | 0 | WParam = tvb_get_letohs(tvb, offset); |
1894 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
1895 | 0 | "%s: Value is %u (0x%04X), type is wrong (W)", |
1896 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1897 | 0 | hf_smb_pipe_word_param : *items->hf_index), |
1898 | 0 | WParam, WParam); |
1899 | 0 | offset += 2; |
1900 | 0 | items++; |
1901 | 0 | } else { |
1902 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
1903 | 0 | tree, 0, *items->hf_index, smb_info); |
1904 | 0 | items++; |
1905 | 0 | } |
1906 | 0 | break; |
1907 | | |
1908 | 0 | case 'i': |
1909 | | /* |
1910 | | * A 32-bit doubleword is received. |
1911 | | */ |
1912 | 0 | if (items->func == NULL) { |
1913 | | /* |
1914 | | * We've run out of items in the table; |
1915 | | * fall back on the default. |
1916 | | */ |
1917 | 0 | offset = add_dword_param(tvb, offset, 0, pinfo, |
1918 | 0 | tree, 0, hf_smb_pipe_doubleword_param, smb_info); |
1919 | 0 | } else if (items->type != PARAM_DWORD) { |
1920 | | /* |
1921 | | * Descriptor character is 'i', but this |
1922 | | * isn't a doubleword parameter. |
1923 | | */ |
1924 | 0 | LParam = tvb_get_letohl(tvb, offset); |
1925 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
1926 | 0 | "%s: Value is %u (0x%08X), type is wrong (i)", |
1927 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1928 | 0 | hf_smb_pipe_doubleword_param : *items->hf_index), |
1929 | 0 | LParam, LParam); |
1930 | 0 | offset += 4; |
1931 | 0 | items++; |
1932 | 0 | } else { |
1933 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
1934 | 0 | tree, 0, *items->hf_index, smb_info); |
1935 | 0 | items++; |
1936 | 0 | } |
1937 | 0 | break; |
1938 | | |
1939 | 0 | case 'e': |
1940 | | /* |
1941 | | * A 16-bit entry count is returned. |
1942 | | */ |
1943 | 0 | WParam = tvb_get_letohs(tvb, offset); |
1944 | 0 | proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2, |
1945 | 0 | WParam); |
1946 | 0 | offset += 2; |
1947 | 0 | *has_ent_count_p = true; |
1948 | 0 | *ent_count_p = WParam; /* Save this for later retrieval */ |
1949 | 0 | break; |
1950 | | |
1951 | 0 | default: |
1952 | 0 | break; |
1953 | 0 | } |
1954 | 0 | } |
1955 | 0 | return offset; |
1956 | 0 | } |
1957 | | |
1958 | | static int |
1959 | | dissect_transact_data(tvbuff_t *tvb, int offset, int convert, |
1960 | | packet_info *pinfo, proto_tree *tree, const unsigned char *desc, |
1961 | | const item_t *items, uint16_t *aux_count_p, smb_info_t *smb_info) |
1962 | 0 | { |
1963 | 0 | unsigned c; |
1964 | 0 | uint16_t WParam; |
1965 | 0 | uint32_t LParam; |
1966 | 0 | int count; |
1967 | 0 | int cptr; |
1968 | 0 | const char *string; |
1969 | 0 | int string_len = 0; |
1970 | |
|
1971 | 0 | if (aux_count_p != NULL) |
1972 | 0 | *aux_count_p = 0; |
1973 | |
|
1974 | 0 | while ((c = *desc++) != '\0') { |
1975 | 0 | switch (c) { |
1976 | | |
1977 | 0 | case 'W': |
1978 | | /* |
1979 | | * A 16-bit word value. |
1980 | | * XXX - handle the count? |
1981 | | */ |
1982 | 0 | desc = get_count(desc, &count); |
1983 | 0 | if (items->func == NULL) { |
1984 | | /* |
1985 | | * We've run out of items in the table; |
1986 | | * fall back on the default. |
1987 | | */ |
1988 | 0 | offset = add_word_param(tvb, offset, 0, pinfo, |
1989 | 0 | tree, convert, hf_smb_pipe_word_param, smb_info); |
1990 | 0 | } else if (items->type != PARAM_WORD) { |
1991 | | /* |
1992 | | * Descriptor character is 'W', but this |
1993 | | * isn't a word parameter. |
1994 | | */ |
1995 | 0 | WParam = tvb_get_letohs(tvb, offset); |
1996 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
1997 | 0 | "%s: Value is %u (0x%04X), type is wrong (W)", |
1998 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
1999 | 0 | hf_smb_pipe_word_param : *items->hf_index), |
2000 | 0 | WParam, WParam); |
2001 | 0 | offset += 2; |
2002 | 0 | items++; |
2003 | 0 | } else { |
2004 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
2005 | 0 | tree, convert, *items->hf_index, smb_info); |
2006 | 0 | items++; |
2007 | 0 | } |
2008 | 0 | break; |
2009 | | |
2010 | 0 | case 'D': |
2011 | | /* |
2012 | | * A 32-bit doubleword value. |
2013 | | * XXX - handle the count? |
2014 | | */ |
2015 | 0 | desc = get_count(desc, &count); |
2016 | 0 | if (items->func == NULL) { |
2017 | | /* |
2018 | | * We've run out of items in the table; |
2019 | | * fall back on the default. |
2020 | | */ |
2021 | 0 | offset = add_dword_param(tvb, offset, 0, pinfo, |
2022 | 0 | tree, convert, hf_smb_pipe_doubleword_param, smb_info); |
2023 | 0 | } else if (items->type != PARAM_DWORD) { |
2024 | | /* |
2025 | | * Descriptor character is 'D', but this |
2026 | | * isn't a doubleword parameter. |
2027 | | */ |
2028 | 0 | LParam = tvb_get_letohl(tvb, offset); |
2029 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2, |
2030 | 0 | "%s: Value is %u (0x%08X), type is wrong (D)", |
2031 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
2032 | 0 | hf_smb_pipe_doubleword_param : *items->hf_index), |
2033 | 0 | LParam, LParam); |
2034 | 0 | offset += 4; |
2035 | 0 | items++; |
2036 | 0 | } else { |
2037 | 0 | offset = (*items->func)(tvb, offset, 0, pinfo, |
2038 | 0 | tree, convert, *items->hf_index, smb_info); |
2039 | 0 | items++; |
2040 | 0 | } |
2041 | 0 | break; |
2042 | | |
2043 | 0 | case 'B': |
2044 | | /* |
2045 | | * A byte or multi-byte value. |
2046 | | */ |
2047 | 0 | desc = get_count(desc, &count); |
2048 | 0 | if (items->func == NULL) { |
2049 | | /* |
2050 | | * We've run out of items in the table; |
2051 | | * fall back on the default. |
2052 | | */ |
2053 | 0 | offset = add_bytes_param(tvb, offset, count, |
2054 | 0 | pinfo, tree, convert, -1, smb_info); |
2055 | 0 | } else if (items->type != PARAM_BYTES) { |
2056 | | /* |
2057 | | * Descriptor character is 'B', but this |
2058 | | * isn't a byte/bytes parameter. |
2059 | | */ |
2060 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count, |
2061 | 0 | "%s: Value is %s, type is wrong (B)", |
2062 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
2063 | 0 | hf_smb_pipe_bytes_param : *items->hf_index), |
2064 | 0 | tvb_bytes_to_str(pinfo->pool, tvb, offset, count)); |
2065 | 0 | offset += count; |
2066 | 0 | items++; |
2067 | 0 | } else { |
2068 | 0 | offset = (*items->func)(tvb, offset, count, |
2069 | 0 | pinfo, tree, convert, *items->hf_index, smb_info); |
2070 | 0 | items++; |
2071 | 0 | } |
2072 | 0 | break; |
2073 | | |
2074 | 0 | case 'O': |
2075 | | /* |
2076 | | * A null pointer. |
2077 | | */ |
2078 | 0 | if (items->func == NULL) { |
2079 | | /* |
2080 | | * We've run out of items in the table; |
2081 | | * fall back on the default. |
2082 | | */ |
2083 | 0 | add_null_pointer_param(tvb, offset, 0, |
2084 | 0 | pinfo, tree, convert, -1, smb_info); |
2085 | 0 | } else { |
2086 | | /* |
2087 | | * If "*items->hf_index" is -1, this is |
2088 | | * a reserved must-be-null field; don't |
2089 | | * clutter the protocol tree by putting |
2090 | | * it in. |
2091 | | */ |
2092 | 0 | if (*items->hf_index > 0) { |
2093 | 0 | add_null_pointer_param(tvb, |
2094 | 0 | offset, 0, pinfo, tree, convert, |
2095 | 0 | *items->hf_index, smb_info); |
2096 | 0 | } |
2097 | 0 | items++; |
2098 | 0 | } |
2099 | 0 | break; |
2100 | | |
2101 | 0 | case 'z': |
2102 | | /* |
2103 | | * A pointer to a null-terminated ASCII string. |
2104 | | */ |
2105 | 0 | if (items->func == NULL) { |
2106 | | /* |
2107 | | * We've run out of items in the table; |
2108 | | * fall back on the default. |
2109 | | */ |
2110 | 0 | offset = add_stringz_pointer_param(tvb, offset, |
2111 | 0 | 0, pinfo, tree, convert, -1, smb_info); |
2112 | 0 | } else if (items->type != PARAM_STRINGZ) { |
2113 | | /* |
2114 | | * Descriptor character is 'z', but this |
2115 | | * isn't a string parameter. |
2116 | | */ |
2117 | 0 | string = get_stringz_pointer_value(pinfo->pool, tvb, offset, |
2118 | 0 | convert, &cptr, &string_len); |
2119 | 0 | offset += 4; |
2120 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, cptr, string_len, |
2121 | 0 | "%s: Value is %s, type is wrong (z)", |
2122 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
2123 | 0 | hf_smb_pipe_string_param : *items->hf_index), |
2124 | 0 | string ? string : "(null)"); |
2125 | 0 | items++; |
2126 | 0 | } else { |
2127 | 0 | offset = (*items->func)(tvb, offset, 0, |
2128 | 0 | pinfo, tree, convert, *items->hf_index, smb_info); |
2129 | 0 | items++; |
2130 | 0 | } |
2131 | 0 | break; |
2132 | | |
2133 | 0 | case 'b': |
2134 | | /* |
2135 | | * A pointer to a byte or multi-byte value. |
2136 | | */ |
2137 | 0 | desc = get_count(desc, &count); |
2138 | 0 | if (items->func == NULL) { |
2139 | | /* |
2140 | | * We've run out of items in the table; |
2141 | | * fall back on the default. |
2142 | | */ |
2143 | 0 | offset = add_bytes_pointer_param(tvb, offset, |
2144 | 0 | count, pinfo, tree, convert, -1, smb_info); |
2145 | 0 | } else if (items->type != PARAM_BYTES) { |
2146 | | /* |
2147 | | * Descriptor character is 'b', but this |
2148 | | * isn't a byte/bytes parameter. |
2149 | | */ |
2150 | 0 | cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert; |
2151 | 0 | offset += 4; |
2152 | 0 | proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count, |
2153 | 0 | "%s: Value is %s, type is wrong (b)", |
2154 | 0 | proto_registrar_get_name((*items->hf_index <= 0) ? |
2155 | 0 | hf_smb_pipe_bytes_param : *items->hf_index), |
2156 | 0 | tvb_bytes_to_str(pinfo->pool, tvb, cptr, count)); |
2157 | 0 | items++; |
2158 | 0 | } else { |
2159 | 0 | offset = (*items->func)(tvb, offset, count, |
2160 | 0 | pinfo, tree, convert, *items->hf_index, smb_info); |
2161 | 0 | items++; |
2162 | 0 | } |
2163 | 0 | break; |
2164 | | |
2165 | 0 | case 'N': |
2166 | | /* |
2167 | | * 16-bit auxiliary data structure count. |
2168 | | * XXX - hf_acount? |
2169 | | */ |
2170 | 0 | WParam = tvb_get_letohs(tvb, offset); |
2171 | 0 | proto_tree_add_uint(tree, hf_aux_data_struct_count, tvb, offset, 2, WParam); |
2172 | 0 | offset += 2; |
2173 | 0 | if (aux_count_p != NULL) |
2174 | 0 | *aux_count_p = WParam; /* Save this for later retrieval */ |
2175 | 0 | break; |
2176 | | |
2177 | 0 | default: |
2178 | 0 | break; |
2179 | 0 | } |
2180 | 0 | } |
2181 | 0 | return offset; |
2182 | 0 | } |
2183 | | |
2184 | | static const value_string commands[] = { |
2185 | | {API_NetShareEnum, "NetShareEnum"}, |
2186 | | {API_NetShareGetInfo, "NetShareGetInfo"}, |
2187 | | {API_NetShareSetInfo, "NetShareSetInfo"}, |
2188 | | {API_NetShareAdd, "NetShareAdd"}, |
2189 | | {API_NetShareDel, "NetShareDel"}, |
2190 | | {API_NetShareCheck, "NetShareCheck"}, |
2191 | | {API_NetSessionEnum, "NetSessionEnum"}, |
2192 | | {API_NetSessionGetInfo, "NetSessionGetInfo"}, |
2193 | | {API_NetSessionDel, "NetSessionDel"}, |
2194 | | {API_WconnectionEnum, "NetConnectionEnum"}, |
2195 | | {API_NetFileEnum, "NetFileEnum"}, |
2196 | | {API_NetFileGetInfo, "NetFileGetInfo"}, |
2197 | | {API_NetFileClose, "NetFileClose"}, |
2198 | | {API_NetServerGetInfo, "NetServerGetInfo"}, |
2199 | | {API_NetServerSetInfo, "NetServerSetInfo"}, |
2200 | | {API_NetServerDiskEnum, "NetServerDiskEnum"}, |
2201 | | {API_NetServerAdminCommand, "NetServerAdminCommand"}, |
2202 | | {API_NetAuditOpen, "NetAuditOpen"}, |
2203 | | {API_NetAuditClear, "NetAuditClear"}, |
2204 | | {API_NetErrorLogOpen, "NetErrorLogOpen"}, |
2205 | | {API_NetErrorLogClear, "NetErrorLogClear"}, |
2206 | | {API_NetCharDevEnum, "NetCharDevEnum"}, |
2207 | | {API_NetCharDevGetInfo, "NetCharDevGetInfo"}, |
2208 | | {API_NetCharDevControl, "NetCharDevControl"}, |
2209 | | {API_NetCharDevQEnum, "NetCharDevQEnum"}, |
2210 | | {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"}, |
2211 | | {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"}, |
2212 | | {API_NetCharDevQPurge, "NetCharDevQPurge"}, |
2213 | | {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"}, |
2214 | | {API_NetMessageNameEnum, "NetMessageNameEnum"}, |
2215 | | {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"}, |
2216 | | {API_NetMessageNameAdd, "NetMessageNameAdd"}, |
2217 | | {API_NetMessageNameDel, "NetMessageNameDel"}, |
2218 | | {API_NetMessageNameFwd, "NetMessageNameFwd"}, |
2219 | | {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"}, |
2220 | | {API_NetMessageBufferSend, "NetMessageBufferSend"}, |
2221 | | {API_NetMessageFileSend, "NetMessageFileSend"}, |
2222 | | {API_NetMessageLogFileSet, "NetMessageLogFileSet"}, |
2223 | | {API_NetMessageLogFileGet, "NetMessageLogFileGet"}, |
2224 | | {API_NetServiceEnum, "NetServiceEnum"}, |
2225 | | {API_NetServiceInstall, "NetServiceInstall"}, |
2226 | | {API_NetServiceControl, "NetServiceControl"}, |
2227 | | {API_NetAccessEnum, "NetAccessEnum"}, |
2228 | | {API_NetAccessGetInfo, "NetAccessGetInfo"}, |
2229 | | {API_NetAccessSetInfo, "NetAccessSetInfo"}, |
2230 | | {API_NetAccessAdd, "NetAccessAdd"}, |
2231 | | {API_NetAccessDel, "NetAccessDel"}, |
2232 | | {API_NetGroupEnum, "NetGroupEnum"}, |
2233 | | {API_NetGroupAdd, "NetGroupAdd"}, |
2234 | | {API_NetGroupDel, "NetGroupDel"}, |
2235 | | {API_NetGroupAddUser, "NetGroupAddUser"}, |
2236 | | {API_NetGroupDelUser, "NetGroupDelUser"}, |
2237 | | {API_NetGroupGetUsers, "NetGroupGetUsers"}, |
2238 | | {API_NetUserEnum, "NetUserEnum"}, |
2239 | | {API_NetUserAdd, "NetUserAdd"}, |
2240 | | {API_NetUserDel, "NetUserDel"}, |
2241 | | {API_NetUserGetInfo, "NetUserGetInfo"}, |
2242 | | {API_NetUserSetInfo, "NetUserSetInfo"}, |
2243 | | {API_NetUserPasswordSet, "NetUserPasswordSet"}, |
2244 | | {API_NetUserGetGroups, "NetUserGetGroups"}, |
2245 | | {API_NetWkstaSetUID, "NetWkstaSetUID"}, |
2246 | | {API_NetWkstaGetInfo, "NetWkstaGetInfo"}, |
2247 | | {API_NetWkstaSetInfo, "NetWkstaSetInfo"}, |
2248 | | {API_NetUseEnum, "NetUseEnum"}, |
2249 | | {API_NetUseAdd, "NetUseAdd"}, |
2250 | | {API_NetUseDel, "NetUseDel"}, |
2251 | | {API_NetUseGetInfo, "NetUseGetInfo"}, |
2252 | | {API_WPrintQEnum, "WPrintQEnum"}, |
2253 | | {API_WPrintQGetInfo, "WPrintQGetInfo"}, |
2254 | | {API_WPrintQSetInfo, "WPrintQSetInfo"}, |
2255 | | {API_WPrintQAdd, "WPrintQAdd"}, |
2256 | | {API_WPrintQDel, "WPrintQDel"}, |
2257 | | {API_WPrintQPause, "WPrintQPause"}, |
2258 | | {API_WPrintQContinue, "WPrintQContinue"}, |
2259 | | {API_WPrintJobEnum, "WPrintJobEnum"}, |
2260 | | {API_WPrintJobGetInfo, "WPrintJobGetInfo"}, |
2261 | | {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"}, |
2262 | | {API_WPrintJobDel, "WPrintJobDel"}, |
2263 | | {API_WPrintJobPause, "WPrintJobPause"}, |
2264 | | {API_WPrintJobContinue, "WPrintJobContinue"}, |
2265 | | {API_WPrintDestEnum, "WPrintDestEnum"}, |
2266 | | {API_WPrintDestGetInfo, "WPrintDestGetInfo"}, |
2267 | | {API_WPrintDestControl, "WPrintDestControl"}, |
2268 | | {API_NetProfileSave, "NetProfileSave"}, |
2269 | | {API_NetProfileLoad, "NetProfileLoad"}, |
2270 | | {API_NetStatisticsGet, "NetStatisticsGet"}, |
2271 | | {API_NetStatisticsClear, "NetStatisticsClear"}, |
2272 | | {API_NetRemoteTOD, "NetRemoteTOD"}, |
2273 | | {API_WNetBiosEnum, "WNetBiosEnum"}, |
2274 | | {API_WNetBiosGetInfo, "WNetBiosGetInfo"}, |
2275 | | {API_NetServerEnum, "NetServerEnum"}, |
2276 | | {API_I_NetServerEnum, "I_NetServerEnum"}, |
2277 | | {API_NetServiceGetInfo, "NetServiceGetInfo"}, |
2278 | | {API_WPrintQPurge, "WPrintQPurge"}, |
2279 | | {API_NetServerEnum2, "NetServerEnum2"}, |
2280 | | {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"}, |
2281 | | {API_NetGroupGetInfo, "NetGroupGetInfo"}, |
2282 | | {API_NetGroupSetInfo, "NetGroupSetInfo"}, |
2283 | | {API_NetGroupSetUsers, "NetGroupSetUsers"}, |
2284 | | {API_NetUserSetGroups, "NetUserSetGroups"}, |
2285 | | {API_NetUserModalsGet, "NetUserModalsGet"}, |
2286 | | {API_NetUserModalsSet, "NetUserModalsSet"}, |
2287 | | {API_NetFileEnum2, "NetFileEnum2"}, |
2288 | | {API_NetUserAdd2, "NetUserAdd2"}, |
2289 | | {API_NetUserSetInfo2, "NetUserSetInfo2"}, |
2290 | | {API_NetUserPasswordSet2, "SetUserPassword"}, |
2291 | | {API_I_NetServerEnum2, "I_NetServerEnum2"}, |
2292 | | {API_NetConfigGet2, "NetConfigGet2"}, |
2293 | | {API_NetConfigGetAll2, "NetConfigGetAll2"}, |
2294 | | {API_NetGetDCName, "NetGetDCName"}, |
2295 | | {API_NetHandleGetInfo, "NetHandleGetInfo"}, |
2296 | | {API_NetHandleSetInfo, "NetHandleSetInfo"}, |
2297 | | {API_NetStatisticsGet2, "NetStatisticsGet2"}, |
2298 | | {API_WBuildGetInfo, "WBuildGetInfo"}, |
2299 | | {API_NetFileGetInfo2, "NetFileGetInfo2"}, |
2300 | | {API_NetFileClose2, "NetFileClose2"}, |
2301 | | {API_NetServerReqChallenge, "NetServerReqChallenge"}, |
2302 | | {API_NetServerAuthenticate, "NetServerAuthenticate"}, |
2303 | | {API_NetServerPasswordSet, "NetServerPasswordSet"}, |
2304 | | {API_WNetAccountDeltas, "WNetAccountDeltas"}, |
2305 | | {API_WNetAccountSync, "WNetAccountSync"}, |
2306 | | {API_NetUserEnum2, "NetUserEnum2"}, |
2307 | | {API_NetWkstaUserLogon, "NetWkstaUserLogon"}, |
2308 | | {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"}, |
2309 | | {API_NetLogonEnum, "NetLogonEnum"}, |
2310 | | {API_NetErrorLogRead, "NetErrorLogRead"}, |
2311 | | {API_I_NetPathType, "I_NetPathType"}, |
2312 | | {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"}, |
2313 | | {API_I_NetPathCompare, "I_NetPathCompare"}, |
2314 | | {API_I_NetNameValidate, "I_NetNameValidate"}, |
2315 | | {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"}, |
2316 | | {API_I_NetNameCompare, "I_NetNameCompare"}, |
2317 | | {API_NetAuditRead, "NetAuditRead"}, |
2318 | | {API_WPrintDestAdd, "WPrintDestAdd"}, |
2319 | | {API_WPrintDestSetInfo, "WPrintDestSetInfo"}, |
2320 | | {API_WPrintDestDel, "WPrintDestDel"}, |
2321 | | {API_NetUserValidate2, "NetUserValidate2"}, |
2322 | | {API_WPrintJobSetInfo, "WPrintJobSetInfo"}, |
2323 | | {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"}, |
2324 | | {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"}, |
2325 | | {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"}, |
2326 | | {API_TI_FTAbortVerify, "TI_FTAbortVerify"}, |
2327 | | {API_TI_FTGetInfo, "TI_FTGetInfo"}, |
2328 | | {API_TI_FTSetInfo, "TI_FTSetInfo"}, |
2329 | | {API_TI_FTLockDisk, "TI_FTLockDisk"}, |
2330 | | {API_TI_FTFixError, "TI_FTFixError"}, |
2331 | | {API_TI_FTAbortFix, "TI_FTAbortFix"}, |
2332 | | {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"}, |
2333 | | {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"}, |
2334 | | {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"}, |
2335 | | {API_NetAccessCheck, "NetAccessCheck"}, |
2336 | | {API_NetAlertRaise, "NetAlertRaise"}, |
2337 | | {API_NetAlertStart, "NetAlertStart"}, |
2338 | | {API_NetAlertStop, "NetAlertStop"}, |
2339 | | {API_NetAuditWrite, "NetAuditWrite"}, |
2340 | | {API_NetIRemoteAPI, "NetIRemoteAPI"}, |
2341 | | {API_NetServiceStatus, "NetServiceStatus"}, |
2342 | | {API_I_NetServerRegister, "I_NetServerRegister"}, |
2343 | | {API_I_NetServerDeregister, "I_NetServerDeregister"}, |
2344 | | {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"}, |
2345 | | {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"}, |
2346 | | {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"}, |
2347 | | {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"}, |
2348 | | {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"}, |
2349 | | {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"}, |
2350 | | {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"}, |
2351 | | {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"}, |
2352 | | {API_I_NetFileEntryMake, "I_NetFileEntryMake"}, |
2353 | | {API_I_NetFileEntryClear, "I_NetFileEntryClear"}, |
2354 | | {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"}, |
2355 | | {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"}, |
2356 | | {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"}, |
2357 | | {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"}, |
2358 | | {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"}, |
2359 | | {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"}, |
2360 | | {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"}, |
2361 | | {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"}, |
2362 | | {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"}, |
2363 | | {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"}, |
2364 | | {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"}, |
2365 | | {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"}, |
2366 | | {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"}, |
2367 | | {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"}, |
2368 | | {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"}, |
2369 | | {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"}, |
2370 | | {API_WIServerSetInfo, "WIServerSetInfo"}, |
2371 | | {API_WPrintDriverEnum, "WPrintDriverEnum"}, |
2372 | | {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"}, |
2373 | | {API_WPrintPortEnum, "WPrintPortEnum"}, |
2374 | | {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"}, |
2375 | | {API_WNetAccountUpdate, "WNetAccountUpdate"}, |
2376 | | {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"}, |
2377 | | {API_NetConfigSet, "NetConfigSet"}, |
2378 | | {API_WAccountsReplicate, "WAccountsReplicate"}, |
2379 | | {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"}, |
2380 | | {API_NetServerEnum3, "NetServerEnum3"}, |
2381 | | {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"}, |
2382 | | {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"}, |
2383 | | {API_NetAliasAdd, "NetAliasAdd"}, |
2384 | | {API_NetAliasDel, "NetAliasDel"}, |
2385 | | {API_NetAliasGetInfo, "NetAliasGetInfo"}, |
2386 | | {API_NetAliasSetInfo, "NetAliasSetInfo"}, |
2387 | | {API_NetAliasEnum, "NetAliasEnum"}, |
2388 | | {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"}, |
2389 | | {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"}, |
2390 | | {API_NetUserGetAppSel, "NetUserGetAppSel"}, |
2391 | | {API_NetUserSetAppSel, "NetUserSetAppSel"}, |
2392 | | {API_NetAppAdd, "NetAppAdd"}, |
2393 | | {API_NetAppDel, "NetAppDel"}, |
2394 | | {API_NetAppGetInfo, "NetAppGetInfo"}, |
2395 | | {API_NetAppSetInfo, "NetAppSetInfo"}, |
2396 | | {API_NetAppEnum, "NetAppEnum"}, |
2397 | | {API_NetUserDCDBInit, "NetUserDCDBInit"}, |
2398 | | {API_NetDASDAdd, "NetDASDAdd"}, |
2399 | | {API_NetDASDDel, "NetDASDDel"}, |
2400 | | {API_NetDASDGetInfo, "NetDASDGetInfo"}, |
2401 | | {API_NetDASDSetInfo, "NetDASDSetInfo"}, |
2402 | | {API_NetDASDEnum, "NetDASDEnum"}, |
2403 | | {API_NetDASDCheck, "NetDASDCheck"}, |
2404 | | {API_NetDASDCtl, "NetDASDCtl"}, |
2405 | | {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"}, |
2406 | | {API_NetUserPasswordSet3, "NetUserPasswordSet3"}, |
2407 | | {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"}, |
2408 | | {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"}, |
2409 | | {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"}, |
2410 | | {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"}, |
2411 | | {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"}, |
2412 | | {API_I_ShareAdd, "I_ShareAdd"}, |
2413 | | {API_I_AliasEnum, "I_AliasEnum"}, |
2414 | | {API_NetAccessApply, "NetAccessApply"}, |
2415 | | {API_WPrt16Query, "WPrt16Query"}, |
2416 | | {API_WPrt16Set, "WPrt16Set"}, |
2417 | | {API_NetUserDel100, "NetUserDel100"}, |
2418 | | {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"}, |
2419 | | {API_WRemoteTODSet, "WRemoteTODSet"}, |
2420 | | {API_WPrintJobMoveAll, "WPrintJobMoveAll"}, |
2421 | | {API_W16AppParmAdd, "W16AppParmAdd"}, |
2422 | | {API_W16AppParmDel, "W16AppParmDel"}, |
2423 | | {API_W16AppParmGet, "W16AppParmGet"}, |
2424 | | {API_W16AppParmSet, "W16AppParmSet"}, |
2425 | | {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"}, |
2426 | | {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"}, |
2427 | | {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"}, |
2428 | | {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"}, |
2429 | | {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"}, |
2430 | | {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"}, |
2431 | | {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"}, |
2432 | | {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"}, |
2433 | | {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"}, |
2434 | | {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"}, |
2435 | | {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"}, |
2436 | | {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"}, |
2437 | | {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"}, |
2438 | | {API_NetServerNameAdd, "NetServerNameAdd"}, |
2439 | | {API_NetServerNameDel, "NetServerNameDel"}, |
2440 | | {API_NetServerNameEnum, "NetServerNameEnum"}, |
2441 | | {API_I_WDASDEnum, "I_WDASDEnum"}, |
2442 | | {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"}, |
2443 | | {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"}, |
2444 | | {0, NULL} |
2445 | | }; |
2446 | | |
2447 | | static value_string_ext commands_ext = VALUE_STRING_EXT_INIT(commands); |
2448 | | |
2449 | | static void |
2450 | | dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert, |
2451 | | proto_tree *tree, smb_info_t *smb_info, |
2452 | | const struct lanman_desc *lanman, bool has_ent_count, |
2453 | | uint16_t ent_count) |
2454 | 0 | { |
2455 | 0 | smb_transact_info_t *trp; |
2456 | 0 | const item_list_t *resp_data_list; |
2457 | 0 | int offset, start_offset; |
2458 | 0 | const char *label; |
2459 | 0 | int ett; |
2460 | 0 | const item_t *resp_data; |
2461 | 0 | proto_item *data_item = NULL; |
2462 | 0 | proto_tree *data_tree = NULL; |
2463 | 0 | proto_item *entry_item; |
2464 | 0 | proto_tree *entry_tree; |
2465 | 0 | unsigned i, j; |
2466 | 0 | uint16_t aux_count; |
2467 | |
|
2468 | 0 | trp = (smb_transact_info_t *)smb_info->sip->extra_info; |
2469 | | |
2470 | | /* |
2471 | | * Find the item table for the matching request's detail level. |
2472 | | */ |
2473 | 0 | for (resp_data_list = lanman->resp_data_list; |
2474 | 0 | resp_data_list->level != -1; resp_data_list++) { |
2475 | 0 | if (resp_data_list->level == trp->info_level) |
2476 | 0 | break; |
2477 | 0 | } |
2478 | 0 | resp_data = resp_data_list->item_list; |
2479 | |
|
2480 | 0 | offset = 0; |
2481 | 0 | if (has_ent_count) { |
2482 | | /* |
2483 | | * The data is a list of entries; create a protocol tree item |
2484 | | * for it. |
2485 | | */ |
2486 | 0 | if (tree) { |
2487 | 0 | label = lanman->resp_data_entry_list_label; |
2488 | 0 | if (label == NULL) |
2489 | 0 | label = "Entries"; |
2490 | 0 | if (lanman->ett_data_entry_list != NULL) |
2491 | 0 | ett = *lanman->ett_data_entry_list; |
2492 | 0 | else |
2493 | 0 | ett = ett_lanman_unknown_entries; |
2494 | |
|
2495 | 0 | data_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett, &data_item, label); |
2496 | 0 | } |
2497 | 0 | } |
2498 | |
|
2499 | 0 | if (trp->data_descrip == NULL) { |
2500 | | /* |
2501 | | * This could happen if we only dissected |
2502 | | * part of the request to which this is a |
2503 | | * reply, e.g. if the request was split |
2504 | | * across TCP segments and we weren't doing |
2505 | | * TCP desegmentation, or if we had a snapshot |
2506 | | * length that was too short. |
2507 | | * |
2508 | | * We can't dissect the data; just show it as raw data or, |
2509 | | * if we've already created a top-level item, note that |
2510 | | * no descriptor is available. |
2511 | | */ |
2512 | 0 | if (has_ent_count) { |
2513 | 0 | if (data_item != NULL) { |
2514 | 0 | proto_item_append_text(data_item, |
2515 | 0 | " (No descriptor available)"); |
2516 | 0 | } |
2517 | 0 | } else { |
2518 | 0 | proto_tree_add_item(data_tree, hf_data_no_descriptor, tvb, offset, -1, ENC_NA); |
2519 | 0 | } |
2520 | 0 | offset += tvb_captured_length_remaining(tvb, offset); |
2521 | 0 | } else { |
2522 | | /* |
2523 | | * If we have an entry count, show all the entries, |
2524 | | * with each one having a protocol tree item. |
2525 | | * |
2526 | | * Otherwise, we just show one returned item, with |
2527 | | * no protocol tree item. |
2528 | | */ |
2529 | 0 | if (!has_ent_count) |
2530 | 0 | ent_count = 1; |
2531 | 0 | for (i = 0; i < ent_count; i++) { |
2532 | 0 | start_offset = offset; |
2533 | 0 | if (has_ent_count && |
2534 | 0 | lanman->resp_data_element_item != NULL) { |
2535 | | /* |
2536 | | * Create a protocol tree item for the |
2537 | | * entry. |
2538 | | */ |
2539 | 0 | entry_item = |
2540 | 0 | (*lanman->resp_data_element_item) |
2541 | 0 | (tvb, data_tree, offset); |
2542 | 0 | entry_tree = proto_item_add_subtree( |
2543 | 0 | entry_item, |
2544 | 0 | *lanman->ett_resp_data_element_item); |
2545 | 0 | } else { |
2546 | | /* |
2547 | | * Just leave it at the current |
2548 | | * level. |
2549 | | */ |
2550 | 0 | entry_item = NULL; |
2551 | 0 | entry_tree = data_tree; |
2552 | 0 | } |
2553 | |
|
2554 | 0 | offset = dissect_transact_data(tvb, offset, |
2555 | 0 | convert, pinfo, entry_tree, |
2556 | 0 | trp->data_descrip, resp_data, &aux_count, smb_info); |
2557 | | |
2558 | | /* auxiliary data */ |
2559 | 0 | if (trp->aux_data_descrip != NULL) { |
2560 | 0 | for (j = 0; j < aux_count; j++) { |
2561 | 0 | offset = dissect_transact_data( |
2562 | 0 | tvb, offset, convert, |
2563 | 0 | pinfo, entry_tree, |
2564 | 0 | trp->data_descrip, |
2565 | 0 | lanman->resp_aux_data, NULL, smb_info); |
2566 | 0 | } |
2567 | 0 | } |
2568 | |
|
2569 | 0 | if (entry_item != NULL) { |
2570 | | /* |
2571 | | * Set the length of the protocol tree |
2572 | | * item for the entry. |
2573 | | */ |
2574 | 0 | proto_item_set_len(entry_item, |
2575 | 0 | offset - start_offset); |
2576 | 0 | } |
2577 | 0 | } |
2578 | 0 | } |
2579 | |
|
2580 | 0 | if (data_item != NULL) { |
2581 | | /* |
2582 | | * Set the length of the protocol tree item |
2583 | | * for the data. |
2584 | | */ |
2585 | 0 | proto_item_set_len(data_item, offset); |
2586 | 0 | } |
2587 | 0 | } |
2588 | | |
2589 | | static bool |
2590 | | dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb, |
2591 | | packet_info *pinfo, proto_tree *parent_tree, smb_info_t *smb_info) |
2592 | 0 | { |
2593 | 0 | smb_transact_info_t *trp = NULL; |
2594 | 0 | int offset = 0/*, start_offset*/; |
2595 | 0 | uint16_t cmd; |
2596 | 0 | uint16_t status; |
2597 | 0 | int convert; |
2598 | 0 | const struct lanman_desc *lanman; |
2599 | 0 | proto_item *item = NULL; |
2600 | 0 | proto_tree *tree = NULL; |
2601 | 0 | unsigned descriptor_len; |
2602 | 0 | const char *param_descrip, *data_descrip, *aux_data_descrip = NULL; |
2603 | 0 | bool has_data; |
2604 | 0 | bool has_ent_count; |
2605 | 0 | uint16_t ent_count = 0, aux_count; |
2606 | 0 | unsigned i; |
2607 | 0 | proto_item *data_item; |
2608 | 0 | proto_tree *data_tree; |
2609 | |
|
2610 | 0 | if (smb_info->sip->extra_info_type == SMB_EI_TRI) |
2611 | 0 | trp = (smb_transact_info_t *)smb_info->sip->extra_info; |
2612 | |
|
2613 | 0 | if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman))) |
2614 | 0 | return false; |
2615 | 0 | if (p_tvb == NULL) { |
2616 | | /* |
2617 | | * Requests must have parameters. |
2618 | | */ |
2619 | 0 | return false; |
2620 | 0 | } |
2621 | 0 | pinfo->current_proto = "LANMAN"; |
2622 | |
|
2623 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN"); |
2624 | |
|
2625 | 0 | if (parent_tree) { |
2626 | 0 | item = proto_tree_add_item(parent_tree, proto_smb_lanman, |
2627 | 0 | pd_tvb, 0, -1, ENC_NA); |
2628 | 0 | tree = proto_item_add_subtree(item, ett_lanman); |
2629 | 0 | } |
2630 | |
|
2631 | 0 | if (smb_info->request) { /* this is a request */ |
2632 | | /* function code */ |
2633 | 0 | cmd = tvb_get_letohs(p_tvb, offset); |
2634 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str_ext(cmd, &commands_ext, "Unknown Command (%u)")); |
2635 | |
|
2636 | 0 | proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2, |
2637 | 0 | cmd); |
2638 | 0 | offset += 2; |
2639 | |
|
2640 | 0 | if(!trp){ |
2641 | 0 | return false; /* can't dissect this request */ |
2642 | 0 | } |
2643 | | |
2644 | | /* |
2645 | | * If we haven't already done so, save the function code in |
2646 | | * the structure we were handed, so that it's available to |
2647 | | * the code parsing the reply, and initialize the detail |
2648 | | * level to -1, meaning "unknown". |
2649 | | */ |
2650 | 0 | if (!pinfo->fd->visited) { |
2651 | 0 | trp->lanman_cmd = cmd; |
2652 | 0 | trp->info_level = -1; |
2653 | 0 | trp->param_descrip=NULL; |
2654 | 0 | trp->data_descrip=NULL; |
2655 | 0 | trp->aux_data_descrip=NULL; |
2656 | 0 | } |
2657 | | |
2658 | | /* parameter descriptor */ |
2659 | 0 | param_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII); |
2660 | 0 | proto_tree_add_string(tree, hf_param_desc, p_tvb, offset, descriptor_len, param_descrip); |
2661 | 0 | if (!pinfo->fd->visited) { |
2662 | | /* |
2663 | | * Save the parameter descriptor for future use. |
2664 | | */ |
2665 | 0 | DISSECTOR_ASSERT(trp->param_descrip == NULL); |
2666 | 0 | trp->param_descrip = wmem_strdup(wmem_file_scope(), param_descrip); |
2667 | 0 | } |
2668 | 0 | offset += descriptor_len; |
2669 | | |
2670 | | /* return descriptor */ |
2671 | 0 | data_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII); |
2672 | 0 | proto_tree_add_string(tree, hf_return_desc, p_tvb, offset, descriptor_len, data_descrip); |
2673 | 0 | if (!pinfo->fd->visited) { |
2674 | | /* |
2675 | | * Save the return descriptor for future use. |
2676 | | */ |
2677 | 0 | DISSECTOR_ASSERT(trp->data_descrip == NULL); |
2678 | 0 | trp->data_descrip = wmem_strdup(wmem_file_scope(), data_descrip); |
2679 | 0 | } |
2680 | 0 | offset += descriptor_len; |
2681 | |
|
2682 | 0 | lanman = find_lanman(cmd); |
2683 | | |
2684 | | /* request parameters */ |
2685 | | /*start_offset = offset;*/ |
2686 | 0 | offset = dissect_request_parameters(p_tvb, offset, pinfo, tree, |
2687 | 0 | param_descrip, lanman->req, &has_data, smb_info); |
2688 | | |
2689 | | /* auxiliary data descriptor */ |
2690 | 0 | if (tvb_reported_length_remaining(p_tvb, offset) > 0){ |
2691 | | /* |
2692 | | * There are more parameters left, so the next |
2693 | | * item is the auxiliary data descriptor. |
2694 | | */ |
2695 | 0 | aux_data_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII); |
2696 | 0 | proto_tree_add_string(tree, hf_aux_data_desc, p_tvb, offset, descriptor_len, aux_data_descrip); |
2697 | 0 | if (!pinfo->fd->visited) { |
2698 | | /* |
2699 | | * Save the auxiliary data descriptor for |
2700 | | * future use. |
2701 | | */ |
2702 | 0 | DISSECTOR_ASSERT(trp->aux_data_descrip == NULL); |
2703 | 0 | trp->aux_data_descrip = |
2704 | 0 | wmem_strdup(wmem_file_scope(), aux_data_descrip); |
2705 | 0 | } |
2706 | 0 | } |
2707 | | |
2708 | | /* reset offset, we now start dissecting the data area */ |
2709 | 0 | offset = 0; |
2710 | 0 | if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) { |
2711 | | /* |
2712 | | * There's a send buffer item in the descriptor |
2713 | | * string, and the data count in the transaction |
2714 | | * is non-zero, so there's data to dissect. |
2715 | | */ |
2716 | |
|
2717 | 0 | if (lanman->req_data_item != NULL) { |
2718 | | /* |
2719 | | * Create a protocol tree item for the data. |
2720 | | */ |
2721 | 0 | data_item = (*lanman->req_data_item)(d_tvb, |
2722 | 0 | pinfo, tree, offset); |
2723 | 0 | data_tree = proto_item_add_subtree(data_item, |
2724 | 0 | *lanman->ett_req_data); |
2725 | 0 | } else { |
2726 | | /* |
2727 | | * Just leave it at the top level. |
2728 | | */ |
2729 | 0 | data_item = NULL; |
2730 | 0 | data_tree = tree; |
2731 | 0 | } |
2732 | | |
2733 | | /* data */ |
2734 | 0 | offset = dissect_transact_data(d_tvb, offset, -1, |
2735 | 0 | pinfo, data_tree, data_descrip, lanman->req_data, |
2736 | 0 | &aux_count, smb_info); /* XXX - what about strings? */ |
2737 | | |
2738 | | /* auxiliary data */ |
2739 | 0 | if (aux_data_descrip != NULL) { |
2740 | 0 | for (i = 0; i < aux_count; i++) { |
2741 | 0 | offset = dissect_transact_data(d_tvb, |
2742 | 0 | offset, -1, pinfo, data_tree, |
2743 | 0 | aux_data_descrip, |
2744 | 0 | lanman->req_aux_data, NULL, smb_info); |
2745 | 0 | } |
2746 | 0 | } |
2747 | |
|
2748 | 0 | if (data_item != NULL) { |
2749 | | /* |
2750 | | * Set the length of the protocol tree item |
2751 | | * for the data. |
2752 | | */ |
2753 | 0 | proto_item_set_len(data_item, offset); |
2754 | 0 | } |
2755 | 0 | } |
2756 | 0 | } else { |
2757 | | /* |
2758 | | * This is a response. |
2759 | | * Have we seen the request to which it's a response? |
2760 | | */ |
2761 | 0 | if (trp == NULL) |
2762 | 0 | return false; /* no - can't dissect it */ |
2763 | | |
2764 | | /* ok we have seen this one before */ |
2765 | | |
2766 | | /* if it looks like an interim response, update COL_INFO and return */ |
2767 | 0 | if( ( tvb_reported_length(p_tvb)==0 ) |
2768 | 0 | && ( tvb_reported_length(d_tvb)==0 ) ){ |
2769 | | /* command */ |
2770 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response", |
2771 | 0 | val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)")); |
2772 | |
|
2773 | 0 | proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd); |
2774 | 0 | return true; |
2775 | 0 | } |
2776 | | |
2777 | | /* command */ |
2778 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response", |
2779 | 0 | val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)")); |
2780 | |
|
2781 | 0 | proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, |
2782 | 0 | trp->lanman_cmd); |
2783 | |
|
2784 | 0 | lanman = find_lanman(trp->lanman_cmd); |
2785 | | |
2786 | | /* response parameters */ |
2787 | | |
2788 | | /* status */ |
2789 | 0 | status = tvb_get_letohs(p_tvb, offset); |
2790 | 0 | proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status); |
2791 | 0 | offset += 2; |
2792 | | |
2793 | | /* convert */ |
2794 | 0 | convert = tvb_get_letohs(p_tvb, offset); |
2795 | 0 | proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert); |
2796 | 0 | offset += 2; |
2797 | |
|
2798 | 0 | if (trp->param_descrip == NULL) { |
2799 | | /* |
2800 | | * This could happen if we only dissected |
2801 | | * part of the request to which this is a |
2802 | | * reply, e.g. if the request was split |
2803 | | * across TCP segments and we weren't doing |
2804 | | * TCP desegmentation, or if we had a snapshot |
2805 | | * length that was too short. |
2806 | | * |
2807 | | * We can't dissect the parameters; just show them |
2808 | | * as raw data. |
2809 | | */ |
2810 | 0 | proto_tree_add_item(tree, hf_param_no_descriptor, p_tvb, offset, -1, ENC_NA); |
2811 | | |
2812 | | /* |
2813 | | * We don't know whether we have a receive buffer, |
2814 | | * as we don't have the descriptor; just show what |
2815 | | * bytes purport to be data. |
2816 | | */ |
2817 | 0 | if (d_tvb && tvb_reported_length(d_tvb) > 0) { |
2818 | 0 | proto_tree_add_item(tree, hf_data_no_descriptor, d_tvb, 0, -1, ENC_NA); |
2819 | 0 | } |
2820 | 0 | } else { |
2821 | | /* rest of the parameters */ |
2822 | 0 | dissect_response_parameters(p_tvb, offset, |
2823 | 0 | pinfo, tree, trp->param_descrip, lanman->resp, |
2824 | 0 | &has_data, &has_ent_count, &ent_count, smb_info); |
2825 | | |
2826 | | /* data */ |
2827 | 0 | if (d_tvb && tvb_reported_length(d_tvb) > 0) { |
2828 | | /* |
2829 | | * Well, there are bytes that purport to |
2830 | | * be data, at least. |
2831 | | */ |
2832 | 0 | if (has_data) { |
2833 | | /* |
2834 | | * There's a receive buffer item |
2835 | | * in the descriptor string, so |
2836 | | * dissect it as response data. |
2837 | | */ |
2838 | 0 | dissect_response_data(d_tvb, pinfo, |
2839 | 0 | convert, tree, smb_info, lanman, |
2840 | 0 | has_ent_count, ent_count); |
2841 | 0 | } else { |
2842 | | /* |
2843 | | * There's no receive buffer item, |
2844 | | * but we do have data, so just |
2845 | | * show what bytes are data. |
2846 | | */ |
2847 | 0 | proto_tree_add_item(tree, hf_data_no_recv_buffer, d_tvb, 0, -1, ENC_NA); |
2848 | 0 | } |
2849 | 0 | } |
2850 | 0 | } |
2851 | 0 | } |
2852 | | |
2853 | 0 | return true; |
2854 | 0 | } |
2855 | | |
2856 | | void |
2857 | | proto_register_pipe_lanman(void) |
2858 | 14 | { |
2859 | 14 | static hf_register_info hf[] = { |
2860 | 14 | { &hf_function_code, |
2861 | 14 | { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC|BASE_EXT_STRING, |
2862 | 14 | &commands_ext, 0, "LANMAN Function Code/Command", HFILL }}, |
2863 | | |
2864 | 14 | { &hf_param_desc, |
2865 | 14 | { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE, |
2866 | 14 | NULL, 0, "LANMAN Parameter Descriptor", HFILL }}, |
2867 | | |
2868 | 14 | { &hf_return_desc, |
2869 | 14 | { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE, |
2870 | 14 | NULL, 0, "LANMAN Return Descriptor", HFILL }}, |
2871 | | |
2872 | 14 | { &hf_aux_data_desc, |
2873 | 14 | { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE, |
2874 | 14 | NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }}, |
2875 | | |
2876 | 14 | { &hf_detail_level, |
2877 | 14 | { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC, |
2878 | 14 | NULL, 0, "LANMAN Detail Level", HFILL }}, |
2879 | | |
2880 | 14 | { &hf_padding, |
2881 | 14 | { "Padding", "lanman.padding", FT_BYTES, BASE_NONE, |
2882 | 14 | NULL, 0, NULL, HFILL }}, |
2883 | | |
2884 | 14 | { &hf_recv_buf_len, |
2885 | 14 | { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC, |
2886 | 14 | NULL, 0, "LANMAN Receive Buffer Length", HFILL }}, |
2887 | | |
2888 | 14 | { &hf_send_buf_len, |
2889 | 14 | { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC, |
2890 | 14 | NULL, 0, "LANMAN Send Buffer Length", HFILL }}, |
2891 | | |
2892 | | #if 0 |
2893 | | { &hf_continuation_from, |
2894 | | { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC, |
2895 | | NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }}, |
2896 | | #endif |
2897 | | |
2898 | 14 | { &hf_status, |
2899 | 14 | { "Status", "lanman.status", FT_UINT16, BASE_DEC, |
2900 | 14 | VALS(status_vals), 0, "LANMAN Return status", HFILL }}, |
2901 | | |
2902 | 14 | { &hf_convert, |
2903 | 14 | { "Convert", "lanman.convert", FT_UINT16, BASE_DEC, |
2904 | 14 | NULL, 0, "LANMAN Convert", HFILL }}, |
2905 | | |
2906 | 14 | { &hf_param_no_descriptor, |
2907 | 14 | { "Parameters (no descriptor available)", "lanman.param_no_descriptor", FT_BYTES, BASE_NONE, |
2908 | 14 | NULL, 0, NULL, HFILL }}, |
2909 | | |
2910 | 14 | { &hf_data_no_descriptor, |
2911 | 14 | { "Data (no descriptor available)", "lanman.data_no_descriptor", FT_BYTES, BASE_NONE, |
2912 | 14 | NULL, 0, NULL, HFILL }}, |
2913 | | |
2914 | 14 | { &hf_data_no_recv_buffer, |
2915 | 14 | { "Data (no receive buffer)", "lanman.data_no_recv_buffer", FT_BYTES, BASE_NONE, |
2916 | 14 | NULL, 0, NULL, HFILL }}, |
2917 | | |
2918 | 14 | { &hf_ecount, |
2919 | 14 | { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC, |
2920 | 14 | NULL, 0, "LANMAN Number of Entries", HFILL }}, |
2921 | | |
2922 | 14 | { &hf_acount, |
2923 | 14 | { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC, |
2924 | 14 | NULL, 0, "LANMAN Number of Available Entries", HFILL }}, |
2925 | | |
2926 | 14 | { &hf_share, |
2927 | 14 | { "Share", "lanman.share", FT_NONE, BASE_NONE, |
2928 | 14 | NULL, 0, NULL, HFILL }}, |
2929 | | |
2930 | 14 | { &hf_share_name, |
2931 | 14 | { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE, |
2932 | 14 | NULL, 0, "LANMAN Name of Share", HFILL }}, |
2933 | | |
2934 | 14 | { &hf_share_type, |
2935 | 14 | { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC, |
2936 | 14 | VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }}, |
2937 | | |
2938 | 14 | { &hf_share_comment, |
2939 | 14 | { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE, |
2940 | 14 | NULL, 0, "LANMAN Share Comment", HFILL }}, |
2941 | | |
2942 | 14 | { &hf_share_permissions, |
2943 | 14 | { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC, |
2944 | 14 | NULL, 0, "LANMAN Permissions on share", HFILL }}, |
2945 | | |
2946 | 14 | { &hf_share_max_uses, |
2947 | 14 | { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC, |
2948 | 14 | NULL, 0, "LANMAN Max connections allowed to share", HFILL }}, |
2949 | | |
2950 | 14 | { &hf_share_current_uses, |
2951 | 14 | { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC, |
2952 | 14 | NULL, 0, "LANMAN Current connections to share", HFILL }}, |
2953 | | |
2954 | 14 | { &hf_share_path, |
2955 | 14 | { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE, |
2956 | 14 | NULL, 0, "LANMAN Share Path", HFILL }}, |
2957 | | |
2958 | 14 | { &hf_share_password, |
2959 | 14 | { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE, |
2960 | 14 | NULL, 0, "LANMAN Share Password", HFILL }}, |
2961 | | |
2962 | 14 | { &hf_server, |
2963 | 14 | { "Server", "lanman.server", FT_NONE, BASE_NONE, |
2964 | 14 | NULL, 0, NULL, HFILL }}, |
2965 | | |
2966 | 14 | { &hf_server_name, |
2967 | 14 | { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE, |
2968 | 14 | NULL, 0, "LANMAN Name of Server", HFILL }}, |
2969 | | |
2970 | 14 | { &hf_server_major, |
2971 | 14 | { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC, |
2972 | 14 | NULL, 0, "LANMAN Server Major Version", HFILL }}, |
2973 | | |
2974 | 14 | { &hf_server_minor, |
2975 | 14 | { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC, |
2976 | 14 | NULL, 0, "LANMAN Server Minor Version", HFILL }}, |
2977 | | |
2978 | 14 | { &hf_server_comment, |
2979 | 14 | { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE, |
2980 | 14 | NULL, 0, "LANMAN Server Comment", HFILL }}, |
2981 | | |
2982 | 14 | { &hf_abytes, |
2983 | 14 | { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC, |
2984 | 14 | NULL, 0, "LANMAN Number of Available Bytes", HFILL }}, |
2985 | | |
2986 | 14 | { &hf_current_time, |
2987 | 14 | { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
2988 | 14 | NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }}, |
2989 | | |
2990 | 14 | { &hf_msecs, |
2991 | 14 | { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC, |
2992 | 14 | NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }}, |
2993 | | |
2994 | 14 | { &hf_hour, |
2995 | 14 | { "Hour", "lanman.hour", FT_UINT8, BASE_DEC, |
2996 | 14 | NULL, 0, "LANMAN Current hour", HFILL }}, |
2997 | | |
2998 | 14 | { &hf_minute, |
2999 | 14 | { "Minute", "lanman.minute", FT_UINT8, BASE_DEC, |
3000 | 14 | NULL, 0, "LANMAN Current minute", HFILL }}, |
3001 | | |
3002 | 14 | { &hf_second, |
3003 | 14 | { "Second", "lanman.second", FT_UINT8, BASE_DEC, |
3004 | 14 | NULL, 0, "LANMAN Current second", HFILL }}, |
3005 | | |
3006 | 14 | { &hf_hundredths, |
3007 | 14 | { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC, |
3008 | 14 | NULL, 0, "LANMAN Current hundredths of a second", HFILL }}, |
3009 | | |
3010 | 14 | { &hf_tzoffset, |
3011 | 14 | { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC, |
3012 | 14 | NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }}, |
3013 | | |
3014 | 14 | { &hf_timeinterval, |
3015 | 14 | { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC, |
3016 | 14 | NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }}, |
3017 | | |
3018 | 14 | { &hf_day, |
3019 | 14 | { "Day", "lanman.day", FT_UINT8, BASE_DEC, |
3020 | 14 | NULL, 0, "LANMAN Current day", HFILL }}, |
3021 | | |
3022 | 14 | { &hf_month, |
3023 | 14 | { "Month", "lanman.month", FT_UINT8, BASE_DEC, |
3024 | 14 | NULL, 0, "LANMAN Current month", HFILL }}, |
3025 | | |
3026 | 14 | { &hf_year, |
3027 | 14 | { "Year", "lanman.year", FT_UINT16, BASE_DEC, |
3028 | 14 | NULL, 0, "LANMAN Current year", HFILL }}, |
3029 | | |
3030 | 14 | { &hf_weekday, |
3031 | 14 | { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC, |
3032 | 14 | VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }}, |
3033 | | |
3034 | 14 | { &hf_enumeration_domain, |
3035 | 14 | { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE, |
3036 | 14 | NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }}, |
3037 | | |
3038 | 14 | { &hf_last_entry, |
3039 | 14 | { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE, |
3040 | 14 | NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }}, |
3041 | | |
3042 | 14 | { &hf_computer_name, |
3043 | 14 | { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE, |
3044 | 14 | NULL, 0, "LANMAN Computer Name", HFILL }}, |
3045 | | |
3046 | 14 | { &hf_user_name, |
3047 | 14 | { "User Name", "lanman.user_name", FT_STRING, BASE_NONE, |
3048 | 14 | NULL, 0, "LANMAN User Name", HFILL }}, |
3049 | | |
3050 | 14 | { &hf_group_name, |
3051 | 14 | { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE, |
3052 | 14 | NULL, 0, "LANMAN Group Name", HFILL }}, |
3053 | | |
3054 | 14 | { &hf_workstation_domain, |
3055 | 14 | { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE, |
3056 | 14 | NULL, 0, "LANMAN Workstation Domain", HFILL }}, |
3057 | | |
3058 | 14 | { &hf_workstation_major, |
3059 | 14 | { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC, |
3060 | 14 | NULL, 0, "LANMAN Workstation Major Version", HFILL }}, |
3061 | | |
3062 | 14 | { &hf_workstation_minor, |
3063 | 14 | { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC, |
3064 | 14 | NULL, 0, "LANMAN Workstation Minor Version", HFILL }}, |
3065 | | |
3066 | 14 | { &hf_logon_domain, |
3067 | 14 | { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE, |
3068 | 14 | NULL, 0, "LANMAN Logon Domain", HFILL }}, |
3069 | | |
3070 | 14 | { &hf_other_domains, |
3071 | 14 | { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE, |
3072 | 14 | NULL, 0, "LANMAN Other Domains", HFILL }}, |
3073 | | |
3074 | 14 | { &hf_password, |
3075 | 14 | { "Password", "lanman.password", FT_STRING, BASE_NONE, |
3076 | 14 | NULL, 0, "LANMAN Password", HFILL }}, |
3077 | | |
3078 | 14 | { &hf_workstation_name, |
3079 | 14 | { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE, |
3080 | 14 | NULL, 0, "LANMAN Workstation Name", HFILL }}, |
3081 | | |
3082 | 14 | { &hf_ustruct_size, |
3083 | 14 | { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC, |
3084 | 14 | NULL, 0, "LANMAN UStruct Length", HFILL }}, |
3085 | | |
3086 | 14 | { &hf_logon_code, |
3087 | 14 | { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC, |
3088 | 14 | VALS(status_vals), 0, "LANMAN Logon Code", HFILL }}, |
3089 | | |
3090 | 14 | { &hf_privilege_level, |
3091 | 14 | { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC, |
3092 | 14 | VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }}, |
3093 | | |
3094 | 14 | { &hf_operator_privileges, |
3095 | 14 | { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC, |
3096 | 14 | VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }}, |
3097 | | |
3098 | 14 | { &hf_num_logons, |
3099 | 14 | { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC, |
3100 | 14 | NULL, 0, "LANMAN Number of Logons", HFILL }}, |
3101 | | |
3102 | 14 | { &hf_bad_pw_count, |
3103 | 14 | { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC, |
3104 | 14 | NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }}, |
3105 | | |
3106 | 14 | { &hf_last_logon, |
3107 | 14 | { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3108 | 14 | NULL, 0, "LANMAN Date and time of last logon", HFILL }}, |
3109 | | |
3110 | 14 | { &hf_last_logoff, |
3111 | 14 | { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3112 | 14 | NULL, 0, "LANMAN Date and time of last logoff", HFILL }}, |
3113 | | |
3114 | 14 | { &hf_logoff_time, |
3115 | 14 | { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3116 | 14 | NULL, 0, "LANMAN Date and time when user should log off", HFILL }}, |
3117 | | |
3118 | 14 | { &hf_kickoff_time, |
3119 | 14 | { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3120 | 14 | NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }}, |
3121 | | |
3122 | 14 | { &hf_password_age, |
3123 | 14 | { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE, |
3124 | 14 | NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }}, |
3125 | | |
3126 | 14 | { &hf_password_can_change, |
3127 | 14 | { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3128 | 14 | NULL, 0, "LANMAN Date and time when user can change their password", HFILL }}, |
3129 | | |
3130 | 14 | { &hf_password_must_change, |
3131 | 14 | { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, |
3132 | 14 | NULL, 0, "LANMAN Date and time when user must change their password", HFILL }}, |
3133 | | |
3134 | 14 | { &hf_script_path, |
3135 | 14 | { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE, |
3136 | 14 | NULL, 0, "LANMAN Pathname of user's logon script", HFILL }}, |
3137 | | |
3138 | 14 | { &hf_logoff_code, |
3139 | 14 | { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC, |
3140 | 14 | VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }}, |
3141 | | |
3142 | 14 | { &hf_duration, |
3143 | 14 | { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE, |
3144 | 14 | NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }}, |
3145 | | |
3146 | 14 | { &hf_comment, |
3147 | 14 | { "Comment", "lanman.comment", FT_STRING, BASE_NONE, |
3148 | 14 | NULL, 0, "LANMAN Comment", HFILL }}, |
3149 | | |
3150 | 14 | { &hf_user_comment, |
3151 | 14 | { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE, |
3152 | 14 | NULL, 0, "LANMAN User Comment", HFILL }}, |
3153 | | |
3154 | 14 | { &hf_full_name, |
3155 | 14 | { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE, |
3156 | 14 | NULL, 0, "LANMAN Full Name", HFILL }}, |
3157 | | |
3158 | 14 | { &hf_homedir, |
3159 | 14 | { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE, |
3160 | 14 | NULL, 0, "LANMAN Home Directory", HFILL }}, |
3161 | | |
3162 | 14 | { &hf_parameters, |
3163 | 14 | { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE, |
3164 | 14 | NULL, 0, "LANMAN Parameters", HFILL }}, |
3165 | | |
3166 | 14 | { &hf_logon_server, |
3167 | 14 | { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE, |
3168 | 14 | NULL, 0, "LANMAN Logon Server", HFILL }}, |
3169 | | |
3170 | 14 | { &hf_country_code, |
3171 | 14 | { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC | BASE_EXT_STRING, |
3172 | 14 | &ms_country_codes_ext, 0, "LANMAN Country Code", HFILL }}, |
3173 | | |
3174 | 14 | { &hf_workstations, |
3175 | 14 | { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE, |
3176 | 14 | NULL, 0, "LANMAN Workstations", HFILL }}, |
3177 | | |
3178 | 14 | { &hf_max_storage, |
3179 | 14 | { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC, |
3180 | 14 | NULL, 0, "LANMAN Max Storage", HFILL }}, |
3181 | | |
3182 | 14 | { &hf_units_per_week, |
3183 | 14 | { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC, |
3184 | 14 | NULL, 0, "LANMAN Units Per Week", HFILL }}, |
3185 | | |
3186 | 14 | { &hf_logon_hours, |
3187 | 14 | { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE, |
3188 | 14 | NULL, 0, "LANMAN Logon Hours", HFILL }}, |
3189 | | |
3190 | | /* XXX - we should have a value_string table for this */ |
3191 | 14 | { &hf_code_page, |
3192 | 14 | { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC, |
3193 | 14 | NULL, 0, "LANMAN Code Page", HFILL }}, |
3194 | | |
3195 | 14 | { &hf_new_password, |
3196 | 14 | { "New Password", "lanman.new_password", FT_BYTES, BASE_NONE, |
3197 | 14 | NULL, 0, "LANMAN New Password (encrypted)", HFILL }}, |
3198 | | |
3199 | 14 | { &hf_old_password, |
3200 | 14 | { "Old Password", "lanman.old_password", FT_BYTES, BASE_NONE, |
3201 | 14 | NULL, 0, "LANMAN Old Password (encrypted)", HFILL }}, |
3202 | | |
3203 | 14 | { &hf_reserved, |
3204 | 14 | { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX, |
3205 | 14 | NULL, 0, "LANMAN Reserved", HFILL }}, |
3206 | | |
3207 | 14 | { &hf_aux_data_struct_count, |
3208 | 14 | { "Auxiliary data structure count", "lanman.aux_data_struct_count", FT_UINT16, BASE_DEC_HEX, |
3209 | 14 | NULL, 0, NULL, HFILL }}, |
3210 | | |
3211 | 14 | }; |
3212 | 14 | static int *ett[] = { |
3213 | 14 | &ett_lanman, |
3214 | 14 | &ett_lanman_unknown_entries, |
3215 | 14 | &ett_lanman_unknown_entry, |
3216 | 14 | &ett_lanman_servers, |
3217 | 14 | &ett_lanman_server, |
3218 | 14 | &ett_lanman_groups, |
3219 | 14 | &ett_lanman_shares, |
3220 | 14 | &ett_lanman_share, |
3221 | 14 | }; |
3222 | | |
3223 | 14 | proto_smb_lanman = proto_register_protocol("Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman"); |
3224 | 14 | proto_register_field_array(proto_smb_lanman, hf, array_length(hf)); |
3225 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
3226 | 14 | } |
3227 | | |
3228 | | static heur_dissector_list_t smb_transact_heur_subdissector_list; |
3229 | | |
3230 | | static reassembly_table dcerpc_reassembly_table; |
3231 | | |
3232 | | bool |
3233 | | dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree, |
3234 | | proto_tree *tree, uint32_t fid, void *data) |
3235 | 15 | { |
3236 | 15 | bool result=false; |
3237 | 15 | bool save_fragmented; |
3238 | 15 | unsigned reported_len; |
3239 | | |
3240 | 15 | fragment_head *fd_head; |
3241 | 15 | fragment_item *fd_i; |
3242 | 15 | tvbuff_t *new_tvb; |
3243 | 15 | proto_item *frag_tree_item; |
3244 | | |
3245 | 15 | heur_dtbl_entry_t *hdtbl_entry; |
3246 | | |
3247 | 15 | dcerpc_set_transport_salt(fid, pinfo); |
3248 | | |
3249 | | /* |
3250 | | * Offer desegmentation service to DCERPC if we have all the |
3251 | | * data. Otherwise, reassembly is (probably) impossible. |
3252 | | */ |
3253 | 15 | pinfo->can_desegment=0; |
3254 | 15 | pinfo->desegment_offset = 0; |
3255 | 15 | pinfo->desegment_len = 0; |
3256 | 15 | reported_len = tvb_reported_length(d_tvb); |
3257 | 15 | if(smb_dcerpc_reassembly && tvb_captured_length(d_tvb) >= reported_len){ |
3258 | 5 | pinfo->can_desegment=2; |
3259 | 5 | } |
3260 | | |
3261 | 15 | save_fragmented = pinfo->fragmented; |
3262 | | |
3263 | | |
3264 | | /* if we are not offering desegmentation, just try the heuristics |
3265 | | and bail out |
3266 | | */ |
3267 | 15 | if(!pinfo->can_desegment){ |
3268 | 10 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3269 | 10 | goto clean_up_and_exit; |
3270 | 10 | } |
3271 | | |
3272 | | |
3273 | | /* below this line, we know we are doing reassembly */ |
3274 | | |
3275 | | /* this is a new packet, see if we are already reassembling this |
3276 | | pdu and if not, check if the dissector wants us |
3277 | | to reassemble it |
3278 | | */ |
3279 | 5 | if(!pinfo->fd->visited){ |
3280 | | /* |
3281 | | * This is the first pass. |
3282 | | * |
3283 | | * Check if we are already reassembling this PDU or not; |
3284 | | * we check for an in-progress reassembly for this FID |
3285 | | * in this direction, by searching for its reassembly |
3286 | | * structure. |
3287 | | */ |
3288 | 5 | fd_head=fragment_get(&dcerpc_reassembly_table, pinfo, fid, NULL); |
3289 | 5 | if(!fd_head){ |
3290 | | /* No reassembly, so this is a new pdu. check if the |
3291 | | dissector wants us to reassemble it or if we |
3292 | | already got the full pdu in this tvb. |
3293 | | */ |
3294 | | |
3295 | | /* |
3296 | | * Try the heuristic dissectors and see if we |
3297 | | * find someone that recognizes this payload. |
3298 | | */ |
3299 | 5 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3300 | | |
3301 | | /* no this didn't look like something we know */ |
3302 | 5 | if(!result){ |
3303 | 5 | goto clean_up_and_exit; |
3304 | 5 | } |
3305 | | |
3306 | | /* did the subdissector want us to reassemble any |
3307 | | more data ? |
3308 | | */ |
3309 | 0 | if(pinfo->desegment_len){ |
3310 | 0 | fragment_add_check(&dcerpc_reassembly_table, |
3311 | 0 | d_tvb, 0, pinfo, fid, NULL, |
3312 | 0 | 0, reported_len, true); |
3313 | 0 | fragment_set_tot_len(&dcerpc_reassembly_table, |
3314 | 0 | pinfo, fid, NULL, |
3315 | 0 | pinfo->desegment_len+reported_len); |
3316 | 0 | } |
3317 | 0 | goto clean_up_and_exit; |
3318 | 5 | } |
3319 | | |
3320 | | /* OK, we're already doing a reassembly for this FID. |
3321 | | skip to last segment in the existing reassembly structure |
3322 | | and add this fragment there |
3323 | | |
3324 | | XXX we might add code here to use any offset values |
3325 | | we might pick up from the Read/Write calls instead of |
3326 | | assuming we always get them in the correct order |
3327 | | */ |
3328 | 0 | for (fd_i = fd_head->next; fd_i->next; fd_i = fd_i->next) {} |
3329 | 0 | fd_head=fragment_add_check(&dcerpc_reassembly_table, |
3330 | 0 | d_tvb, 0, pinfo, fid, NULL, |
3331 | 0 | fd_i->offset+fd_i->len, |
3332 | 0 | reported_len, true); |
3333 | | |
3334 | | /* if we completed reassembly */ |
3335 | 0 | if(fd_head){ |
3336 | 0 | new_tvb = tvb_new_chain(d_tvb, fd_head->tvb_data); |
3337 | 0 | add_new_data_source(pinfo, new_tvb, |
3338 | 0 | "DCERPC over SMB"); |
3339 | 0 | pinfo->fragmented=false; |
3340 | |
|
3341 | 0 | d_tvb=new_tvb; |
3342 | | |
3343 | | /* list what segments we have */ |
3344 | 0 | show_fragment_tree(fd_head, &smb_pipe_frag_items, |
3345 | 0 | tree, pinfo, d_tvb, &frag_tree_item); |
3346 | | |
3347 | | /* dissect the full PDU */ |
3348 | 0 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3349 | 0 | } |
3350 | 0 | goto clean_up_and_exit; |
3351 | 5 | } |
3352 | | |
3353 | | /* |
3354 | | * This is not the first pass; see if it's in the table of |
3355 | | * reassembled packets. |
3356 | | * |
3357 | | * XXX - we know that several of the arguments aren't going to |
3358 | | * be used, so we pass bogus variables. Can we clean this |
3359 | | * up so that we don't have to distinguish between the first |
3360 | | * pass and subsequent passes? |
3361 | | */ |
3362 | 0 | fd_head=fragment_add_check(&dcerpc_reassembly_table, |
3363 | 0 | d_tvb, 0, pinfo, fid, NULL, 0, 0, true); |
3364 | 0 | if(!fd_head){ |
3365 | | /* we didn't find it, try any of the heuristic dissectors |
3366 | | and bail out |
3367 | | */ |
3368 | 0 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3369 | 0 | goto clean_up_and_exit; |
3370 | 0 | } |
3371 | 0 | if(!(fd_head->flags&FD_DEFRAGMENTED)){ |
3372 | | /* we don't have a fully reassembled frame */ |
3373 | 0 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3374 | 0 | goto clean_up_and_exit; |
3375 | 0 | } |
3376 | | |
3377 | | /* it is reassembled but it was reassembled in a different frame */ |
3378 | 0 | if(pinfo->num!=fd_head->reassembled_in){ |
3379 | 0 | proto_tree_add_uint(parent_tree, hf_smb_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in); |
3380 | 0 | goto clean_up_and_exit; |
3381 | 0 | } |
3382 | | |
3383 | | |
3384 | | /* display the reassembled pdu */ |
3385 | 0 | new_tvb = tvb_new_chain(d_tvb, fd_head->tvb_data); |
3386 | 0 | add_new_data_source(pinfo, new_tvb, |
3387 | 0 | "DCERPC over SMB"); |
3388 | 0 | pinfo->fragmented=false; |
3389 | |
|
3390 | 0 | d_tvb=new_tvb; |
3391 | | |
3392 | | /* list what segments we have */ |
3393 | 0 | show_fragment_tree(fd_head, &smb_pipe_frag_items, |
3394 | 0 | tree, pinfo, d_tvb, &frag_tree_item); |
3395 | | |
3396 | | /* dissect the full PDU */ |
3397 | 0 | result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data); |
3398 | | |
3399 | | |
3400 | |
|
3401 | 15 | clean_up_and_exit: |
3402 | | /* clear out the variables */ |
3403 | 15 | pinfo->can_desegment=0; |
3404 | 15 | pinfo->desegment_offset = 0; |
3405 | 15 | pinfo->desegment_len = 0; |
3406 | | |
3407 | 15 | if (!result) |
3408 | 15 | call_data_dissector(d_tvb, pinfo, parent_tree); |
3409 | | |
3410 | 15 | pinfo->fragmented = save_fragmented; |
3411 | 15 | return true; |
3412 | 0 | } |
3413 | | |
3414 | 0 | #define CALL_NAMED_PIPE 0x54 |
3415 | 0 | #define WAIT_NAMED_PIPE 0x53 |
3416 | 0 | #define PEEK_NAMED_PIPE 0x23 |
3417 | 0 | #define Q_NM_P_HAND_STATE 0x21 |
3418 | 0 | #define SET_NM_P_HAND_STATE 0x01 |
3419 | 0 | #define Q_NM_PIPE_INFO 0x22 |
3420 | 0 | #define TRANSACT_NM_PIPE 0x26 |
3421 | 0 | #define RAW_READ_NM_PIPE 0x11 |
3422 | 0 | #define RAW_WRITE_NM_PIPE 0x31 |
3423 | | |
3424 | | static const value_string functions[] = { |
3425 | | {CALL_NAMED_PIPE, "CallNamedPipe"}, |
3426 | | {WAIT_NAMED_PIPE, "WaitNamedPipe"}, |
3427 | | {PEEK_NAMED_PIPE, "PeekNamedPipe"}, |
3428 | | {Q_NM_P_HAND_STATE, "QNmPHandState"}, |
3429 | | {SET_NM_P_HAND_STATE, "SetNmPHandState"}, |
3430 | | {Q_NM_PIPE_INFO, "QNmPipeInfo"}, |
3431 | | {TRANSACT_NM_PIPE, "TransactNmPipe"}, |
3432 | | {RAW_READ_NM_PIPE, "RawReadNmPipe"}, |
3433 | | {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"}, |
3434 | | {0, NULL} |
3435 | | }; |
3436 | | |
3437 | | static const value_string pipe_status[] = { |
3438 | | {1, "Disconnected by server"}, |
3439 | | {2, "Listening"}, |
3440 | | {3, "Connection to server is OK"}, |
3441 | | {4, "Server end of pipe is closed"}, |
3442 | | {0, NULL} |
3443 | | }; |
3444 | | |
3445 | 0 | #define PIPE_LANMAN 1 |
3446 | 0 | #define PIPE_DCERPC 2 |
3447 | | |
3448 | | /* decode the SMB pipe protocol |
3449 | | for requests |
3450 | | pipe is the name of the pipe, e.g. LANMAN |
3451 | | smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name |
3452 | | for responses |
3453 | | pipe is NULL |
3454 | | smb_info->trans_subcmd gives us which pipe this response is for |
3455 | | */ |
3456 | | bool |
3457 | | dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb, |
3458 | | tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe, |
3459 | | packet_info *pinfo, proto_tree *tree, smb_info_t *smb_info) |
3460 | 0 | { |
3461 | 0 | smb_transact_info_t *tri; |
3462 | 0 | unsigned sp_len; |
3463 | 0 | proto_item *pipe_item = NULL; |
3464 | 0 | proto_tree *pipe_tree = NULL; |
3465 | 0 | int offset; |
3466 | 0 | int trans_subcmd=0; |
3467 | 0 | int function; |
3468 | 0 | int fid = -1; |
3469 | 0 | uint16_t info_level; |
3470 | |
|
3471 | 0 | if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe))) |
3472 | 0 | return false; |
3473 | 0 | pinfo->current_proto = "SMB Pipe"; |
3474 | | |
3475 | | /* |
3476 | | * Set the columns. |
3477 | | */ |
3478 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe"); |
3479 | 0 | col_set_str(pinfo->cinfo, COL_INFO, |
3480 | 0 | smb_info->request ? "Request" : "Response"); |
3481 | |
|
3482 | 0 | if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI) |
3483 | 0 | tri = (smb_transact_info_t *)smb_info->sip->extra_info; |
3484 | 0 | else |
3485 | 0 | tri = NULL; |
3486 | | |
3487 | | /* |
3488 | | * Set up a subtree for the pipe protocol. (It might not contain |
3489 | | * anything.) |
3490 | | */ |
3491 | 0 | if (sp_tvb != NULL) |
3492 | 0 | sp_len = tvb_captured_length(sp_tvb); |
3493 | 0 | else |
3494 | 0 | sp_len = 0; |
3495 | 0 | if (tree) { |
3496 | 0 | pipe_item = proto_tree_add_item(tree, proto_smb_pipe, |
3497 | 0 | sp_tvb, 0, sp_len, ENC_NA); |
3498 | 0 | pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe); |
3499 | 0 | } |
3500 | 0 | offset = 0; |
3501 | | |
3502 | | /* |
3503 | | * Do we have any setup words at all? |
3504 | | */ |
3505 | 0 | if (s_tvb != NULL && tvb_reported_length(s_tvb) != 0) { |
3506 | | /* |
3507 | | * Yes. The first of them is the function. |
3508 | | */ |
3509 | 0 | function = tvb_get_letohs(s_tvb, offset); |
3510 | 0 | proto_tree_add_uint(pipe_tree, hf_smb_pipe_function, s_tvb, |
3511 | 0 | offset, 2, function); |
3512 | 0 | offset += 2; |
3513 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", |
3514 | 0 | val_to_str(function, functions, "Unknown function (0x%04x)"), |
3515 | 0 | smb_info->request ? "Request" : "Response"); |
3516 | |
|
3517 | 0 | if (tri != NULL) |
3518 | 0 | tri->function = function; |
3519 | | |
3520 | | /* |
3521 | | * The second of them depends on the function. |
3522 | | */ |
3523 | 0 | switch (function) { |
3524 | | |
3525 | 0 | case CALL_NAMED_PIPE: |
3526 | 0 | case WAIT_NAMED_PIPE: |
3527 | | /* |
3528 | | * It's a priority. |
3529 | | */ |
3530 | 0 | proto_tree_add_item(pipe_tree, hf_smb_pipe_priority, s_tvb, |
3531 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
3532 | 0 | break; |
3533 | | |
3534 | 0 | case PEEK_NAMED_PIPE: |
3535 | 0 | case Q_NM_P_HAND_STATE: |
3536 | 0 | case SET_NM_P_HAND_STATE: |
3537 | 0 | case Q_NM_PIPE_INFO: |
3538 | 0 | case TRANSACT_NM_PIPE: |
3539 | 0 | case RAW_READ_NM_PIPE: |
3540 | 0 | case RAW_WRITE_NM_PIPE: |
3541 | | /* |
3542 | | * It's a FID. |
3543 | | */ |
3544 | 0 | fid = tvb_get_letohs(s_tvb, 2); |
3545 | 0 | dissect_smb_fid(s_tvb, pinfo, pipe_tree, offset, 2, (uint16_t) fid, false, false, false, smb_info); |
3546 | 0 | if (tri != NULL) |
3547 | 0 | tri->fid = fid; |
3548 | 0 | break; |
3549 | | |
3550 | 0 | default: |
3551 | | /* |
3552 | | * It's something unknown. |
3553 | | * XXX - put it into the tree? |
3554 | | */ |
3555 | 0 | break; |
3556 | 0 | } |
3557 | 0 | } else { |
3558 | | /* |
3559 | | * This is either a response or a pipe transaction with |
3560 | | * no setup information. |
3561 | | * |
3562 | | * In the former case, we can get that information from |
3563 | | * the matching request, if we saw it. |
3564 | | * |
3565 | | * In the latter case, there is no function or FID. |
3566 | | */ |
3567 | 0 | if (tri != NULL && tri->function != -1) { |
3568 | 0 | function = tri->function; |
3569 | 0 | proto_tree_add_uint(pipe_tree, hf_smb_pipe_function, NULL, |
3570 | 0 | 0, 0, function); |
3571 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", |
3572 | 0 | val_to_str(function, functions, "Unknown function (0x%04x)"), |
3573 | 0 | smb_info->request ? "Request" : "Response"); |
3574 | |
|
3575 | 0 | fid = tri->fid; |
3576 | 0 | if (fid != -1) |
3577 | 0 | dissect_smb_fid(d_tvb, pinfo, pipe_tree, 0, 0, (uint16_t) fid, false, false, true, smb_info); |
3578 | 0 | } else { |
3579 | 0 | function = -1; |
3580 | 0 | fid = -1; |
3581 | 0 | } |
3582 | 0 | } |
3583 | | |
3584 | | /* |
3585 | | * XXX - put the byte count and the pipe name into the tree as well; |
3586 | | * that requires us to fetch a possibly-Unicode string. |
3587 | | */ |
3588 | | |
3589 | 0 | if(smb_info->request){ |
3590 | 0 | if(strncmp(pipe,"LANMAN",6) == 0){ |
3591 | 0 | trans_subcmd=PIPE_LANMAN; |
3592 | 0 | } else { |
3593 | | /* assume it is DCERPC */ |
3594 | 0 | trans_subcmd=PIPE_DCERPC; |
3595 | 0 | } |
3596 | |
|
3597 | 0 | if (!pinfo->fd->visited) { |
3598 | 0 | if (tri == NULL) |
3599 | 0 | return false; |
3600 | 0 | tri->trans_subcmd = trans_subcmd; |
3601 | 0 | } |
3602 | 0 | } else { |
3603 | 0 | if(tri == NULL) |
3604 | 0 | return false; |
3605 | 0 | trans_subcmd = tri->trans_subcmd; |
3606 | 0 | } |
3607 | | |
3608 | 0 | if (tri == NULL) { |
3609 | | /* |
3610 | | * We don't know what type of pipe transaction this |
3611 | | * was, so indicate that we didn't dissect it. |
3612 | | */ |
3613 | 0 | return false; |
3614 | 0 | } |
3615 | | |
3616 | 0 | switch (function) { |
3617 | | |
3618 | 0 | case CALL_NAMED_PIPE: |
3619 | 0 | case TRANSACT_NM_PIPE: |
3620 | 0 | switch(trans_subcmd){ |
3621 | | |
3622 | 0 | case PIPE_LANMAN: |
3623 | 0 | return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo, tree, smb_info); |
3624 | | |
3625 | 0 | case PIPE_DCERPC: |
3626 | | /* |
3627 | | * Only dissect this if we know the FID. |
3628 | | */ |
3629 | 0 | if (fid != -1) { |
3630 | 0 | if (d_tvb == NULL) |
3631 | 0 | return false; |
3632 | 0 | return dissect_pipe_dcerpc(d_tvb, pinfo, tree, pipe_tree, fid, smb_info); |
3633 | 0 | } |
3634 | 0 | break; |
3635 | 0 | } |
3636 | 0 | break; |
3637 | | |
3638 | 0 | case -1: |
3639 | | /* |
3640 | | * We don't know the function; we dissect only LANMAN |
3641 | | * pipe messages, not RPC pipe messages, in that case. |
3642 | | */ |
3643 | 0 | switch(trans_subcmd){ |
3644 | 0 | case PIPE_LANMAN: |
3645 | 0 | return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo, tree, smb_info); |
3646 | 0 | } |
3647 | 0 | break; |
3648 | | |
3649 | 0 | case WAIT_NAMED_PIPE: |
3650 | 0 | break; |
3651 | | |
3652 | 0 | case PEEK_NAMED_PIPE: |
3653 | | /* |
3654 | | * Request contains no parameters or data. |
3655 | | */ |
3656 | 0 | if (!smb_info->request) { |
3657 | 0 | if (p_tvb == NULL) |
3658 | 0 | return false; |
3659 | 0 | offset = 0; |
3660 | 0 | proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_available, |
3661 | 0 | p_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3662 | 0 | offset += 2; |
3663 | 0 | proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_remaining, |
3664 | 0 | p_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3665 | 0 | offset += 2; |
3666 | 0 | proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_status, |
3667 | 0 | p_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3668 | 0 | } |
3669 | 0 | break; |
3670 | | |
3671 | 0 | case Q_NM_P_HAND_STATE: |
3672 | | /* |
3673 | | * Request contains no parameters or data. |
3674 | | */ |
3675 | 0 | if (!smb_info->request) { |
3676 | 0 | if (p_tvb == NULL) |
3677 | 0 | return false; |
3678 | 0 | dissect_ipc_state(p_tvb, pipe_tree, 0, false); |
3679 | 0 | } |
3680 | 0 | break; |
3681 | | |
3682 | 0 | case SET_NM_P_HAND_STATE: |
3683 | | /* |
3684 | | * Response contains no parameters or data. |
3685 | | */ |
3686 | 0 | if (smb_info->request) { |
3687 | 0 | if (p_tvb == NULL) |
3688 | 0 | return false; |
3689 | 0 | dissect_ipc_state(p_tvb, pipe_tree, 0, true); |
3690 | 0 | } |
3691 | 0 | break; |
3692 | | |
3693 | 0 | case Q_NM_PIPE_INFO: |
3694 | 0 | offset = 0; |
3695 | 0 | if (smb_info->request) { |
3696 | 0 | if (p_tvb == NULL) |
3697 | 0 | return false; |
3698 | | |
3699 | | /* |
3700 | | * Request contains an information level. |
3701 | | */ |
3702 | 0 | info_level = tvb_get_letohs(p_tvb, offset); |
3703 | 0 | proto_tree_add_uint(pipe_tree, hf_smb_pipe_getinfo_info_level, |
3704 | 0 | p_tvb, offset, 2, info_level); |
3705 | 0 | if (!pinfo->fd->visited) |
3706 | 0 | tri->info_level = info_level; |
3707 | 0 | } else { |
3708 | 0 | uint8_t pipe_namelen; |
3709 | |
|
3710 | 0 | if (d_tvb == NULL) |
3711 | 0 | return false; |
3712 | | |
3713 | 0 | switch (tri->info_level) { |
3714 | | |
3715 | 0 | case 1: |
3716 | 0 | proto_tree_add_item(pipe_tree, |
3717 | 0 | hf_smb_pipe_getinfo_output_buffer_size, |
3718 | 0 | d_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3719 | 0 | offset += 2; |
3720 | 0 | proto_tree_add_item(pipe_tree, |
3721 | 0 | hf_smb_pipe_getinfo_input_buffer_size, |
3722 | 0 | d_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3723 | 0 | offset += 2; |
3724 | 0 | proto_tree_add_item(pipe_tree, |
3725 | 0 | hf_smb_pipe_getinfo_maximum_instances, |
3726 | 0 | d_tvb, offset, 1, ENC_LITTLE_ENDIAN); |
3727 | 0 | offset += 1; |
3728 | 0 | proto_tree_add_item(pipe_tree, |
3729 | 0 | hf_smb_pipe_getinfo_current_instances, |
3730 | 0 | d_tvb, offset, 1, ENC_LITTLE_ENDIAN); |
3731 | 0 | offset += 1; |
3732 | 0 | pipe_namelen = tvb_get_uint8(d_tvb, offset); |
3733 | 0 | proto_tree_add_uint(pipe_tree, |
3734 | 0 | hf_smb_pipe_getinfo_pipe_name_length, |
3735 | 0 | d_tvb, offset, 1, pipe_namelen); |
3736 | 0 | offset += 1; |
3737 | | /* XXX - can this be Unicode? */ |
3738 | 0 | proto_tree_add_item(pipe_tree, |
3739 | 0 | hf_smb_pipe_getinfo_pipe_name, |
3740 | 0 | d_tvb, offset, pipe_namelen, ENC_ASCII); |
3741 | 0 | break; |
3742 | 0 | } |
3743 | 0 | } |
3744 | 0 | break; |
3745 | | |
3746 | 0 | case RAW_READ_NM_PIPE: |
3747 | | /* |
3748 | | * Request contains no parameters or data. |
3749 | | */ |
3750 | 0 | if (!smb_info->request) { |
3751 | 0 | if (d_tvb == NULL) |
3752 | 0 | return false; |
3753 | | |
3754 | 0 | dissect_file_data(d_tvb, pipe_tree, 0, |
3755 | 0 | (uint16_t) tvb_reported_length(d_tvb), |
3756 | 0 | -1, |
3757 | 0 | (uint16_t) tvb_reported_length(d_tvb)); |
3758 | 0 | } |
3759 | 0 | break; |
3760 | | |
3761 | 0 | case RAW_WRITE_NM_PIPE: |
3762 | 0 | offset = 0; |
3763 | 0 | if (smb_info->request) { |
3764 | 0 | if (d_tvb == NULL) |
3765 | 0 | return false; |
3766 | | |
3767 | 0 | dissect_file_data(d_tvb, pipe_tree, |
3768 | 0 | offset, (uint16_t) tvb_reported_length(d_tvb), |
3769 | 0 | -1, |
3770 | 0 | (uint16_t) tvb_reported_length(d_tvb)); |
3771 | 0 | } else { |
3772 | 0 | if (p_tvb == NULL) |
3773 | 0 | return false; |
3774 | 0 | proto_tree_add_item(pipe_tree, |
3775 | 0 | hf_smb_pipe_write_raw_bytes_written, |
3776 | 0 | p_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
3777 | 0 | } |
3778 | 0 | break; |
3779 | 0 | } |
3780 | 0 | return true; |
3781 | 0 | } |
3782 | | |
3783 | | void |
3784 | | proto_register_smb_pipe(void) |
3785 | 14 | { |
3786 | 14 | static hf_register_info hf[] = { |
3787 | 14 | { &hf_smb_pipe_function, |
3788 | 14 | { "Function", "smb_pipe.function", FT_UINT16, BASE_HEX, |
3789 | 14 | VALS(functions), 0, "SMB Pipe Function Code", HFILL }}, |
3790 | 14 | { &hf_smb_pipe_priority, |
3791 | 14 | { "Priority", "smb_pipe.priority", FT_UINT16, BASE_DEC, |
3792 | 14 | NULL, 0, "SMB Pipe Priority", HFILL }}, |
3793 | 14 | { &hf_smb_pipe_peek_available, |
3794 | 14 | { "Available Bytes", "smb_pipe.peek.available_bytes", FT_UINT16, BASE_DEC, |
3795 | 14 | NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }}, |
3796 | 14 | { &hf_smb_pipe_peek_remaining, |
3797 | 14 | { "Bytes Remaining", "smb_pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC, |
3798 | 14 | NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }}, |
3799 | 14 | { &hf_smb_pipe_peek_status, |
3800 | 14 | { "Pipe Status", "smb_pipe.peek.status", FT_UINT16, BASE_DEC, |
3801 | 14 | VALS(pipe_status), 0, NULL, HFILL }}, |
3802 | 14 | { &hf_smb_pipe_getinfo_info_level, |
3803 | 14 | { "Information Level", "smb_pipe.getinfo.info_level", FT_UINT16, BASE_DEC, |
3804 | 14 | NULL, 0, "Information level of information to return", HFILL }}, |
3805 | 14 | { &hf_smb_pipe_getinfo_output_buffer_size, |
3806 | 14 | { "Output Buffer Size", "smb_pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC, |
3807 | 14 | NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }}, |
3808 | 14 | { &hf_smb_pipe_getinfo_input_buffer_size, |
3809 | 14 | { "Input Buffer Size", "smb_pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC, |
3810 | 14 | NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }}, |
3811 | 14 | { &hf_smb_pipe_getinfo_maximum_instances, |
3812 | 14 | { "Maximum Instances", "smb_pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC, |
3813 | 14 | NULL, 0, "Maximum allowed number of instances", HFILL }}, |
3814 | 14 | { &hf_smb_pipe_getinfo_current_instances, |
3815 | 14 | { "Current Instances", "smb_pipe.getinfo.current_instances", FT_UINT8, BASE_DEC, |
3816 | 14 | NULL, 0, "Current number of instances", HFILL }}, |
3817 | 14 | { &hf_smb_pipe_getinfo_pipe_name_length, |
3818 | 14 | { "Pipe Name Length", "smb_pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC, |
3819 | 14 | NULL, 0, "Length of pipe name", HFILL }}, |
3820 | 14 | { &hf_smb_pipe_getinfo_pipe_name, |
3821 | 14 | { "Pipe Name", "smb_pipe.getinfo.pipe_name", FT_STRING, BASE_NONE, |
3822 | 14 | NULL, 0, "Name of pipe", HFILL }}, |
3823 | 14 | { &hf_smb_pipe_write_raw_bytes_written, |
3824 | 14 | { "Bytes Written", "smb_pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC, |
3825 | 14 | NULL, 0, "Number of bytes written to the pipe", HFILL }}, |
3826 | 14 | { &hf_smb_pipe_fragment_overlap, |
3827 | 14 | { "Fragment overlap", "smb_pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE, |
3828 | 14 | NULL, 0x0, "Fragment overlaps with other fragments", HFILL }}, |
3829 | 14 | { &hf_smb_pipe_fragment_overlap_conflict, |
3830 | 14 | { "Conflicting data in fragment overlap", "smb_pipe.fragment.overlap.conflict", FT_BOOLEAN, |
3831 | 14 | BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }}, |
3832 | 14 | { &hf_smb_pipe_fragment_multiple_tails, |
3833 | 14 | { "Multiple tail fragments found", "smb_pipe.fragment.multipletails", FT_BOOLEAN, |
3834 | 14 | BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }}, |
3835 | 14 | { &hf_smb_pipe_fragment_too_long_fragment, |
3836 | 14 | { "Fragment too long", "smb_pipe.fragment.toolongfragment", FT_BOOLEAN, |
3837 | 14 | BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }}, |
3838 | 14 | { &hf_smb_pipe_fragment_error, |
3839 | 14 | { "Defragmentation error", "smb_pipe.fragment.error", FT_FRAMENUM, |
3840 | 14 | BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }}, |
3841 | 14 | { &hf_smb_pipe_fragment_count, |
3842 | 14 | { "Fragment count", "smb_pipe.fragment.count", FT_UINT32, |
3843 | 14 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
3844 | 14 | { &hf_smb_pipe_fragment, |
3845 | 14 | { "Fragment", "smb_pipe.fragment", FT_FRAMENUM, |
3846 | 14 | BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }}, |
3847 | 14 | { &hf_smb_pipe_fragments, |
3848 | 14 | { "Fragments", "smb_pipe.fragments", FT_NONE, |
3849 | 14 | BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }}, |
3850 | 14 | { &hf_smb_pipe_reassembled_in, |
3851 | 14 | { "This PDU is reassembled in", "smb_pipe.reassembled_in", FT_FRAMENUM, |
3852 | 14 | BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }}, |
3853 | 14 | { &hf_smb_pipe_reassembled_length, |
3854 | 14 | { "Reassembled SMB Pipe length", "smb_pipe.reassembled.length", FT_UINT32, |
3855 | 14 | BASE_DEC, NULL, 0x0, "The total length of the reassembled payload", HFILL }}, |
3856 | | |
3857 | | /* Generated from convert_proto_tree_add_text.pl */ |
3858 | 14 | { &hf_smb_pipe_word_param, |
3859 | 14 | { "Word Param", "smb_pipe.word_param", FT_UINT16, |
3860 | 14 | BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }}, |
3861 | 14 | { &hf_smb_pipe_doubleword_param, |
3862 | 14 | { "Doubleword Param", "smb_pipe.doubleword_param", FT_UINT32, |
3863 | 14 | BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }}, |
3864 | 14 | { &hf_smb_pipe_byte_param, |
3865 | 14 | { "Byte Param", "smb_pipe.byte_param", FT_UINT8, |
3866 | 14 | BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }}, |
3867 | 14 | { &hf_smb_pipe_bytes_param, |
3868 | 14 | { "Bytes Param", "smb_pipe.bytes_param", FT_BYTES, |
3869 | 14 | BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
3870 | 14 | { &hf_smb_pipe_string_param, |
3871 | 14 | { "String Param", "smb_pipe.string_param", FT_STRING, |
3872 | 14 | BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
3873 | 14 | { &hf_smb_pipe_stringz_param, |
3874 | 14 | { "String Param", "smb_pipe.string_param", FT_STRINGZ, |
3875 | 14 | BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
3876 | 14 | }; |
3877 | 14 | static int *ett[] = { |
3878 | 14 | &ett_smb_pipe, |
3879 | 14 | &ett_smb_pipe_fragment, |
3880 | 14 | &ett_smb_pipe_fragments, |
3881 | 14 | }; |
3882 | | |
3883 | 14 | static ei_register_info ei[] = { |
3884 | 14 | { &ei_smb_pipe_bogus_netwkstauserlogon, { "smb_pipe.bogus_netwkstauserlogon_parameters", PI_PROTOCOL, PI_WARN, "Bogus NetWkstaUserLogon parameters", EXPFILL }}, |
3885 | 14 | { &ei_smb_pipe_bad_type, { "smb_pipe.bad_type", PI_PROTOCOL, PI_ERROR, "Bad type field", EXPFILL }}, |
3886 | 14 | }; |
3887 | | |
3888 | 14 | expert_module_t* expert_smb_pipe; |
3889 | | |
3890 | 14 | proto_smb_pipe = proto_register_protocol("SMB Pipe Protocol", "SMB Pipe", "smb_pipe"); |
3891 | | |
3892 | 14 | proto_register_field_array(proto_smb_pipe, hf, array_length(hf)); |
3893 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
3894 | 14 | expert_smb_pipe = expert_register_protocol(proto_smb_pipe); |
3895 | 14 | expert_register_field_array(expert_smb_pipe, ei, array_length(ei)); |
3896 | | |
3897 | 14 | smb_transact_heur_subdissector_list = register_heur_dissector_list_with_description("smb_transact", "SMB Pipe DCERPC data", proto_smb_pipe); |
3898 | | /* |
3899 | | * XXX - addresses_ports_reassembly_table_functions? |
3900 | | * Probably correct for SMB-over-NBT and SMB-over-TCP, |
3901 | | * as stuff from two different connections should |
3902 | | * probably not be combined, but what about other |
3903 | | * transports for SMB, e.g. NBF or Netware? |
3904 | | */ |
3905 | 14 | reassembly_table_register(&dcerpc_reassembly_table, |
3906 | 14 | &addresses_reassembly_table_functions); |
3907 | 14 | } |
3908 | | |
3909 | | /* |
3910 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
3911 | | * |
3912 | | * Local variables: |
3913 | | * c-basic-offset: 8 |
3914 | | * tab-width: 8 |
3915 | | * indent-tabs-mode: t |
3916 | | * End: |
3917 | | * |
3918 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
3919 | | * :indentSize=8:tabSize=8:noTabs=false: |
3920 | | */ |