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