2 XXX Fixme : shouldnt show [malformed frame] for long packets
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
11 * $Id: packet-smb-pipe.c,v 1.99 2003/12/21 04:31:56 jmayer Exp $
13 * Ethereal - Network traffic analyzer
14 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #include <epan/packet.h>
46 #include "packet-smb-pipe.h"
47 #include "packet-smb-browse.h"
48 #include "packet-smb-common.h"
49 #include "packet-dcerpc.h"
50 #include "reassemble.h"
52 static int proto_smb_pipe = -1;
53 static int hf_pipe_function = -1;
54 static int hf_pipe_priority = -1;
55 static int hf_pipe_peek_available = -1;
56 static int hf_pipe_peek_remaining = -1;
57 static int hf_pipe_peek_status = -1;
58 static int hf_pipe_getinfo_info_level = -1;
59 static int hf_pipe_getinfo_output_buffer_size = -1;
60 static int hf_pipe_getinfo_input_buffer_size = -1;
61 static int hf_pipe_getinfo_maximum_instances = -1;
62 static int hf_pipe_getinfo_current_instances = -1;
63 static int hf_pipe_getinfo_pipe_name_length = -1;
64 static int hf_pipe_getinfo_pipe_name = -1;
65 static int hf_pipe_write_raw_bytes_written = -1;
66 static int hf_pipe_fragments = -1;
67 static int hf_pipe_fragment = -1;
68 static int hf_pipe_fragment_overlap = -1;
69 static int hf_pipe_fragment_overlap_conflict = -1;
70 static int hf_pipe_fragment_multiple_tails = -1;
71 static int hf_pipe_fragment_too_long_fragment = -1;
72 static int hf_pipe_fragment_error = -1;
73 static int hf_pipe_reassembled_in = -1;
75 static gint ett_smb_pipe = -1;
76 static gint ett_smb_pipe_fragment = -1;
77 static gint ett_smb_pipe_fragments = -1;
79 static const fragment_items smb_pipe_frag_items = {
80 &ett_smb_pipe_fragment,
81 &ett_smb_pipe_fragments,
84 &hf_pipe_fragment_overlap,
85 &hf_pipe_fragment_overlap_conflict,
86 &hf_pipe_fragment_multiple_tails,
87 &hf_pipe_fragment_too_long_fragment,
88 &hf_pipe_fragment_error,
93 static int proto_smb_lanman = -1;
94 static int hf_function_code = -1;
95 static int hf_param_desc = -1;
96 static int hf_return_desc = -1;
97 static int hf_aux_data_desc = -1;
98 static int hf_detail_level = -1;
99 static int hf_recv_buf_len = -1;
100 static int hf_send_buf_len = -1;
101 static int hf_continuation_from = -1;
102 static int hf_status = -1;
103 static int hf_convert = -1;
104 static int hf_ecount = -1;
105 static int hf_acount = -1;
106 static int hf_share_name = -1;
107 static int hf_share_type = -1;
108 static int hf_share_comment = -1;
109 static int hf_share_permissions = -1;
110 static int hf_share_max_uses = -1;
111 static int hf_share_current_uses = -1;
112 static int hf_share_path = -1;
113 static int hf_share_password = -1;
114 static int hf_server_name = -1;
115 static int hf_server_major = -1;
116 static int hf_server_minor = -1;
117 static int hf_server_comment = -1;
118 static int hf_abytes = -1;
119 static int hf_current_time = -1;
120 static int hf_msecs = -1;
121 static int hf_hour = -1;
122 static int hf_minute = -1;
123 static int hf_second = -1;
124 static int hf_hundredths = -1;
125 static int hf_tzoffset = -1;
126 static int hf_timeinterval = -1;
127 static int hf_day = -1;
128 static int hf_month = -1;
129 static int hf_year = -1;
130 static int hf_weekday = -1;
131 static int hf_enumeration_domain = -1;
132 static int hf_computer_name = -1;
133 static int hf_user_name = -1;
134 static int hf_group_name = -1;
135 static int hf_workstation_domain = -1;
136 static int hf_workstation_major = -1;
137 static int hf_workstation_minor = -1;
138 static int hf_logon_domain = -1;
139 static int hf_other_domains = -1;
140 static int hf_password = -1;
141 static int hf_workstation_name = -1;
142 static int hf_ustruct_size = -1;
143 static int hf_logon_code = -1;
144 static int hf_privilege_level = -1;
145 static int hf_operator_privileges = -1;
146 static int hf_num_logons = -1;
147 static int hf_bad_pw_count = -1;
148 static int hf_last_logon = -1;
149 static int hf_last_logoff = -1;
150 static int hf_logoff_time = -1;
151 static int hf_kickoff_time = -1;
152 static int hf_password_age = -1;
153 static int hf_password_can_change = -1;
154 static int hf_password_must_change = -1;
155 static int hf_script_path = -1;
156 static int hf_logoff_code = -1;
157 static int hf_duration = -1;
158 static int hf_comment = -1;
159 static int hf_user_comment = -1;
160 static int hf_full_name = -1;
161 static int hf_homedir = -1;
162 static int hf_parameters = -1;
163 static int hf_logon_server = -1;
164 static int hf_country_code = -1;
165 static int hf_workstations = -1;
166 static int hf_max_storage = -1;
167 static int hf_units_per_week = -1;
168 static int hf_logon_hours = -1;
169 static int hf_code_page = -1;
170 static int hf_new_password = -1;
171 static int hf_old_password = -1;
172 static int hf_reserved = -1;
174 static gint ett_lanman = -1;
175 static gint ett_lanman_unknown_entries = -1;
176 static gint ett_lanman_unknown_entry = -1;
177 static gint ett_lanman_shares = -1;
178 static gint ett_lanman_share = -1;
179 static gint ett_lanman_groups = -1;
180 static gint ett_lanman_servers = -1;
181 static gint ett_lanman_server = -1;
183 static dissector_handle_t data_handle;
188 * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
190 * among other documents.
193 static const value_string status_vals[] = {
195 {5, "User has insufficient privilege"},
196 {65, "Network access is denied"},
197 {86, "The specified password is invalid"},
198 {SMBE_moredata, "Additional data is available"},
199 {2114, "Service is not running on the remote computer"},
200 {2123, "Supplied buffer is too small"},
201 {2141, "Server is not configured for transactions (IPC$ not shared)"},
202 {2212, "An error occurred while loading or running the logon script"},
203 {2214, "The logon was not validated by any server"},
204 {2217, "The logon server is running an older software version"},
205 {2221, "The user name was not found"},
206 {2226, "Operation not permitted on Backup Domain Controller"},
207 {2240, "The user is not allowed to logon from this computer"},
208 {2241, "The user is not allowed to logon at this time"},
209 {2242, "The user password has expired"},
210 {2243, "The password cannot be changed"},
211 {2246, "The password is too short"},
215 static const value_string privilege_vals[] = {
218 {2, "Administrator"},
222 static const value_string op_privilege_vals[] = {
223 {0, "Print operator"},
224 {1, "Communications operator"},
225 {2, "Server operator"},
226 {3, "Accounts operator"},
230 static const value_string weekday_vals[] = {
242 add_word_param(tvbuff_t *tvb, int offset, int count _U_,
243 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
248 proto_tree_add_item(tree, hf_index, tvb, offset, 2, TRUE);
250 WParam = tvb_get_letohs(tvb, offset);
251 proto_tree_add_text(tree, tvb, offset, 2,
252 "Word Param: %u (0x%04X)", WParam, WParam);
259 add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
260 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
265 proto_tree_add_item(tree, hf_index, tvb, offset, 4, TRUE);
267 LParam = tvb_get_letohl(tvb, offset);
268 proto_tree_add_text(tree, tvb, offset, 4,
269 "Doubleword Param: %u (0x%08X)", LParam, LParam);
276 add_byte_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
277 proto_tree *tree, int convert _U_, int hf_index)
282 proto_tree_add_item(tree, hf_index, tvb, offset, count, TRUE);
285 BParam = tvb_get_guint8(tvb, offset);
286 proto_tree_add_text(tree, tvb, offset, count,
287 "Byte Param: %u (0x%02X)",
290 proto_tree_add_text(tree, tvb, offset, count,
292 tvb_bytes_to_str(tvb, offset, count));
300 add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
301 proto_tree *tree _U_, int convert _U_, int hf_index _U_)
304 * This is for parameters that have descriptor entries but that
305 * are, in practice, just padding.
312 add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
313 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
315 if (hf_index != -1) {
316 proto_tree_add_text(tree, tvb, offset, 0,
318 proto_registrar_get_name(hf_index));
320 proto_tree_add_text(tree, tvb, offset, 0,
321 "String Param (Null pointer)");
326 add_string_param(tvbuff_t *tvb, int offset, int count _U_,
327 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
331 string_len = tvb_strsize(tvb, offset);
332 if (hf_index != -1) {
333 proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
336 proto_tree_add_text(tree, tvb, offset, string_len,
338 tvb_format_text(tvb, offset, string_len));
340 offset += string_len;
345 get_stringz_pointer_value(tvbuff_t *tvb, int offset, int convert, int *cptrp,
351 /* pointer to string */
352 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
356 if (tvb_offset_exists(tvb, cptr) &&
357 (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
358 string_len++; /* include the terminating '\0' */
360 return tvb_format_text(tvb, cptr, string_len - 1);
366 add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
367 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
373 string = get_stringz_pointer_value(tvb, offset, convert, &cptr,
378 if (string != NULL) {
379 if (hf_index != -1) {
380 proto_tree_add_item(tree, hf_index, tvb, cptr,
383 proto_tree_add_text(tree, tvb, cptr, string_len,
384 "String Param: %s", string);
387 if (hf_index != -1) {
388 proto_tree_add_text(tree, tvb, 0, 0,
389 "%s: <String goes past end of frame>",
390 proto_registrar_get_name(hf_index));
392 proto_tree_add_text(tree, tvb, 0, 0,
393 "String Param: <String goes past end of frame>");
401 add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
402 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
406 /* pointer to byte array */
407 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
411 if (tvb_bytes_exist(tvb, cptr, count)) {
412 if (hf_index != -1) {
413 proto_tree_add_item(tree, hf_index, tvb, cptr,
416 proto_tree_add_text(tree, tvb, cptr, count,
418 tvb_bytes_to_str(tvb, cptr, count));
421 if (hf_index != -1) {
422 proto_tree_add_text(tree, tvb, 0, 0,
423 "%s: <Bytes go past end of frame>",
424 proto_registrar_get_name(hf_index));
426 proto_tree_add_text(tree, tvb, 0, 0,
427 "Byte Param: <Bytes goes past end of frame>");
435 add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
436 proto_tree *tree, int convert _U_, int hf_index)
438 struct smb_info *smb_info = pinfo->private_data;
439 smb_transact_info_t *trp = smb_info->sip->extra_info;
442 level = tvb_get_letohs(tvb, offset);
443 if (!pinfo->fd->flags.visited)
444 trp->info_level = level; /* remember this for the response */
445 proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
451 add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
452 proto_tree *tree, int convert _U_, int hf_index)
456 WParam = tvb_get_letohs(tvb, offset);
457 if (WParam == 0xffff) { /* -1 */
458 proto_tree_add_uint_format(tree, hf_index, tvb,
461 proto_registrar_get_name(hf_index));
463 proto_tree_add_uint(tree, hf_index, tvb,
471 add_server_type(tvbuff_t *tvb, int offset, int count _U_,
472 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
474 offset = dissect_smb_server_type_flags(
475 tvb, offset, pinfo, tree, NULL, FALSE);
480 add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
481 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
483 offset = dissect_smb_server_type_flags(
484 tvb, offset, pinfo, tree, NULL, TRUE);
489 add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
490 proto_tree *tree, int convert _U_, int hf_index)
494 nstime.secs = tvb_get_letohl(tvb, offset);
496 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
497 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
498 time_secs_to_str(nstime.secs));
504 * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but-
505 * it's-local-time-not-UTC time.
508 add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
509 const char *absent_name)
514 nstime.secs = tvb_get_letohl(tvb, offset);
517 * Sigh. Sometimes it appears that -1 means "unknown", and
518 * sometimes it appears that 0 means "unknown", for the last
521 if (nstime.secs == -1 || nstime.secs == 0) {
522 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
523 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
527 * Run it through "gmtime()" to break it down, and then
528 * run it through "mktime()" to put it back together
531 tmp = gmtime(&nstime.secs);
532 tmp->tm_isdst = -1; /* we don't know if it's DST or not */
533 nstime.secs = mktime(tmp);
534 proto_tree_add_time(tree, hf_index, tvb, offset, 4,
542 add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
543 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
545 return add_abstime_common(tvb, offset, tree, hf_index, "Never");
549 add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
550 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
552 return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
556 add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
557 proto_tree *tree, int convert _U_, int hf_index)
561 nlogons = tvb_get_letohs(tvb, offset);
562 if (nlogons == 0xffff) /* -1 */
563 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 2,
564 nlogons, "%s: Unknown",
565 proto_registrar_get_name(hf_index));
567 proto_tree_add_uint(tree, hf_index, tvb, offset, 2,
574 add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
575 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
579 max_storage = tvb_get_letohl(tvb, offset);
580 if (max_storage == 0xffffffff)
581 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
582 max_storage, "%s: No limit",
583 proto_registrar_get_name(hf_index));
585 proto_tree_add_uint(tree, hf_index, tvb, offset, 4,
592 add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
593 proto_tree *tree, int convert, int hf_index)
597 /* pointer to byte array */
598 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
602 if (tvb_bytes_exist(tvb, cptr, count)) {
605 * The logon hours should be exactly 21 bytes long.
607 * XXX - should actually carve up the bits;
608 * we need the units per week to do that, though.
610 proto_tree_add_item(tree, hf_index, tvb, cptr, count,
613 proto_tree_add_bytes_format(tree, hf_index, tvb,
614 cptr, count, tvb_get_ptr(tvb, cptr, count),
615 "%s: %s (wrong length, should be 21, is %d",
616 proto_registrar_get_name(hf_index),
617 tvb_bytes_to_str(tvb, cptr, count), count);
620 proto_tree_add_text(tree, tvb, 0, 0,
621 "%s: <Bytes go past end of frame>",
622 proto_registrar_get_name(hf_index));
629 add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
630 proto_tree *tree, int convert _U_, int hf_index)
634 tzoffset = tvb_get_letohs(tvb, offset);
636 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
637 tzoffset, "%s: %s east of UTC",
638 proto_registrar_get_name(hf_index),
639 time_secs_to_str(-tzoffset*60));
640 } else if (tzoffset > 0) {
641 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
642 tzoffset, "%s: %s west of UTC",
643 proto_registrar_get_name(hf_index),
644 time_secs_to_str(tzoffset*60));
646 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
647 tzoffset, "%s: at UTC",
648 proto_registrar_get_name(hf_index));
655 add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
656 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
658 guint16 timeinterval;
660 timeinterval = tvb_get_letohs(tvb, offset);
661 proto_tree_add_uint_format(tree, hf_timeinterval, tvb, offset, 2,
662 timeinterval, "%s: %f seconds", proto_registrar_get_name(hf_index),
669 add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
670 proto_tree *tree, int convert _U_, int hf_index _U_)
673 proto_tree_add_text(tree, tvb, offset, count,
674 "Bogus NetWkstaUserLogon parameters: length is %d, should be 54",
681 proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, TRUE);
688 proto_tree_add_item(tree, hf_password, tvb, offset, 15, TRUE);
694 /* workstation name */
695 proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, TRUE);
701 * The following data structure describes the Remote API requests we
704 * Simply fill in the number and parameter information.
705 * Try to keep them in order.
707 * We will extend this data structure as we try to decode more.
711 * This is a pointer to a function to process an item.
713 typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
717 * Type of an item; determines what parameter strings are valid for
721 PARAM_NONE, /* for the end-of-list stopper */
722 PARAM_WORD, /* 'W' or 'h' - 16-bit word */
723 PARAM_DWORD, /* 'D' or 'i' - 32-bit word */
724 PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
725 PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
729 * This structure describes an item; "hf_index" points to the index
730 * for the field corresponding to that item, "func" points to the
731 * function to use to add that item to the tree, and "type" is the
732 * type that the item is supposed to have.
741 * This structure describes a list of items; each list of items
742 * has a corresponding detail level.
746 const item_t *item_list;
752 proto_item *(*req_data_item)(tvbuff_t *, packet_info *,
755 const item_t *req_data;
756 const item_t *req_aux_data;
758 const gchar *resp_data_entry_list_label;
759 gint *ett_data_entry_list;
760 proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
762 gint *ett_resp_data_element_item;
763 const item_list_t *resp_data_list;
764 const item_t *resp_aux_data;
767 static int no_hf = -1; /* for padding crap */
769 static const item_t lm_params_req_netshareenum[] = {
770 { &hf_detail_level, add_detail_level, PARAM_WORD },
771 { &hf_recv_buf_len, add_word_param, PARAM_WORD },
772 { NULL, NULL, PARAM_NONE }
775 static const item_t lm_params_resp_netshareenum[] = {
776 { &hf_acount, add_word_param, PARAM_WORD },
777 { NULL, NULL, PARAM_NONE }
781 * Create a subtree for a share.
784 netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
787 return proto_tree_add_text(tree, tvb, offset, -1,
788 "Share %.13s", tvb_get_ptr(tvb, offset, 13));
793 static const item_t lm_null[] = {
794 { NULL, NULL, PARAM_NONE }
797 static const item_list_t lm_null_list[] = {
801 static const item_t lm_data_resp_netshareenum_1[] = {
802 { &hf_share_name, add_byte_param, PARAM_BYTES },
803 { &no_hf, add_pad_param, PARAM_BYTES },
804 { &hf_share_type, add_word_param, PARAM_WORD },
805 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
806 { NULL, NULL, PARAM_NONE }
809 static const item_list_t lm_data_resp_netshareenum[] = {
810 { 1, lm_data_resp_netshareenum_1 },
814 static const item_t lm_params_req_netsharegetinfo[] = {
815 { &hf_share_name, add_string_param, PARAM_STRINGZ },
816 { &hf_detail_level, add_detail_level, PARAM_WORD },
817 { NULL, NULL, PARAM_NONE }
820 static const item_t lm_params_resp_netsharegetinfo[] = {
821 { &hf_abytes, add_word_param, PARAM_WORD },
822 { NULL, NULL, PARAM_NONE }
825 static const item_t lm_data_resp_netsharegetinfo_0[] = {
826 { &hf_share_name, add_byte_param, PARAM_BYTES },
827 { NULL, NULL, PARAM_NONE }
830 static const item_t lm_data_resp_netsharegetinfo_1[] = {
831 { &hf_share_name, add_byte_param, PARAM_BYTES },
832 { &no_hf, add_pad_param, PARAM_BYTES },
833 { &hf_share_type, add_word_param, PARAM_WORD },
834 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
835 { NULL, NULL, PARAM_NONE }
838 static const item_t lm_data_resp_netsharegetinfo_2[] = {
839 { &hf_share_name, add_byte_param, PARAM_BYTES },
840 { &no_hf, add_pad_param, PARAM_BYTES },
841 { &hf_share_type, add_word_param, PARAM_WORD },
842 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
843 { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
844 { &hf_share_max_uses, add_max_uses, PARAM_WORD },
845 { &hf_share_current_uses, add_word_param, PARAM_WORD },
846 { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
847 { &hf_share_password, add_byte_param, PARAM_BYTES },
848 { NULL, NULL, PARAM_NONE }
851 static const item_list_t lm_data_resp_netsharegetinfo[] = {
852 { 0, lm_data_resp_netsharegetinfo_0 },
853 { 1, lm_data_resp_netsharegetinfo_1 },
854 { 2, lm_data_resp_netsharegetinfo_2 },
858 static const item_t lm_params_req_netservergetinfo[] = {
859 { &hf_detail_level, add_detail_level, PARAM_WORD },
860 { NULL, NULL, PARAM_NONE }
863 static const item_t lm_params_resp_netservergetinfo[] = {
864 { &hf_abytes, add_word_param, PARAM_WORD },
865 { NULL, NULL, PARAM_NONE }
868 static const item_t lm_data_serverinfo_0[] = {
869 { &hf_server_name, add_byte_param, PARAM_BYTES },
870 { NULL, NULL, PARAM_NONE }
873 static const item_t lm_data_serverinfo_1[] = {
874 { &hf_server_name, add_byte_param, PARAM_BYTES },
875 { &hf_server_major, add_byte_param, PARAM_BYTES },
876 { &hf_server_minor, add_byte_param, PARAM_BYTES },
877 { &no_hf, add_server_type, PARAM_DWORD },
878 { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
879 { NULL, NULL, PARAM_NONE }
882 static const item_list_t lm_data_serverinfo[] = {
883 { 0, lm_data_serverinfo_0 },
884 { 1, lm_data_serverinfo_1 },
888 static const item_t lm_params_req_netusergetinfo[] = {
889 { &hf_user_name, add_string_param, PARAM_STRINGZ },
890 { &hf_detail_level, add_detail_level, PARAM_WORD },
891 { NULL, NULL, PARAM_NONE }
894 static const item_t lm_params_resp_netusergetinfo[] = {
895 { &hf_abytes, add_word_param, PARAM_WORD },
896 { NULL, NULL, PARAM_NONE }
899 static const item_t lm_data_resp_netusergetinfo_11[] = {
900 { &hf_user_name, add_byte_param, PARAM_BYTES },
901 { &no_hf, add_pad_param, PARAM_BYTES },
902 { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
903 { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
904 { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
905 { &hf_privilege_level, add_word_param, PARAM_WORD },
906 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
907 { &hf_password_age, add_reltime, PARAM_DWORD },
908 { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
909 { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
910 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
911 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
912 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
913 { &hf_num_logons, add_nlogons, PARAM_WORD },
914 { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
915 { &hf_country_code, add_word_param, PARAM_WORD },
916 { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
917 { &hf_max_storage, add_max_storage, PARAM_DWORD },
918 { &hf_units_per_week, add_word_param, PARAM_WORD },
919 { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
920 { &hf_code_page, add_word_param, PARAM_WORD },
921 { NULL, NULL, PARAM_NONE }
924 static const item_list_t lm_data_resp_netusergetinfo[] = {
925 { 11, lm_data_resp_netusergetinfo_11 },
929 static const item_t lm_params_req_netusergetgroups[] = {
930 { &hf_user_name, add_string_param, PARAM_STRINGZ },
931 { &hf_detail_level, add_detail_level, PARAM_WORD },
932 { NULL, NULL, PARAM_NONE }
935 static const item_t lm_params_resp_netusergetgroups[] = {
936 { &hf_abytes, add_word_param, PARAM_WORD },
937 { NULL, NULL, PARAM_NONE }
940 static const item_t lm_data_resp_netusergetgroups_0[] = {
941 { &hf_group_name, add_byte_param, PARAM_BYTES },
942 { NULL, NULL, PARAM_NONE }
945 static const item_list_t lm_data_resp_netusergetgroups[] = {
946 { 0, lm_data_resp_netusergetgroups_0 },
951 * Has no detail level; make it the default.
953 static const item_t lm_data_resp_netremotetod_nolevel[] = {
954 { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
955 { &hf_msecs, add_dword_param, PARAM_DWORD },
956 { &hf_hour, add_byte_param, PARAM_BYTES },
957 { &hf_minute, add_byte_param, PARAM_BYTES },
958 { &hf_second, add_byte_param, PARAM_BYTES },
959 { &hf_hundredths, add_byte_param, PARAM_BYTES },
960 { &hf_tzoffset, add_tzoffset, PARAM_WORD },
961 { &hf_timeinterval, add_timeinterval, PARAM_WORD },
962 { &hf_day, add_byte_param, PARAM_BYTES },
963 { &hf_month, add_byte_param, PARAM_BYTES },
964 { &hf_year, add_word_param, PARAM_WORD },
965 { &hf_weekday, add_byte_param, PARAM_BYTES },
966 { NULL, NULL, PARAM_NONE }
969 static const item_list_t lm_data_resp_netremotetod[] = {
970 { -1, lm_data_resp_netremotetod_nolevel },
973 static const item_t lm_params_req_netserverenum2[] = {
974 { &hf_detail_level, add_detail_level, PARAM_WORD },
975 { &no_hf, add_server_type_info, PARAM_DWORD },
976 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
977 { NULL, NULL, PARAM_NONE }
981 * Create a subtree for a server.
984 netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
987 return proto_tree_add_text(tree, tvb, offset, -1,
988 "Server %.16s", tvb_get_ptr(tvb, offset, 16));
993 static const item_t lm_params_resp_netserverenum2[] = {
994 { &hf_acount, add_word_param, PARAM_WORD },
995 { NULL, NULL, PARAM_NONE }
998 static const item_t lm_params_req_netwkstagetinfo[] = {
999 { &hf_detail_level, add_detail_level, PARAM_WORD },
1000 { NULL, NULL, PARAM_NONE }
1003 static const item_t lm_params_resp_netwkstagetinfo[] = {
1004 { &hf_abytes, add_word_param, PARAM_WORD },
1005 { NULL, NULL, PARAM_NONE }
1008 static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1009 { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1010 { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1011 { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1012 { &hf_workstation_major, add_byte_param, PARAM_BYTES },
1013 { &hf_workstation_minor, add_byte_param, PARAM_BYTES },
1014 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1015 { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1016 { NULL, NULL, PARAM_NONE }
1019 static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1020 { 10, lm_data_resp_netwkstagetinfo_10 },
1024 static const item_t lm_params_req_netwkstauserlogon[] = {
1025 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1026 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1027 { &hf_detail_level, add_detail_level, PARAM_WORD },
1028 { &no_hf, add_logon_args, PARAM_BYTES },
1029 { &hf_ustruct_size, add_word_param, PARAM_WORD },
1030 { NULL, NULL, PARAM_NONE }
1033 static const item_t lm_params_resp_netwkstauserlogon[] = {
1034 { &hf_abytes, add_word_param, PARAM_WORD },
1035 { NULL, NULL, PARAM_NONE }
1038 static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1039 { &hf_logon_code, add_word_param, PARAM_WORD },
1040 { &hf_user_name, add_byte_param, PARAM_BYTES },
1041 { &no_hf, add_pad_param, PARAM_BYTES },
1042 { &hf_privilege_level, add_word_param, PARAM_WORD },
1043 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1044 { &hf_num_logons, add_nlogons, PARAM_WORD },
1045 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1046 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1047 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1048 { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1049 { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1050 { &hf_password_age, add_reltime, PARAM_DWORD },
1051 { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1052 { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1053 { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1054 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1055 { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1056 { &hf_reserved, add_dword_param, PARAM_DWORD },
1057 { NULL, NULL, PARAM_NONE }
1060 static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1061 { 1, lm_data_resp_netwkstauserlogon_1 },
1065 static const item_t lm_params_req_netwkstauserlogoff[] = {
1066 { &hf_user_name, add_byte_param, PARAM_BYTES },
1067 { &no_hf, add_pad_param, PARAM_BYTES },
1068 { &hf_workstation_name, add_byte_param, PARAM_BYTES },
1069 { NULL, NULL, PARAM_NONE }
1072 static const item_t lm_params_resp_netwkstauserlogoff[] = {
1073 { &hf_abytes, add_word_param, PARAM_WORD },
1074 { NULL, NULL, PARAM_NONE }
1077 static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1078 { &hf_logoff_code, add_word_param, PARAM_WORD },
1079 { &hf_duration, add_reltime, PARAM_DWORD },
1080 { &hf_num_logons, add_nlogons, PARAM_WORD },
1081 { NULL, NULL, PARAM_NONE }
1084 static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1085 { 1, lm_data_resp_netwkstauserlogoff_1 },
1089 static const item_t lm_params_req_samoemchangepassword[] = {
1090 { &hf_user_name, add_string_param, PARAM_STRINGZ },
1091 { NULL, NULL, PARAM_NONE }
1094 static const item_t lm_data_req_samoemchangepassword[] = {
1095 { &hf_new_password, add_byte_param, PARAM_BYTES },
1096 { &hf_old_password, add_byte_param, PARAM_BYTES },
1097 { NULL, NULL, PARAM_NONE }
1100 #define API_NetShareEnum 0
1101 #define API_NetShareGetInfo 1
1102 #define API_NetShareSetInfo 2
1103 #define API_NetShareAdd 3
1104 #define API_NetShareDel 4
1105 #define API_NetShareCheck 5
1106 #define API_NetSessionEnum 6
1107 #define API_NetSessionGetInfo 7
1108 #define API_NetSessionDel 8
1109 #define API_WconnectionEnum 9
1110 #define API_NetFileEnum 10
1111 #define API_NetFileGetInfo 11
1112 #define API_NetFileClose 12
1113 #define API_NetServerGetInfo 13
1114 #define API_NetServerSetInfo 14
1115 #define API_NetServerDiskEnum 15
1116 #define API_NetServerAdminCommand 16
1117 #define API_NetAuditOpen 17
1118 #define API_NetAuditClear 18
1119 #define API_NetErrorLogOpen 19
1120 #define API_NetErrorLogClear 20
1121 #define API_NetCharDevEnum 21
1122 #define API_NetCharDevGetInfo 22
1123 #define API_NetCharDevControl 23
1124 #define API_NetCharDevQEnum 24
1125 #define API_NetCharDevQGetInfo 25
1126 #define API_NetCharDevQSetInfo 26
1127 #define API_NetCharDevQPurge 27
1128 #define API_NetCharDevQPurgeSelf 28
1129 #define API_NetMessageNameEnum 29
1130 #define API_NetMessageNameGetInfo 30
1131 #define API_NetMessageNameAdd 31
1132 #define API_NetMessageNameDel 32
1133 #define API_NetMessageNameFwd 33
1134 #define API_NetMessageNameUnFwd 34
1135 #define API_NetMessageBufferSend 35
1136 #define API_NetMessageFileSend 36
1137 #define API_NetMessageLogFileSet 37
1138 #define API_NetMessageLogFileGet 38
1139 #define API_NetServiceEnum 39
1140 #define API_NetServiceInstall 40
1141 #define API_NetServiceControl 41
1142 #define API_NetAccessEnum 42
1143 #define API_NetAccessGetInfo 43
1144 #define API_NetAccessSetInfo 44
1145 #define API_NetAccessAdd 45
1146 #define API_NetAccessDel 46
1147 #define API_NetGroupEnum 47
1148 #define API_NetGroupAdd 48
1149 #define API_NetGroupDel 49
1150 #define API_NetGroupAddUser 50
1151 #define API_NetGroupDelUser 51
1152 #define API_NetGroupGetUsers 52
1153 #define API_NetUserEnum 53
1154 #define API_NetUserAdd 54
1155 #define API_NetUserDel 55
1156 #define API_NetUserGetInfo 56
1157 #define API_NetUserSetInfo 57
1158 #define API_NetUserPasswordSet 58
1159 #define API_NetUserGetGroups 59
1160 /*This line and number replaced a Dead Entry for 60 */
1161 /*This line and number replaced a Dead Entry for 61 */
1162 #define API_NetWkstaSetUID 62
1163 #define API_NetWkstaGetInfo 63
1164 #define API_NetWkstaSetInfo 64
1165 #define API_NetUseEnum 65
1166 #define API_NetUseAdd 66
1167 #define API_NetUseDel 67
1168 #define API_NetUseGetInfo 68
1169 #define API_WPrintQEnum 69
1170 #define API_WPrintQGetInfo 70
1171 #define API_WPrintQSetInfo 71
1172 #define API_WPrintQAdd 72
1173 #define API_WPrintQDel 73
1174 #define API_WPrintQPause 74
1175 #define API_WPrintQContinue 75
1176 #define API_WPrintJobEnum 76
1177 #define API_WPrintJobGetInfo 77
1178 #define API_WPrintJobSetInfo_OLD 78
1179 /* This line and number replaced a Dead Entry for 79 */
1180 /* This line and number replaced a Dead Entry for 80 */
1181 #define API_WPrintJobDel 81
1182 #define API_WPrintJobPause 82
1183 #define API_WPrintJobContinue 83
1184 #define API_WPrintDestEnum 84
1185 #define API_WPrintDestGetInfo 85
1186 #define API_WPrintDestControl 86
1187 #define API_NetProfileSave 87
1188 #define API_NetProfileLoad 88
1189 #define API_NetStatisticsGet 89
1190 #define API_NetStatisticsClear 90
1191 #define API_NetRemoteTOD 91
1192 #define API_WNetBiosEnum 92
1193 #define API_WNetBiosGetInfo 93
1194 #define API_NetServerEnum 94
1195 #define API_I_NetServerEnum 95
1196 #define API_NetServiceGetInfo 96
1197 /* This line and number replaced a Dead Entry for 97 */
1198 /* This line and number replaced a Dead Entry for 98 */
1199 /* This line and number replaced a Dead Entry for 99 */
1200 /* This line and number replaced a Dead Entry for 100 */
1201 /* This line and number replaced a Dead Entry for 101 */
1202 /* This line and number replaced a Dead Entry for 102 */
1203 #define API_WPrintQPurge 103
1204 #define API_NetServerEnum2 104
1205 #define API_NetAccessGetUserPerms 105
1206 #define API_NetGroupGetInfo 106
1207 #define API_NetGroupSetInfo 107
1208 #define API_NetGroupSetUsers 108
1209 #define API_NetUserSetGroups 109
1210 #define API_NetUserModalsGet 110
1211 #define API_NetUserModalsSet 111
1212 #define API_NetFileEnum2 112
1213 #define API_NetUserAdd2 113
1214 #define API_NetUserSetInfo2 114
1215 #define API_NetUserPasswordSet2 115
1216 #define API_I_NetServerEnum2 116
1217 #define API_NetConfigGet2 117
1218 #define API_NetConfigGetAll2 118
1219 #define API_NetGetDCName 119
1220 #define API_NetHandleGetInfo 120
1221 #define API_NetHandleSetInfo 121
1222 #define API_NetStatisticsGet2 122
1223 #define API_WBuildGetInfo 123
1224 #define API_NetFileGetInfo2 124
1225 #define API_NetFileClose2 125
1226 #define API_NetServerReqChallenge 126
1227 #define API_NetServerAuthenticate 127
1228 #define API_NetServerPasswordSet 128
1229 #define API_WNetAccountDeltas 129
1230 #define API_WNetAccountSync 130
1231 #define API_NetUserEnum2 131
1232 #define API_NetWkstaUserLogon 132
1233 #define API_NetWkstaUserLogoff 133
1234 #define API_NetLogonEnum 134
1235 #define API_NetErrorLogRead 135
1236 #define API_I_NetPathType 136
1237 #define API_I_NetPathCanonicalize 137
1238 #define API_I_NetPathCompare 138
1239 #define API_I_NetNameValidate 139
1240 #define API_I_NetNameCanonicalize 140
1241 #define API_I_NetNameCompare 141
1242 #define API_NetAuditRead 142
1243 #define API_WPrintDestAdd 143
1244 #define API_WPrintDestSetInfo 144
1245 #define API_WPrintDestDel 145
1246 #define API_NetUserValidate2 146
1247 #define API_WPrintJobSetInfo 147
1248 #define API_TI_NetServerDiskEnum 148
1249 #define API_TI_NetServerDiskGetInfo 149
1250 #define API_TI_FTVerifyMirror 150
1251 #define API_TI_FTAbortVerify 151
1252 #define API_TI_FTGetInfo 152
1253 #define API_TI_FTSetInfo 153
1254 #define API_TI_FTLockDisk 154
1255 #define API_TI_FTFixError 155
1256 #define API_TI_FTAbortFix 156
1257 #define API_TI_FTDiagnoseError 157
1258 #define API_TI_FTGetDriveStats 158
1259 /* This line and number replaced a Dead Entry for 159 */
1260 #define API_TI_FTErrorGetInfo 160
1261 /* This line and number replaced a Dead Entry for 161 */
1262 /* This line and number replaced a Dead Entry for 162 */
1263 #define API_NetAccessCheck 163
1264 #define API_NetAlertRaise 164
1265 #define API_NetAlertStart 165
1266 #define API_NetAlertStop 166
1267 #define API_NetAuditWrite 167
1268 #define API_NetIRemoteAPI 168
1269 #define API_NetServiceStatus 169
1270 #define API_I_NetServerRegister 170
1271 #define API_I_NetServerDeregister 171
1272 #define API_I_NetSessionEntryMake 172
1273 #define API_I_NetSessionEntryClear 173
1274 #define API_I_NetSessionEntryGetInfo 174
1275 #define API_I_NetSessionEntrySetInfo 175
1276 #define API_I_NetConnectionEntryMake 176
1277 #define API_I_NetConnectionEntryClear 177
1278 #define API_I_NetConnectionEntrySetInfo 178
1279 #define API_I_NetConnectionEntryGetInfo 179
1280 #define API_I_NetFileEntryMake 180
1281 #define API_I_NetFileEntryClear 181
1282 #define API_I_NetFileEntrySetInfo 182
1283 #define API_I_NetFileEntryGetInfo 183
1284 #define API_AltSrvMessageBufferSend 184
1285 #define API_AltSrvMessageFileSend 185
1286 #define API_wI_NetRplWkstaEnum 186
1287 #define API_wI_NetRplWkstaGetInfo 187
1288 #define API_wI_NetRplWkstaSetInfo 188
1289 #define API_wI_NetRplWkstaAdd 189
1290 #define API_wI_NetRplWkstaDel 190
1291 #define API_wI_NetRplProfileEnum 191
1292 #define API_wI_NetRplProfileGetInfo 192
1293 #define API_wI_NetRplProfileSetInfo 193
1294 #define API_wI_NetRplProfileAdd 194
1295 #define API_wI_NetRplProfileDel 195
1296 #define API_wI_NetRplProfileClone 196
1297 #define API_wI_NetRplBaseProfileEnum 197
1298 /* This line and number replaced a Dead Entry for 198 */
1299 /* This line and number replaced a Dead Entry for 199 */
1300 /* This line and number replaced a Dead Entry for 200 */
1301 #define API_WIServerSetInfo 201
1302 /* This line and number replaced a Dead Entry for 202 */
1303 /* This line and number replaced a Dead Entry for 203 */
1304 /* This line and number replaced a Dead Entry for 204 */
1305 #define API_WPrintDriverEnum 205
1306 #define API_WPrintQProcessorEnum 206
1307 #define API_WPrintPortEnum 207
1308 #define API_WNetWriteUpdateLog 208
1309 #define API_WNetAccountUpdate 209
1310 #define API_WNetAccountConfirmUpdate 210
1311 #define API_NetConfigSet 211
1312 #define API_WAccountsReplicate 212
1313 /* 213 is used by WfW */
1314 #define API_SamOEMChgPasswordUser2_P 214
1315 #define API_NetServerEnum3 215
1316 /* XXX - what about 216 through 249? */
1317 #define API_WPrintDriverGetInfo 250
1318 #define API_WPrintDriverSetInfo 251
1319 #define API_NetAliasAdd 252
1320 #define API_NetAliasDel 253
1321 #define API_NetAliasGetInfo 254
1322 #define API_NetAliasSetInfo 255
1323 #define API_NetAliasEnum 256
1324 #define API_NetUserGetLogonAsn 257
1325 #define API_NetUserSetLogonAsn 258
1326 #define API_NetUserGetAppSel 259
1327 #define API_NetUserSetAppSel 260
1328 #define API_NetAppAdd 261
1329 #define API_NetAppDel 262
1330 #define API_NetAppGetInfo 263
1331 #define API_NetAppSetInfo 264
1332 #define API_NetAppEnum 265
1333 #define API_NetUserDCDBInit 266
1334 #define API_NetDASDAdd 267
1335 #define API_NetDASDDel 268
1336 #define API_NetDASDGetInfo 269
1337 #define API_NetDASDSetInfo 270
1338 #define API_NetDASDEnum 271
1339 #define API_NetDASDCheck 272
1340 #define API_NetDASDCtl 273
1341 #define API_NetUserRemoteLogonCheck 274
1342 #define API_NetUserPasswordSet3 275
1343 #define API_NetCreateRIPLMachine 276
1344 #define API_NetDeleteRIPLMachine 277
1345 #define API_NetGetRIPLMachineInfo 278
1346 #define API_NetSetRIPLMachineInfo 279
1347 #define API_NetEnumRIPLMachine 280
1348 #define API_I_ShareAdd 281
1349 #define API_I_AliasEnum 282
1350 #define API_NetAccessApply 283
1351 #define API_WPrt16Query 284
1352 #define API_WPrt16Set 285
1353 #define API_NetUserDel100 286
1354 #define API_NetUserRemoteLogonCheck2 287
1355 #define API_WRemoteTODSet 294
1356 #define API_WPrintJobMoveAll 295
1357 #define API_W16AppParmAdd 296
1358 #define API_W16AppParmDel 297
1359 #define API_W16AppParmGet 298
1360 #define API_W16AppParmSet 299
1361 #define API_W16RIPLMachineCreate 300
1362 #define API_W16RIPLMachineGetInfo 301
1363 #define API_W16RIPLMachineSetInfo 302
1364 #define API_W16RIPLMachineEnum 303
1365 #define API_W16RIPLMachineListParmEnum 304
1366 #define API_W16RIPLMachClassGetInfo 305
1367 #define API_W16RIPLMachClassEnum 306
1368 #define API_W16RIPLMachClassCreate 307
1369 #define API_W16RIPLMachClassSetInfo 308
1370 #define API_W16RIPLMachClassDelete 309
1371 #define API_W16RIPLMachClassLPEnum 310
1372 #define API_W16RIPLMachineDelete 311
1373 #define API_W16WSLevelGetInfo 312
1374 #define API_NetServerNameAdd 313
1375 #define API_NetServerNameDel 314
1376 #define API_NetServerNameEnum 315
1377 #define API_I_WDASDEnum 316
1378 #define API_I_WDASDEnumTerminate 317
1379 #define API_I_WDASDSetInfo2 318
1381 static const struct lanman_desc lmd[] = {
1383 lm_params_req_netshareenum,
1388 lm_params_resp_netshareenum,
1391 netshareenum_share_entry,
1393 lm_data_resp_netshareenum,
1396 { API_NetShareGetInfo,
1397 lm_params_req_netsharegetinfo,
1402 lm_params_resp_netsharegetinfo,
1407 lm_data_resp_netsharegetinfo,
1410 { API_NetServerGetInfo,
1411 lm_params_req_netservergetinfo,
1416 lm_params_resp_netservergetinfo,
1424 { API_NetUserGetInfo,
1425 lm_params_req_netusergetinfo,
1430 lm_params_resp_netusergetinfo,
1435 lm_data_resp_netusergetinfo,
1438 { API_NetUserGetGroups,
1439 lm_params_req_netusergetgroups,
1444 lm_params_resp_netusergetgroups,
1449 lm_data_resp_netusergetgroups,
1463 lm_data_resp_netremotetod,
1466 { API_NetServerEnum2,
1467 lm_params_req_netserverenum2,
1472 lm_params_resp_netserverenum2,
1474 &ett_lanman_servers,
1475 netserverenum2_server_entry,
1480 { API_NetWkstaGetInfo,
1481 lm_params_req_netwkstagetinfo,
1486 lm_params_resp_netwkstagetinfo,
1491 lm_data_resp_netwkstagetinfo,
1494 { API_NetWkstaUserLogon,
1495 lm_params_req_netwkstauserlogon,
1500 lm_params_resp_netwkstauserlogon,
1505 lm_data_resp_netwkstauserlogon,
1508 { API_NetWkstaUserLogoff,
1509 lm_params_req_netwkstauserlogoff,
1514 lm_params_resp_netwkstauserlogoff,
1519 lm_data_resp_netwkstauserlogoff,
1522 { API_SamOEMChgPasswordUser2_P,
1523 lm_params_req_samoemchangepassword,
1526 lm_data_req_samoemchangepassword,
1546 &ett_lanman_unknown_entry,
1551 static const struct lanman_desc *
1552 find_lanman(int lanman_num)
1556 for (i = 0; lmd[i].lanman_num != -1; i++) {
1557 if (lmd[i].lanman_num == lanman_num)
1563 static const guchar *
1564 get_count(const guchar *desc, int *countp)
1569 if (!isdigit(*desc)) {
1570 *countp = 1; /* no count was supplied */
1574 while ((c = *desc) != '\0' && isdigit(c)) {
1575 count = (count * 10) + c - '0';
1579 *countp = count; /* XXX - what if it's 0? */
1584 dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1585 proto_tree *tree, const guchar *desc, const item_t *items,
1586 gboolean *has_data_p)
1594 *has_data_p = FALSE;
1595 while ((c = *desc++) != '\0') {
1600 * A 16-bit word value in the request.
1602 if (items->func == NULL) {
1604 * We've run out of items in the table;
1605 * fall back on the default.
1607 offset = add_word_param(tvb, offset, 0, pinfo,
1609 } else if (items->type != PARAM_WORD) {
1611 * Descriptor character is 'W', but this
1612 * isn't a word parameter.
1614 WParam = tvb_get_letohs(tvb, offset);
1615 proto_tree_add_text(tree, tvb, offset, 2,
1616 "%s: Value is %u (0x%04X), type is wrong (W)",
1617 (*items->hf_index == -1) ?
1619 proto_registrar_get_name(*items->hf_index),
1624 offset = (*items->func)(tvb, offset, 0, pinfo,
1625 tree, 0, *items->hf_index);
1632 * A 32-bit doubleword value in the request.
1634 if (items->func == NULL) {
1636 * We've run out of items in the table;
1637 * fall back on the default.
1639 offset = add_dword_param(tvb, offset, 0, pinfo,
1641 } else if (items->type != PARAM_DWORD) {
1643 * Descriptor character is 'D', but this
1644 * isn't a doubleword parameter.
1646 LParam = tvb_get_letohl(tvb, offset);
1647 proto_tree_add_text(tree, tvb, offset, 2,
1648 "%s: Value is %u (0x%08X), type is wrong (D)",
1649 (*items->hf_index == -1) ?
1650 "Doubleword Param" :
1651 proto_registrar_get_name(*items->hf_index),
1656 offset = (*items->func)(tvb, offset, 0, pinfo,
1657 tree, 0, *items->hf_index);
1664 * A byte or multi-byte value in the request.
1666 desc = get_count(desc, &count);
1667 if (items->func == NULL) {
1669 * We've run out of items in the table;
1670 * fall back on the default.
1672 offset = add_byte_param(tvb, offset, count,
1673 pinfo, tree, 0, -1);
1674 } else if (items->type != PARAM_BYTES) {
1676 * Descriptor character is 'b', but this
1677 * isn't a byte/bytes parameter.
1679 proto_tree_add_text(tree, tvb, offset, count,
1680 "%s: Value is %s, type is wrong (b)",
1681 (*items->hf_index == -1) ?
1683 proto_registrar_get_name(*items->hf_index),
1684 tvb_bytes_to_str(tvb, offset, count));
1688 offset = (*items->func)(tvb, offset, count,
1689 pinfo, tree, 0, *items->hf_index);
1698 if (items->func == NULL) {
1700 * We've run out of items in the table;
1701 * fall back on the default.
1703 add_null_pointer_param(tvb, offset, 0,
1704 pinfo, tree, 0, -1);
1707 * If "*items->hf_index" is -1, this is
1708 * a reserved must-be-null field; don't
1709 * clutter the protocol tree by putting
1712 if (*items->hf_index != -1) {
1713 add_null_pointer_param(tvb,
1714 offset, 0, pinfo, tree, 0,
1723 * A null-terminated ASCII string.
1725 if (items->func == NULL) {
1727 * We've run out of items in the table;
1728 * fall back on the default.
1730 offset = add_string_param(tvb, offset, 0,
1731 pinfo, tree, 0, -1);
1732 } else if (items->type != PARAM_STRINGZ) {
1734 * Descriptor character is 'z', but this
1735 * isn't a string parameter.
1737 string_len = tvb_strsize(tvb, offset);
1738 proto_tree_add_text(tree, tvb, offset, string_len,
1739 "%s: Value is %s, type is wrong (z)",
1740 (*items->hf_index == -1) ?
1742 proto_registrar_get_name(*items->hf_index),
1743 tvb_format_text(tvb, offset, string_len));
1744 offset += string_len;
1747 offset = (*items->func)(tvb, offset, 0,
1748 pinfo, tree, 0, *items->hf_index);
1755 * One or more pad bytes.
1757 desc = get_count(desc, &count);
1758 proto_tree_add_text(tree, tvb, offset, count,
1765 * 16-bit receive buffer length.
1767 proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1774 * 32-bit send buffer offset.
1775 * This appears not to be sent over the wire.
1782 * 16-bit send buffer length.
1784 proto_tree_add_item(tree, hf_send_buf_len, tvb,
1797 dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1798 proto_tree *tree, const guchar *desc, const item_t *items,
1799 gboolean *has_data_p, gboolean *has_ent_count_p, guint16 *ent_count_p)
1806 *has_data_p = FALSE;
1807 *has_ent_count_p = FALSE;
1808 while ((c = *desc++) != '\0') {
1813 * 32-bit receive buffer offset.
1820 * A byte or series of bytes is returned.
1822 desc = get_count(desc, &count);
1823 if (items->func == NULL) {
1825 * We've run out of items in the table;
1826 * fall back on the default.
1828 offset = add_byte_param(tvb, offset, count,
1829 pinfo, tree, 0, -1);
1830 } else if (items->type != PARAM_BYTES) {
1832 * Descriptor character is 'b', but this
1833 * isn't a byte/bytes parameter.
1835 proto_tree_add_text(tree, tvb, offset, count,
1836 "%s: Value is %s, type is wrong (g)",
1837 (*items->hf_index == -1) ?
1839 proto_registrar_get_name(*items->hf_index),
1840 tvb_bytes_to_str(tvb, offset, count));
1844 offset = (*items->func)(tvb, offset, count,
1845 pinfo, tree, 0, *items->hf_index);
1852 * A 16-bit word is received.
1854 if (items->func == NULL) {
1856 * We've run out of items in the table;
1857 * fall back on the default.
1859 offset = add_word_param(tvb, offset, 0, pinfo,
1861 } else if (items->type != PARAM_WORD) {
1863 * Descriptor character is 'h', but this
1864 * isn't a word parameter.
1866 WParam = tvb_get_letohs(tvb, offset);
1867 proto_tree_add_text(tree, tvb, offset, 2,
1868 "%s: Value is %u (0x%04X), type is wrong (W)",
1869 (*items->hf_index == -1) ?
1871 proto_registrar_get_name(*items->hf_index),
1876 offset = (*items->func)(tvb, offset, 0, pinfo,
1877 tree, 0, *items->hf_index);
1884 * A 32-bit doubleword is received.
1886 if (items->func == NULL) {
1888 * We've run out of items in the table;
1889 * fall back on the default.
1891 offset = add_dword_param(tvb, offset, 0, pinfo,
1893 } else if (items->type != PARAM_DWORD) {
1895 * Descriptor character is 'i', but this
1896 * isn't a doubleword parameter.
1898 LParam = tvb_get_letohl(tvb, offset);
1899 proto_tree_add_text(tree, tvb, offset, 2,
1900 "%s: Value is %u (0x%08X), type is wrong (i)",
1901 (*items->hf_index == -1) ?
1902 "Doubleword Param" :
1903 proto_registrar_get_name(*items->hf_index),
1908 offset = (*items->func)(tvb, offset, 0, pinfo,
1909 tree, 0, *items->hf_index);
1916 * A 16-bit entry count is returned.
1918 WParam = tvb_get_letohs(tvb, offset);
1919 proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1922 *has_ent_count_p = TRUE;
1923 *ent_count_p = WParam; /* Save this for later retrieval */
1934 dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1935 packet_info *pinfo, proto_tree *tree, const guchar *desc,
1936 const item_t *items, guint16 *aux_count_p)
1946 if (aux_count_p != NULL)
1949 while ((c = *desc++) != '\0') {
1954 * A 16-bit word value.
1955 * XXX - handle the count?
1957 desc = get_count(desc, &count);
1958 if (items->func == NULL) {
1960 * We've run out of items in the table;
1961 * fall back on the default.
1963 offset = add_word_param(tvb, offset, 0, pinfo,
1965 } else if (items->type != PARAM_WORD) {
1967 * Descriptor character is 'W', but this
1968 * isn't a word parameter.
1970 WParam = tvb_get_letohs(tvb, offset);
1971 proto_tree_add_text(tree, tvb, offset, 2,
1972 "%s: Value is %u (0x%04X), type is wrong (W)",
1973 (*items->hf_index == -1) ?
1975 proto_registrar_get_name(*items->hf_index),
1980 offset = (*items->func)(tvb, offset, 0, pinfo,
1981 tree, convert, *items->hf_index);
1988 * A 32-bit doubleword value.
1989 * XXX - handle the count?
1991 desc = get_count(desc, &count);
1992 if (items->func == NULL) {
1994 * We've run out of items in the table;
1995 * fall back on the default.
1997 offset = add_dword_param(tvb, offset, 0, pinfo,
1999 } else if (items->type != PARAM_DWORD) {
2001 * Descriptor character is 'D', but this
2002 * isn't a doubleword parameter.
2004 LParam = tvb_get_letohl(tvb, offset);
2005 proto_tree_add_text(tree, tvb, offset, 2,
2006 "%s: Value is %u (0x%08X), type is wrong (D)",
2007 (*items->hf_index == -1) ?
2008 "Doubleword Param" :
2009 proto_registrar_get_name(*items->hf_index),
2014 offset = (*items->func)(tvb, offset, 0, pinfo,
2015 tree, convert, *items->hf_index);
2022 * A byte or multi-byte value.
2024 desc = get_count(desc, &count);
2025 if (items->func == NULL) {
2027 * We've run out of items in the table;
2028 * fall back on the default.
2030 offset = add_byte_param(tvb, offset, count,
2031 pinfo, tree, convert, -1);
2032 } else if (items->type != PARAM_BYTES) {
2034 * Descriptor character is 'B', but this
2035 * isn't a byte/bytes parameter.
2037 proto_tree_add_text(tree, tvb, offset, count,
2038 "%s: Value is %s, type is wrong (B)",
2039 (*items->hf_index == -1) ?
2041 proto_registrar_get_name(*items->hf_index),
2042 tvb_bytes_to_str(tvb, offset, count));
2046 offset = (*items->func)(tvb, offset, count,
2047 pinfo, tree, convert, *items->hf_index);
2056 if (items->func == NULL) {
2058 * We've run out of items in the table;
2059 * fall back on the default.
2061 add_null_pointer_param(tvb, offset, 0,
2062 pinfo, tree, convert, -1);
2065 * If "*items->hf_index" is -1, this is
2066 * a reserved must-be-null field; don't
2067 * clutter the protocol tree by putting
2070 if (*items->hf_index != -1) {
2071 add_null_pointer_param(tvb,
2072 offset, 0, pinfo, tree, convert,
2081 * A pointer to a null-terminated ASCII string.
2083 if (items->func == NULL) {
2085 * We've run out of items in the table;
2086 * fall back on the default.
2088 offset = add_stringz_pointer_param(tvb, offset,
2089 0, pinfo, tree, convert, -1);
2090 } else if (items->type != PARAM_STRINGZ) {
2092 * Descriptor character is 'z', but this
2093 * isn't a string parameter.
2095 string = get_stringz_pointer_value(tvb, offset,
2096 convert, &cptr, &string_len);
2098 proto_tree_add_text(tree, tvb, cptr, string_len,
2099 "%s: Value is %s, type is wrong (z)",
2100 (*items->hf_index == -1) ?
2102 proto_registrar_get_name(*items->hf_index),
2106 offset = (*items->func)(tvb, offset, 0,
2107 pinfo, tree, convert, *items->hf_index);
2114 * A pointer to a byte or multi-byte value.
2116 desc = get_count(desc, &count);
2117 if (items->func == NULL) {
2119 * We've run out of items in the table;
2120 * fall back on the default.
2122 offset = add_bytes_pointer_param(tvb, offset,
2123 count, pinfo, tree, convert, -1);
2124 } else if (items->type != PARAM_BYTES) {
2126 * Descriptor character is 'b', but this
2127 * isn't a byte/bytes parameter.
2129 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2131 proto_tree_add_text(tree, tvb, offset, count,
2132 "%s: Value is %s, type is wrong (b)",
2133 (*items->hf_index == -1) ?
2135 proto_registrar_get_name(*items->hf_index),
2136 tvb_bytes_to_str(tvb, cptr, count));
2139 offset = (*items->func)(tvb, offset, count,
2140 pinfo, tree, convert, *items->hf_index);
2147 * 16-bit auxiliary data structure count.
2150 WParam = tvb_get_letohs(tvb, offset);
2151 proto_tree_add_text(tree, tvb, offset, 2,
2153 "Auxiliary data structure count",
2156 if (aux_count_p != NULL)
2157 *aux_count_p = WParam; /* Save this for later retrieval */
2167 static const value_string commands[] = {
2168 {API_NetShareEnum, "NetShareEnum"},
2169 {API_NetShareGetInfo, "NetShareGetInfo"},
2170 {API_NetShareSetInfo, "NetShareSetInfo"},
2171 {API_NetShareAdd, "NetShareAdd"},
2172 {API_NetShareDel, "NetShareDel"},
2173 {API_NetShareCheck, "NetShareCheck"},
2174 {API_NetSessionEnum, "NetSessionEnum"},
2175 {API_NetSessionGetInfo, "NetSessionGetInfo"},
2176 {API_NetSessionDel, "NetSessionDel"},
2177 {API_WconnectionEnum, "NetConnectionEnum"},
2178 {API_NetFileEnum, "NetFileEnum"},
2179 {API_NetFileGetInfo, "NetFileGetInfo"},
2180 {API_NetFileClose, "NetFileClose"},
2181 {API_NetServerGetInfo, "NetServerGetInfo"},
2182 {API_NetServerSetInfo, "NetServerSetInfo"},
2183 {API_NetServerDiskEnum, "NetServerDiskEnum"},
2184 {API_NetServerAdminCommand, "NetServerAdminCommand"},
2185 {API_NetAuditOpen, "NetAuditOpen"},
2186 {API_NetAuditClear, "NetAuditClear"},
2187 {API_NetErrorLogOpen, "NetErrorLogOpen"},
2188 {API_NetErrorLogClear, "NetErrorLogClear"},
2189 {API_NetCharDevEnum, "NetCharDevEnum"},
2190 {API_NetCharDevGetInfo, "NetCharDevGetInfo"},
2191 {API_NetCharDevControl, "NetCharDevControl"},
2192 {API_NetCharDevQEnum, "NetCharDevQEnum"},
2193 {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"},
2194 {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"},
2195 {API_NetCharDevQPurge, "NetCharDevQPurge"},
2196 {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"},
2197 {API_NetMessageNameEnum, "NetMessageNameEnum"},
2198 {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"},
2199 {API_NetMessageNameAdd, "NetMessageNameAdd"},
2200 {API_NetMessageNameDel, "NetMessageNameDel"},
2201 {API_NetMessageNameFwd, "NetMessageNameFwd"},
2202 {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"},
2203 {API_NetMessageBufferSend, "NetMessageBufferSend"},
2204 {API_NetMessageFileSend, "NetMessageFileSend"},
2205 {API_NetMessageLogFileSet, "NetMessageLogFileSet"},
2206 {API_NetMessageLogFileGet, "NetMessageLogFileGet"},
2207 {API_NetServiceEnum, "NetServiceEnum"},
2208 {API_NetServiceInstall, "NetServiceInstall"},
2209 {API_NetServiceControl, "NetServiceControl"},
2210 {API_NetAccessEnum, "NetAccessEnum"},
2211 {API_NetAccessGetInfo, "NetAccessGetInfo"},
2212 {API_NetAccessSetInfo, "NetAccessSetInfo"},
2213 {API_NetAccessAdd, "NetAccessAdd"},
2214 {API_NetAccessDel, "NetAccessDel"},
2215 {API_NetGroupEnum, "NetGroupEnum"},
2216 {API_NetGroupAdd, "NetGroupAdd"},
2217 {API_NetGroupDel, "NetGroupDel"},
2218 {API_NetGroupAddUser, "NetGroupAddUser"},
2219 {API_NetGroupDelUser, "NetGroupDelUser"},
2220 {API_NetGroupGetUsers, "NetGroupGetUsers"},
2221 {API_NetUserEnum, "NetUserEnum"},
2222 {API_NetUserAdd, "NetUserAdd"},
2223 {API_NetUserDel, "NetUserDel"},
2224 {API_NetUserGetInfo, "NetUserGetInfo"},
2225 {API_NetUserSetInfo, "NetUserSetInfo"},
2226 {API_NetUserPasswordSet, "NetUserPasswordSet"},
2227 {API_NetUserGetGroups, "NetUserGetGroups"},
2228 {API_NetWkstaSetUID, "NetWkstaSetUID"},
2229 {API_NetWkstaGetInfo, "NetWkstaGetInfo"},
2230 {API_NetWkstaSetInfo, "NetWkstaSetInfo"},
2231 {API_NetUseEnum, "NetUseEnum"},
2232 {API_NetUseAdd, "NetUseAdd"},
2233 {API_NetUseDel, "NetUseDel"},
2234 {API_NetUseGetInfo, "NetUseGetInfo"},
2235 {API_WPrintQEnum, "WPrintQEnum"},
2236 {API_WPrintQGetInfo, "WPrintQGetInfo"},
2237 {API_WPrintQSetInfo, "WPrintQSetInfo"},
2238 {API_WPrintQAdd, "WPrintQAdd"},
2239 {API_WPrintQDel, "WPrintQDel"},
2240 {API_WPrintQPause, "WPrintQPause"},
2241 {API_WPrintQContinue, "WPrintQContinue"},
2242 {API_WPrintJobEnum, "WPrintJobEnum"},
2243 {API_WPrintJobGetInfo, "WPrintJobGetInfo"},
2244 {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"},
2245 {API_WPrintJobDel, "WPrintJobDel"},
2246 {API_WPrintJobPause, "WPrintJobPause"},
2247 {API_WPrintJobContinue, "WPrintJobContinue"},
2248 {API_WPrintDestEnum, "WPrintDestEnum"},
2249 {API_WPrintDestGetInfo, "WPrintDestGetInfo"},
2250 {API_WPrintDestControl, "WPrintDestControl"},
2251 {API_NetProfileSave, "NetProfileSave"},
2252 {API_NetProfileLoad, "NetProfileLoad"},
2253 {API_NetStatisticsGet, "NetStatisticsGet"},
2254 {API_NetStatisticsClear, "NetStatisticsClear"},
2255 {API_NetRemoteTOD, "NetRemoteTOD"},
2256 {API_WNetBiosEnum, "WNetBiosEnum"},
2257 {API_WNetBiosGetInfo, "WNetBiosGetInfo"},
2258 {API_NetServerEnum, "NetServerEnum"},
2259 {API_I_NetServerEnum, "I_NetServerEnum"},
2260 {API_NetServiceGetInfo, "NetServiceGetInfo"},
2261 {API_WPrintQPurge, "WPrintQPurge"},
2262 {API_NetServerEnum2, "NetServerEnum2"},
2263 {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"},
2264 {API_NetGroupGetInfo, "NetGroupGetInfo"},
2265 {API_NetGroupSetInfo, "NetGroupSetInfo"},
2266 {API_NetGroupSetUsers, "NetGroupSetUsers"},
2267 {API_NetUserSetGroups, "NetUserSetGroups"},
2268 {API_NetUserModalsGet, "NetUserModalsGet"},
2269 {API_NetUserModalsSet, "NetUserModalsSet"},
2270 {API_NetFileEnum2, "NetFileEnum2"},
2271 {API_NetUserAdd2, "NetUserAdd2"},
2272 {API_NetUserSetInfo2, "NetUserSetInfo2"},
2273 {API_NetUserPasswordSet2, "SetUserPassword"},
2274 {API_I_NetServerEnum2, "I_NetServerEnum2"},
2275 {API_NetConfigGet2, "NetConfigGet2"},
2276 {API_NetConfigGetAll2, "NetConfigGetAll2"},
2277 {API_NetGetDCName, "NetGetDCName"},
2278 {API_NetHandleGetInfo, "NetHandleGetInfo"},
2279 {API_NetHandleSetInfo, "NetHandleSetInfo"},
2280 {API_NetStatisticsGet2, "NetStatisticsGet2"},
2281 {API_WBuildGetInfo, "WBuildGetInfo"},
2282 {API_NetFileGetInfo2, "NetFileGetInfo2"},
2283 {API_NetFileClose2, "NetFileClose2"},
2284 {API_NetServerReqChallenge, "NetServerReqChallenge"},
2285 {API_NetServerAuthenticate, "NetServerAuthenticate"},
2286 {API_NetServerPasswordSet, "NetServerPasswordSet"},
2287 {API_WNetAccountDeltas, "WNetAccountDeltas"},
2288 {API_WNetAccountSync, "WNetAccountSync"},
2289 {API_NetUserEnum2, "NetUserEnum2"},
2290 {API_NetWkstaUserLogon, "NetWkstaUserLogon"},
2291 {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"},
2292 {API_NetLogonEnum, "NetLogonEnum"},
2293 {API_NetErrorLogRead, "NetErrorLogRead"},
2294 {API_I_NetPathType, "I_NetPathType"},
2295 {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"},
2296 {API_I_NetPathCompare, "I_NetPathCompare"},
2297 {API_I_NetNameValidate, "I_NetNameValidate"},
2298 {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"},
2299 {API_I_NetNameCompare, "I_NetNameCompare"},
2300 {API_NetAuditRead, "NetAuditRead"},
2301 {API_WPrintDestAdd, "WPrintDestAdd"},
2302 {API_WPrintDestSetInfo, "WPrintDestSetInfo"},
2303 {API_WPrintDestDel, "WPrintDestDel"},
2304 {API_NetUserValidate2, "NetUserValidate2"},
2305 {API_WPrintJobSetInfo, "WPrintJobSetInfo"},
2306 {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"},
2307 {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"},
2308 {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"},
2309 {API_TI_FTAbortVerify, "TI_FTAbortVerify"},
2310 {API_TI_FTGetInfo, "TI_FTGetInfo"},
2311 {API_TI_FTSetInfo, "TI_FTSetInfo"},
2312 {API_TI_FTLockDisk, "TI_FTLockDisk"},
2313 {API_TI_FTFixError, "TI_FTFixError"},
2314 {API_TI_FTAbortFix, "TI_FTAbortFix"},
2315 {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"},
2316 {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"},
2317 {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"},
2318 {API_NetAccessCheck, "NetAccessCheck"},
2319 {API_NetAlertRaise, "NetAlertRaise"},
2320 {API_NetAlertStart, "NetAlertStart"},
2321 {API_NetAlertStop, "NetAlertStop"},
2322 {API_NetAuditWrite, "NetAuditWrite"},
2323 {API_NetIRemoteAPI, "NetIRemoteAPI"},
2324 {API_NetServiceStatus, "NetServiceStatus"},
2325 {API_I_NetServerRegister, "I_NetServerRegister"},
2326 {API_I_NetServerDeregister, "I_NetServerDeregister"},
2327 {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"},
2328 {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"},
2329 {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"},
2330 {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"},
2331 {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"},
2332 {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"},
2333 {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2334 {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2335 {API_I_NetFileEntryMake, "I_NetFileEntryMake"},
2336 {API_I_NetFileEntryClear, "I_NetFileEntryClear"},
2337 {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"},
2338 {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"},
2339 {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"},
2340 {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"},
2341 {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"},
2342 {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"},
2343 {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"},
2344 {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"},
2345 {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"},
2346 {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"},
2347 {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"},
2348 {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"},
2349 {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"},
2350 {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"},
2351 {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"},
2352 {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"},
2353 {API_WIServerSetInfo, "WIServerSetInfo"},
2354 {API_WPrintDriverEnum, "WPrintDriverEnum"},
2355 {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"},
2356 {API_WPrintPortEnum, "WPrintPortEnum"},
2357 {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"},
2358 {API_WNetAccountUpdate, "WNetAccountUpdate"},
2359 {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"},
2360 {API_NetConfigSet, "NetConfigSet"},
2361 {API_WAccountsReplicate, "WAccountsReplicate"},
2362 {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"},
2363 {API_NetServerEnum3, "NetServerEnum3"},
2364 {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"},
2365 {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"},
2366 {API_NetAliasAdd, "NetAliasAdd"},
2367 {API_NetAliasDel, "NetAliasDel"},
2368 {API_NetAliasGetInfo, "NetAliasGetInfo"},
2369 {API_NetAliasSetInfo, "NetAliasSetInfo"},
2370 {API_NetAliasEnum, "NetAliasEnum"},
2371 {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"},
2372 {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"},
2373 {API_NetUserGetAppSel, "NetUserGetAppSel"},
2374 {API_NetUserSetAppSel, "NetUserSetAppSel"},
2375 {API_NetAppAdd, "NetAppAdd"},
2376 {API_NetAppDel, "NetAppDel"},
2377 {API_NetAppGetInfo, "NetAppGetInfo"},
2378 {API_NetAppSetInfo, "NetAppSetInfo"},
2379 {API_NetAppEnum, "NetAppEnum"},
2380 {API_NetUserDCDBInit, "NetUserDCDBInit"},
2381 {API_NetDASDAdd, "NetDASDAdd"},
2382 {API_NetDASDDel, "NetDASDDel"},
2383 {API_NetDASDGetInfo, "NetDASDGetInfo"},
2384 {API_NetDASDSetInfo, "NetDASDSetInfo"},
2385 {API_NetDASDEnum, "NetDASDEnum"},
2386 {API_NetDASDCheck, "NetDASDCheck"},
2387 {API_NetDASDCtl, "NetDASDCtl"},
2388 {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"},
2389 {API_NetUserPasswordSet3, "NetUserPasswordSet3"},
2390 {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"},
2391 {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"},
2392 {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"},
2393 {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"},
2394 {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"},
2395 {API_I_ShareAdd, "I_ShareAdd"},
2396 {API_I_AliasEnum, "I_AliasEnum"},
2397 {API_NetAccessApply, "NetAccessApply"},
2398 {API_WPrt16Query, "WPrt16Query"},
2399 {API_WPrt16Set, "WPrt16Set"},
2400 {API_NetUserDel100, "NetUserDel100"},
2401 {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"},
2402 {API_WRemoteTODSet, "WRemoteTODSet"},
2403 {API_WPrintJobMoveAll, "WPrintJobMoveAll"},
2404 {API_W16AppParmAdd, "W16AppParmAdd"},
2405 {API_W16AppParmDel, "W16AppParmDel"},
2406 {API_W16AppParmGet, "W16AppParmGet"},
2407 {API_W16AppParmSet, "W16AppParmSet"},
2408 {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"},
2409 {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"},
2410 {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"},
2411 {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"},
2412 {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"},
2413 {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"},
2414 {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"},
2415 {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"},
2416 {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"},
2417 {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"},
2418 {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"},
2419 {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"},
2420 {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"},
2421 {API_NetServerNameAdd, "NetServerNameAdd"},
2422 {API_NetServerNameDel, "NetServerNameDel"},
2423 {API_NetServerNameEnum, "NetServerNameEnum"},
2424 {API_I_WDASDEnum, "I_WDASDEnum"},
2425 {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"},
2426 {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"},
2431 dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2432 proto_tree *tree, struct smb_info *smb_info,
2433 const struct lanman_desc *lanman, gboolean has_ent_count,
2436 smb_transact_info_t *trp = smb_info->sip->extra_info;
2437 const item_list_t *resp_data_list;
2438 int offset, start_offset;
2441 const item_t *resp_data;
2442 proto_item *data_item;
2443 proto_tree *data_tree;
2444 proto_item *entry_item;
2445 proto_tree *entry_tree;
2450 * Find the item table for the matching request's detail level.
2452 for (resp_data_list = lanman->resp_data_list;
2453 resp_data_list->level != -1; resp_data_list++) {
2454 if (resp_data_list->level == trp->info_level)
2457 resp_data = resp_data_list->item_list;
2460 if (has_ent_count) {
2462 * The data is a list of entries; create a protocol tree item
2466 label = lanman->resp_data_entry_list_label;
2469 if (lanman->ett_data_entry_list != NULL)
2470 ett = *lanman->ett_data_entry_list;
2472 ett = ett_lanman_unknown_entries;
2473 data_item = proto_tree_add_text(tree, tvb, offset, -1,
2475 data_tree = proto_item_add_subtree(data_item, ett);
2482 * Just leave it at the top level.
2488 if (trp->data_descrip == NULL) {
2490 * This could happen if we only dissected
2491 * part of the request to which this is a
2492 * reply, e.g. if the request was split
2493 * across TCP segments and we weren't doing
2494 * TCP desegmentation, or if we had a snapshot
2495 * length that was too short.
2497 * We can't dissect the data; just show it as raw data or,
2498 * if we've already created a top-level item, note that
2499 * no descriptor is available.
2501 if (has_ent_count) {
2502 if (data_item != NULL) {
2503 proto_item_append_text(data_item,
2504 " (No descriptor available)");
2507 proto_tree_add_text(data_tree, tvb, offset, -1,
2508 "Data (no descriptor available)");
2510 offset += tvb_length_remaining(tvb, offset);
2513 * If we have an entry count, show all the entries,
2514 * with each one having a protocol tree item.
2516 * Otherwise, we just show one returned item, with
2517 * no protocol tree item.
2521 for (i = 0; i < ent_count; i++) {
2522 start_offset = offset;
2523 if (has_ent_count &&
2524 lanman->resp_data_element_item != NULL) {
2526 * Create a protocol tree item for the
2530 (*lanman->resp_data_element_item)
2531 (tvb, data_tree, offset);
2532 entry_tree = proto_item_add_subtree(
2534 *lanman->ett_resp_data_element_item);
2537 * Just leave it at the current
2541 entry_tree = data_tree;
2544 offset = dissect_transact_data(tvb, offset,
2545 convert, pinfo, entry_tree,
2546 trp->data_descrip, resp_data, &aux_count);
2548 /* auxiliary data */
2549 if (trp->aux_data_descrip != NULL) {
2550 for (j = 0; j < aux_count; j++) {
2551 offset = dissect_transact_data(
2552 tvb, offset, convert,
2555 lanman->resp_aux_data, NULL);
2559 if (entry_item != NULL) {
2561 * Set the length of the protocol tree
2562 * item for the entry.
2564 proto_item_set_len(entry_item,
2565 offset - start_offset);
2570 if (data_item != NULL) {
2572 * Set the length of the protocol tree item
2575 proto_item_set_len(data_item, offset);
2580 dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2581 packet_info *pinfo, proto_tree *parent_tree)
2583 smb_info_t *smb_info = pinfo->private_data;
2584 smb_transact_info_t *trp = smb_info->sip->extra_info;
2585 int offset = 0, start_offset;
2589 const struct lanman_desc *lanman;
2590 proto_item *item = NULL;
2591 proto_tree *tree = NULL;
2592 guint descriptor_len;
2593 const gchar *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2595 gboolean has_ent_count;
2596 guint16 ent_count, aux_count;
2598 proto_item *data_item;
2599 proto_tree *data_tree;
2601 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2603 if (smb_info->request && p_tvb == NULL) {
2605 * Requests must have parameters.
2609 pinfo->current_proto = "LANMAN";
2611 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2612 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2616 item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2617 pd_tvb, 0, -1, FALSE);
2618 tree = proto_item_add_subtree(item, ett_lanman);
2621 if (smb_info->request) { /* this is a request */
2623 cmd = tvb_get_letohs(p_tvb, offset);
2624 if (check_col(pinfo->cinfo, COL_INFO)) {
2625 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str(cmd, commands, "Unknown Command (%u)"));
2627 proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2632 * If we haven't already done so, save the function code in
2633 * the structure we were handed, so that it's available to
2634 * the code parsing the reply, and initialize the detail
2635 * level to -1, meaning "unknown".
2637 if (!pinfo->fd->flags.visited) {
2638 trp->lanman_cmd = cmd;
2639 trp->info_level = -1;
2640 trp->param_descrip=NULL;
2641 trp->data_descrip=NULL;
2642 trp->aux_data_descrip=NULL;
2645 /* parameter descriptor */
2646 descriptor_len = tvb_strsize(p_tvb, offset);
2647 proto_tree_add_item(tree, hf_param_desc, p_tvb, offset,
2648 descriptor_len, TRUE);
2649 param_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2650 if (!pinfo->fd->flags.visited) {
2652 * Save the parameter descriptor for future use.
2654 g_assert(trp->param_descrip == NULL);
2655 trp->param_descrip = g_strdup(param_descrip);
2657 offset += descriptor_len;
2659 /* return descriptor */
2660 descriptor_len = tvb_strsize(p_tvb, offset);
2661 proto_tree_add_item(tree, hf_return_desc, p_tvb, offset,
2662 descriptor_len, TRUE);
2663 data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2664 if (!pinfo->fd->flags.visited) {
2666 * Save the return descriptor for future use.
2668 g_assert(trp->data_descrip == NULL);
2669 trp->data_descrip = g_strdup(data_descrip);
2671 offset += descriptor_len;
2673 lanman = find_lanman(cmd);
2675 /* request parameters */
2676 start_offset = offset;
2677 offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2678 param_descrip, lanman->req, &has_data);
2680 /* auxiliary data descriptor */
2681 if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2683 * There are more parameters left, so the next
2684 * item is the auxiliary data descriptor.
2686 descriptor_len = tvb_strsize(p_tvb, offset);
2687 proto_tree_add_item(tree, hf_aux_data_desc, p_tvb, offset,
2688 descriptor_len, TRUE);
2689 aux_data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2690 if (!pinfo->fd->flags.visited) {
2692 * Save the auxiliary data descriptor for
2695 g_assert(trp->aux_data_descrip == NULL);
2696 trp->aux_data_descrip =
2697 g_strdup(aux_data_descrip);
2699 offset += descriptor_len;
2702 /* reset offset, we now start dissecting the data area */
2704 if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2706 * There's a send buffer item in the descriptor
2707 * string, and the data count in the transaction
2708 * is non-zero, so there's data to dissect.
2711 if (lanman->req_data_item != NULL) {
2713 * Create a protocol tree item for the data.
2715 data_item = (*lanman->req_data_item)(d_tvb,
2716 pinfo, tree, offset);
2717 data_tree = proto_item_add_subtree(data_item,
2718 *lanman->ett_req_data);
2721 * Just leave it at the top level.
2728 offset = dissect_transact_data(d_tvb, offset, -1,
2729 pinfo, data_tree, data_descrip, lanman->req_data,
2730 &aux_count); /* XXX - what about strings? */
2732 /* auxiliary data */
2733 if (aux_data_descrip != NULL) {
2734 for (i = 0; i < aux_count; i++) {
2735 offset = dissect_transact_data(d_tvb,
2736 offset, -1, pinfo, data_tree,
2738 lanman->req_aux_data, NULL);
2742 if (data_item != NULL) {
2744 * Set the length of the protocol tree item
2747 proto_item_set_len(data_item, offset);
2752 * This is a response.
2753 * Have we seen the request to which it's a response?
2756 return FALSE; /* no - can't dissect it */
2758 /* ok we have seen this one before */
2760 /* if it looks like an interim response, update COL_INFO and return */
2761 if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
2762 && ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
2764 if (check_col(pinfo->cinfo, COL_INFO)) {
2765 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2766 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2768 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2773 if (check_col(pinfo->cinfo, COL_INFO)) {
2774 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2775 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2777 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2780 lanman = find_lanman(trp->lanman_cmd);
2782 /* response parameters */
2785 status = tvb_get_letohs(p_tvb, offset);
2786 proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2790 convert = tvb_get_letohs(p_tvb, offset);
2791 proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2794 if (trp->param_descrip == NULL) {
2796 * This could happen if we only dissected
2797 * part of the request to which this is a
2798 * reply, e.g. if the request was split
2799 * across TCP segments and we weren't doing
2800 * TCP desegmentation, or if we had a snapshot
2801 * length that was too short.
2803 * We can't dissect the parameters; just show them
2806 proto_tree_add_text(tree, p_tvb, offset, -1,
2807 "Parameters (no descriptor available)");
2810 * We don't know whether we have a receive buffer,
2811 * as we don't have the descriptor; just show what
2812 * bytes purport to be data.
2814 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2815 proto_tree_add_text(tree, d_tvb, 0, -1,
2816 "Data (no descriptor available)");
2819 /* rest of the parameters */
2820 offset = dissect_response_parameters(p_tvb, offset,
2821 pinfo, tree, trp->param_descrip, lanman->resp,
2822 &has_data, &has_ent_count, &ent_count);
2824 /* reset offset, we now start dissecting the data area */
2827 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2829 * Well, there are bytes that purport to
2830 * be data, at least.
2834 * There's a receive buffer item
2835 * in the descriptor string, so
2836 * dissect it as response data.
2838 dissect_response_data(d_tvb, pinfo,
2839 convert, tree, smb_info, lanman,
2840 has_ent_count, ent_count);
2843 * There's no receive buffer item,
2844 * but we do have data, so just
2845 * show what bytes are data.
2847 proto_tree_add_text(tree, d_tvb, 0, -1,
2848 "Data (no receive buffer)");
2858 proto_register_pipe_lanman(void)
2860 static hf_register_info hf[] = {
2861 { &hf_function_code,
2862 { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC,
2863 VALS(commands), 0, "LANMAN Function Code/Command", HFILL }},
2866 { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2867 NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2870 { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2871 NULL, 0, "LANMAN Return Descriptor", HFILL }},
2873 { &hf_aux_data_desc,
2874 { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2875 NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2878 { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2879 NULL, 0, "LANMAN Detail Level", HFILL }},
2882 { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2883 NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2886 { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2887 NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2889 { &hf_continuation_from,
2890 { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2891 NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2894 { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2895 VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2898 { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2899 NULL, 0, "LANMAN Convert", HFILL }},
2902 { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2903 NULL, 0, "LANMAN Number of Entries", HFILL }},
2906 { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2907 NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2910 { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2911 NULL, 0, "LANMAN Name of Share", HFILL }},
2914 { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2915 VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2917 { &hf_share_comment,
2918 { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2919 NULL, 0, "LANMAN Share Comment", HFILL }},
2921 { &hf_share_permissions,
2922 { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2923 NULL, 0, "LANMAN Permissions on share", HFILL }},
2925 { &hf_share_max_uses,
2926 { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2927 NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2929 { &hf_share_current_uses,
2930 { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2931 NULL, 0, "LANMAN Current connections to share", HFILL }},
2934 { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2935 NULL, 0, "LANMAN Share Path", HFILL }},
2937 { &hf_share_password,
2938 { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2939 NULL, 0, "LANMAN Share Password", HFILL }},
2942 { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2943 NULL, 0, "LANMAN Name of Server", HFILL }},
2946 { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2947 NULL, 0, "LANMAN Server Major Version", HFILL }},
2950 { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2951 NULL, 0, "LANMAN Server Minor Version", HFILL }},
2953 { &hf_server_comment,
2954 { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
2955 NULL, 0, "LANMAN Server Comment", HFILL }},
2958 { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
2959 NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
2962 { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, BASE_NONE,
2963 NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
2966 { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
2967 NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
2970 { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
2971 NULL, 0, "LANMAN Current hour", HFILL }},
2974 { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
2975 NULL, 0, "LANMAN Current minute", HFILL }},
2978 { "Second", "lanman.second", FT_UINT8, BASE_DEC,
2979 NULL, 0, "LANMAN Current second", HFILL }},
2982 { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
2983 NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
2986 { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
2987 NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
2990 { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
2991 NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
2994 { "Day", "lanman.day", FT_UINT8, BASE_DEC,
2995 NULL, 0, "LANMAN Current day", HFILL }},
2998 { "Month", "lanman.month", FT_UINT8, BASE_DEC,
2999 NULL, 0, "LANMAN Current month", HFILL }},
3002 { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3003 NULL, 0, "LANMAN Current year", HFILL }},
3006 { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3007 VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3009 { &hf_enumeration_domain,
3010 { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3011 NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3013 { &hf_computer_name,
3014 { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3015 NULL, 0, "LANMAN Computer Name", HFILL }},
3018 { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3019 NULL, 0, "LANMAN User Name", HFILL }},
3022 { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3023 NULL, 0, "LANMAN Group Name", HFILL }},
3025 { &hf_workstation_domain,
3026 { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3027 NULL, 0, "LANMAN Workstation Domain", HFILL }},
3029 { &hf_workstation_major,
3030 { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3031 NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3033 { &hf_workstation_minor,
3034 { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3035 NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3038 { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3039 NULL, 0, "LANMAN Logon Domain", HFILL }},
3041 { &hf_other_domains,
3042 { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3043 NULL, 0, "LANMAN Other Domains", HFILL }},
3046 { "Password", "lanman.password", FT_STRING, BASE_NONE,
3047 NULL, 0, "LANMAN Password", HFILL }},
3049 { &hf_workstation_name,
3050 { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3051 NULL, 0, "LANMAN Workstation Name", HFILL }},
3054 { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3055 NULL, 0, "LANMAN UStruct Length", HFILL }},
3058 { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3059 VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3061 { &hf_privilege_level,
3062 { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3063 VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3065 { &hf_operator_privileges,
3066 { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3067 VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3070 { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3071 NULL, 0, "LANMAN Number of Logons", HFILL }},
3074 { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3075 NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3078 { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, BASE_NONE,
3079 NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3082 { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, BASE_NONE,
3083 NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3086 { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3087 NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3090 { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3091 NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3094 { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3095 NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3097 { &hf_password_can_change,
3098 { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, BASE_NONE,
3099 NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3101 { &hf_password_must_change,
3102 { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, BASE_NONE,
3103 NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3106 { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3107 NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3110 { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3111 VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3114 { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3115 NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3118 { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3119 NULL, 0, "LANMAN Comment", HFILL }},
3122 { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3123 NULL, 0, "LANMAN User Comment", HFILL }},
3126 { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3127 NULL, 0, "LANMAN Full Name", HFILL }},
3130 { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3131 NULL, 0, "LANMAN Home Directory", HFILL }},
3134 { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3135 NULL, 0, "LANMAN Parameters", HFILL }},
3138 { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3139 NULL, 0, "LANMAN Logon Server", HFILL }},
3141 /* XXX - we should have a value_string table for this */
3143 { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC,
3144 VALS(ms_country_codes), 0, "LANMAN Country Code", HFILL }},
3147 { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3148 NULL, 0, "LANMAN Workstations", HFILL }},
3151 { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3152 NULL, 0, "LANMAN Max Storage", HFILL }},
3154 { &hf_units_per_week,
3155 { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3156 NULL, 0, "LANMAN Units Per Week", HFILL }},
3159 { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3160 NULL, 0, "LANMAN Logon Hours", HFILL }},
3162 /* XXX - we should have a value_string table for this */
3164 { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3165 NULL, 0, "LANMAN Code Page", HFILL }},
3168 { "New Password", "lanman.new_password", FT_BYTES, BASE_HEX,
3169 NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3172 { "Old Password", "lanman.old_password", FT_BYTES, BASE_HEX,
3173 NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3176 { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3177 NULL, 0, "LANMAN Reserved", HFILL }},
3180 static gint *ett[] = {
3182 &ett_lanman_unknown_entries,
3183 &ett_lanman_unknown_entry,
3184 &ett_lanman_servers,
3191 proto_smb_lanman = proto_register_protocol(
3192 "Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3193 proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3194 proto_register_subtree_array(ett, array_length(ett));
3197 static heur_dissector_list_t smb_transact_heur_subdissector_list;
3199 static GHashTable *dcerpc_fragment_table = NULL;
3200 static GHashTable *dcerpc_reassembled_table = NULL;
3203 smb_dcerpc_reassembly_init(void)
3205 fragment_table_init(&dcerpc_fragment_table);
3206 reassembled_table_init(&dcerpc_reassembled_table);
3210 dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3211 proto_tree *tree, guint32 fid)
3213 dcerpc_private_info dcerpc_priv;
3214 smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
3216 gboolean save_fragmented;
3219 fragment_data *fd_head;
3222 dcerpc_priv.transport_type = DCERPC_TRANSPORT_SMB;
3223 dcerpc_priv.data.smb.fid = fid;
3225 pinfo->private_data = &dcerpc_priv;
3229 * Offer desegmentation service to DCERPC if we have all the
3230 * data. Otherwise, reassembly is (probably) impossible.
3232 pinfo->can_desegment=0;
3233 pinfo->desegment_offset = 0;
3234 pinfo->desegment_len = 0;
3235 reported_len = tvb_reported_length(d_tvb);
3236 if(smb_dcerpc_reassembly && tvb_bytes_exist(d_tvb, 0, reported_len)){
3237 pinfo->can_desegment=2;
3240 save_fragmented = pinfo->fragmented;
3243 /* if we are not offering desegmentation, just try the heuristics
3246 if(!pinfo->can_desegment){
3247 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3248 goto clean_up_and_exit;
3252 /* below this line, we know we are doing reassembly */
3255 * We have to keep track of reassemblies by FID, because
3256 * we could have more than one pipe operation in a frame
3257 * with NetBIOS-over-TCP.
3259 * We also have to keep track of them by direction, as
3260 * we might have reassemblies in progress in both directions.
3262 * We do that by combining the FID and the direction and
3263 * using that as the reassembly ID.
3265 * The direction is indicated by the SMB request/reply flag - data
3266 * from client to server is carried in requests, data from server
3267 * to client is carried in replies.
3269 * We know that the FID is only 16 bits long, so we put the
3270 * direction in bit 17.
3273 if (smb_priv->request)
3274 hash_key |= 0x10000;
3276 /* this is a new packet, see if we are already reassembling this
3277 pdu and if not, check if the dissector wants us
3280 if(!pinfo->fd->flags.visited){
3282 * This is the first pass.
3284 * Check if we are already reassembling this PDU or not;
3285 * we check for an in-progress reassembly for this FID
3286 * in this direction, by searching for its reassembly
3289 fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
3291 /* No reassembly, so this is a new pdu. check if the
3292 dissector wants us to reassemble it or if we
3293 already got the full pdu in this tvb.
3297 * First, just check if it looks like dcerpc or not.
3299 * XXX - this assumes that the dissector is idempotent,
3300 * as it's doing a "trial" dissection building no
3301 * tree; that's not necessarily the case.
3303 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, NULL);
3305 /* no this didnt look like something we know */
3307 goto clean_up_and_exit;
3310 /* did the subdissector want us to reassemble any
3313 if(pinfo->desegment_len){
3314 fragment_add_check(d_tvb, 0, pinfo, fid,
3315 dcerpc_fragment_table,
3316 dcerpc_reassembled_table,
3317 0, reported_len, TRUE);
3318 fragment_set_tot_len(pinfo, fid,
3319 dcerpc_fragment_table,
3320 pinfo->desegment_len+reported_len);
3321 goto clean_up_and_exit;
3324 /* guess we have the full pdu in this tvb then,
3325 just dissect it and continue.
3327 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3328 goto clean_up_and_exit;
3331 /* OK, we're already doing a reassembly for this FID.
3332 skip to last segment in the existing reassembly structure
3333 and add this fragment there
3335 XXX we might add code here to use any offset values
3336 we might pick up from the Read/Write calls instead of
3337 assuming we always get them in the correct order
3339 while(fd_head->next){
3340 fd_head=fd_head->next;
3342 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
3343 dcerpc_fragment_table, dcerpc_reassembled_table,
3344 fd_head->offset+fd_head->len,
3345 reported_len, TRUE);
3347 /* if we completed reassembly */
3349 new_tvb = tvb_new_real_data(fd_head->data,
3350 fd_head->datalen, fd_head->datalen);
3351 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3352 add_new_data_source(pinfo, new_tvb,
3354 pinfo->fragmented=FALSE;
3358 /* list what segments we have */
3359 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3360 tree, pinfo, d_tvb);
3362 /* dissect the full PDU */
3363 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3365 goto clean_up_and_exit;
3369 * This is not the first pass; see if it's in the table of
3370 * reassembled packets.
3372 * XXX - we know that several of the arguments aren't going to
3373 * be used, so we pass bogus variables. Can we clean this
3374 * up so that we don't have to distinguish between the first
3375 * pass and subsequent passes?
3377 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
3378 dcerpc_reassembled_table, 0, 0, TRUE);
3380 /* we didnt find it, try any of the heuristic dissectors
3383 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3384 goto clean_up_and_exit;
3386 if(!fd_head->flags&FD_DEFRAGMENTED){
3387 /* we dont have a fully reassembled frame */
3388 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3389 goto clean_up_and_exit;
3392 /* it is reassembled but it was reassembled in a different frame */
3393 if(pinfo->fd->num!=fd_head->reassembled_in){
3394 proto_tree_add_uint(parent_tree, hf_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3395 goto clean_up_and_exit;
3399 /* display the reassembled pdu */
3400 new_tvb = tvb_new_real_data(fd_head->data,
3401 fd_head->datalen, fd_head->datalen);
3402 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3403 add_new_data_source(pinfo, new_tvb,
3405 pinfo->fragmented=FALSE;
3409 /* list what segments we have */
3410 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3411 tree, pinfo, d_tvb);
3413 /* dissect the full PDU */
3414 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3419 /* clear out the variables */
3420 pinfo->private_data = smb_priv;
3421 pinfo->can_desegment=0;
3422 pinfo->desegment_offset = 0;
3423 pinfo->desegment_len = 0;
3426 call_dissector(data_handle, d_tvb, pinfo, parent_tree);
3428 pinfo->fragmented = save_fragmented;
3433 proto_register_pipe_dcerpc(void)
3435 register_heur_dissector_list("smb_transact", &smb_transact_heur_subdissector_list);
3436 register_init_routine(smb_dcerpc_reassembly_init);
3439 #define CALL_NAMED_PIPE 0x54
3440 #define WAIT_NAMED_PIPE 0x53
3441 #define PEEK_NAMED_PIPE 0x23
3442 #define Q_NM_P_HAND_STATE 0x21
3443 #define SET_NM_P_HAND_STATE 0x01
3444 #define Q_NM_PIPE_INFO 0x22
3445 #define TRANSACT_NM_PIPE 0x26
3446 #define RAW_READ_NM_PIPE 0x11
3447 #define RAW_WRITE_NM_PIPE 0x31
3449 static const value_string functions[] = {
3450 {CALL_NAMED_PIPE, "CallNamedPipe"},
3451 {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3452 {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3453 {Q_NM_P_HAND_STATE, "QNmPHandState"},
3454 {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3455 {Q_NM_PIPE_INFO, "QNmPipeInfo"},
3456 {TRANSACT_NM_PIPE, "TransactNmPipe"},
3457 {RAW_READ_NM_PIPE, "RawReadNmPipe"},
3458 {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3462 static const value_string pipe_status[] = {
3463 {1, "Disconnected by server"},
3465 {3, "Connection to server is OK"},
3466 {4, "Server end of pipe is closed"},
3470 #define PIPE_LANMAN 1
3471 #define PIPE_DCERPC 2
3473 /* decode the SMB pipe protocol
3475 pipe is the name of the pipe, e.g. LANMAN
3476 smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3479 smb_info->trans_subcmd gives us which pipe this response is for
3482 dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3483 tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3484 packet_info *pinfo, proto_tree *tree)
3486 smb_info_t *smb_info;
3487 smb_transact_info_t *tri;
3489 proto_item *pipe_item = NULL;
3490 proto_tree *pipe_tree = NULL;
3497 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3499 pinfo->current_proto = "SMB Pipe";
3501 smb_info = pinfo->private_data;
3506 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
3507 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3509 if (check_col(pinfo->cinfo, COL_INFO)) {
3510 col_set_str(pinfo->cinfo, COL_INFO,
3511 smb_info->request ? "Request" : "Response");
3514 if (smb_info->sip != NULL)
3515 tri = smb_info->sip->extra_info;
3520 * Set up a subtree for the pipe protocol. (It might not contain
3524 sp_len = tvb_length(sp_tvb);
3528 pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3529 sp_tvb, 0, sp_len, FALSE);
3530 pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3535 * Do we have any setup words at all?
3537 if (s_tvb != NULL && tvb_length(s_tvb) != 0) {
3539 * Yes. The first of them is the function.
3541 function = tvb_get_letohs(s_tvb, offset);
3542 proto_tree_add_uint(pipe_tree, hf_pipe_function, s_tvb,
3543 offset, 2, function);
3545 if (check_col(pinfo->cinfo, COL_INFO)) {
3546 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3547 val_to_str(function, functions, "Unknown function (0x%04x)"),
3548 smb_info->request ? "Request" : "Response");
3551 tri->function = function;
3554 * The second of them depends on the function.
3558 case CALL_NAMED_PIPE:
3559 case WAIT_NAMED_PIPE:
3563 proto_tree_add_item(pipe_tree, hf_pipe_priority, s_tvb,
3567 case PEEK_NAMED_PIPE:
3568 case Q_NM_P_HAND_STATE:
3569 case SET_NM_P_HAND_STATE:
3570 case Q_NM_PIPE_INFO:
3571 case TRANSACT_NM_PIPE:
3572 case RAW_READ_NM_PIPE:
3573 case RAW_WRITE_NM_PIPE:
3577 fid = tvb_get_letohs(s_tvb, 2);
3578 add_fid(s_tvb, pinfo, pipe_tree, offset, 2, (guint16) fid);
3585 * It's something unknown.
3586 * XXX - put it into the tree?
3593 * This is either a response or a pipe transaction with
3594 * no setup information.
3596 * In the former case, we can get that information from
3597 * the matching request, if we saw it.
3599 * In the latter case, there is no function or FID.
3601 if (tri != NULL && tri->function != -1) {
3602 function = tri->function;
3603 proto_tree_add_uint(pipe_tree, hf_pipe_function, NULL,
3605 if (check_col(pinfo->cinfo, COL_INFO)) {
3606 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3607 val_to_str(function, functions, "Unknown function (0x%04x)"),
3608 smb_info->request ? "Request" : "Response");
3612 add_fid(NULL, pinfo, pipe_tree, 0, 0, (guint16) fid);
3620 * XXX - put the byte count and the pipe name into the tree as well;
3621 * that requires us to fetch a possibly-Unicode string.
3624 if(smb_info->request){
3625 if(strncmp(pipe,"LANMAN",6) == 0){
3626 trans_subcmd=PIPE_LANMAN;
3628 /* assume it is DCERPC */
3629 trans_subcmd=PIPE_DCERPC;
3632 if (!pinfo->fd->flags.visited)
3633 tri->trans_subcmd = trans_subcmd;
3635 trans_subcmd = tri->trans_subcmd;
3639 * We don't know what type of pipe transaction this
3640 * was, so indicate that we didn't dissect it.
3647 case CALL_NAMED_PIPE:
3648 case TRANSACT_NM_PIPE:
3649 switch(trans_subcmd){
3652 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3658 * Only dissect this if we know the FID.
3663 return dissect_pipe_dcerpc(d_tvb, pinfo, tree,
3672 * We don't know the function; we dissect only LANMAN
3673 * pipe messages, not RPC pipe messages, in that case.
3675 switch(trans_subcmd){
3677 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3683 case WAIT_NAMED_PIPE:
3686 case PEEK_NAMED_PIPE:
3688 * Request contains no parameters or data.
3690 if (!smb_info->request) {
3694 proto_tree_add_item(pipe_tree, hf_pipe_peek_available,
3695 p_tvb, offset, 2, TRUE);
3697 proto_tree_add_item(pipe_tree, hf_pipe_peek_remaining,
3698 p_tvb, offset, 2, TRUE);
3700 proto_tree_add_item(pipe_tree, hf_pipe_peek_status,
3701 p_tvb, offset, 2, TRUE);
3706 case Q_NM_P_HAND_STATE:
3708 * Request contains no parameters or data.
3710 if (!smb_info->request) {
3713 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, FALSE);
3717 case SET_NM_P_HAND_STATE:
3719 * Response contains no parameters or data.
3721 if (smb_info->request) {
3724 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, TRUE);
3728 case Q_NM_PIPE_INFO:
3730 if (smb_info->request) {
3735 * Request contains an information level.
3737 info_level = tvb_get_letohs(p_tvb, offset);
3738 proto_tree_add_uint(pipe_tree, hf_pipe_getinfo_info_level,
3739 p_tvb, offset, 2, info_level);
3741 if (!pinfo->fd->flags.visited)
3742 tri->info_level = info_level;
3744 guint8 pipe_namelen;
3749 switch (tri->info_level) {
3752 proto_tree_add_item(pipe_tree,
3753 hf_pipe_getinfo_output_buffer_size,
3754 d_tvb, offset, 2, TRUE);
3756 proto_tree_add_item(pipe_tree,
3757 hf_pipe_getinfo_input_buffer_size,
3758 d_tvb, offset, 2, TRUE);
3760 proto_tree_add_item(pipe_tree,
3761 hf_pipe_getinfo_maximum_instances,
3762 d_tvb, offset, 1, TRUE);
3764 proto_tree_add_item(pipe_tree,
3765 hf_pipe_getinfo_current_instances,
3766 d_tvb, offset, 1, TRUE);
3768 pipe_namelen = tvb_get_guint8(d_tvb, offset);
3769 proto_tree_add_uint(pipe_tree,
3770 hf_pipe_getinfo_pipe_name_length,
3771 d_tvb, offset, 1, pipe_namelen);
3773 /* XXX - can this be Unicode? */
3774 proto_tree_add_item(pipe_tree,
3775 hf_pipe_getinfo_pipe_name,
3776 d_tvb, offset, pipe_namelen, TRUE);
3782 case RAW_READ_NM_PIPE:
3784 * Request contains no parameters or data.
3786 if (!smb_info->request) {
3790 offset = dissect_file_data(d_tvb, pipe_tree, 0,
3791 (guint16) tvb_reported_length(d_tvb),
3792 (guint16) tvb_reported_length(d_tvb));
3796 case RAW_WRITE_NM_PIPE:
3798 if (smb_info->request) {
3802 offset = dissect_file_data(d_tvb, pipe_tree,
3803 offset, (guint16) tvb_reported_length(d_tvb),
3804 (guint16) tvb_reported_length(d_tvb));
3808 proto_tree_add_item(pipe_tree,
3809 hf_pipe_write_raw_bytes_written,
3810 p_tvb, offset, 2, TRUE);
3819 proto_register_smb_pipe(void)
3821 static hf_register_info hf[] = {
3822 { &hf_pipe_function,
3823 { "Function", "pipe.function", FT_UINT16, BASE_HEX,
3824 VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3825 { &hf_pipe_priority,
3826 { "Priority", "pipe.priority", FT_UINT16, BASE_DEC,
3827 NULL, 0, "SMB Pipe Priority", HFILL }},
3828 { &hf_pipe_peek_available,
3829 { "Available Bytes", "pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3830 NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3831 { &hf_pipe_peek_remaining,
3832 { "Bytes Remaining", "pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3833 NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3834 { &hf_pipe_peek_status,
3835 { "Pipe Status", "pipe.peek.status", FT_UINT16, BASE_DEC,
3836 VALS(pipe_status), 0, "Pipe status", HFILL }},
3837 { &hf_pipe_getinfo_info_level,
3838 { "Information Level", "pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3839 NULL, 0, "Information level of information to return", HFILL }},
3840 { &hf_pipe_getinfo_output_buffer_size,
3841 { "Output Buffer Size", "pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3842 NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3843 { &hf_pipe_getinfo_input_buffer_size,
3844 { "Input Buffer Size", "pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3845 NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3846 { &hf_pipe_getinfo_maximum_instances,
3847 { "Maximum Instances", "pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3848 NULL, 0, "Maximum allowed number of instances", HFILL }},
3849 { &hf_pipe_getinfo_current_instances,
3850 { "Current Instances", "pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3851 NULL, 0, "Current number of instances", HFILL }},
3852 { &hf_pipe_getinfo_pipe_name_length,
3853 { "Pipe Name Length", "pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3854 NULL, 0, "Length of pipe name", HFILL }},
3855 { &hf_pipe_getinfo_pipe_name,
3856 { "Pipe Name", "pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3857 NULL, 0, "Name of pipe", HFILL }},
3858 { &hf_pipe_write_raw_bytes_written,
3859 { "Bytes Written", "pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3860 NULL, 0, "Number of bytes written to the pipe", HFILL }},
3861 { &hf_pipe_fragment_overlap,
3862 { "Fragment overlap", "pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3863 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3864 { &hf_pipe_fragment_overlap_conflict,
3865 { "Conflicting data in fragment overlap", "pipe.fragment.overlap.conflict", FT_BOOLEAN,
3866 BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3867 { &hf_pipe_fragment_multiple_tails,
3868 { "Multiple tail fragments found", "pipe.fragment.multipletails", FT_BOOLEAN,
3869 BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3870 { &hf_pipe_fragment_too_long_fragment,
3871 { "Fragment too long", "pipe.fragment.toolongfragment", FT_BOOLEAN,
3872 BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3873 { &hf_pipe_fragment_error,
3874 { "Defragmentation error", "pipe.fragment.error", FT_FRAMENUM,
3875 BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3876 { &hf_pipe_fragment,
3877 { "Fragment", "pipe.fragment", FT_FRAMENUM,
3878 BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3879 { &hf_pipe_fragments,
3880 { "Fragments", "pipe.fragments", FT_NONE,
3881 BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3882 { &hf_pipe_reassembled_in,
3883 { "This PDU is reassembled in", "pipe.reassembled_in", FT_FRAMENUM,
3884 BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3886 static gint *ett[] = {
3888 &ett_smb_pipe_fragment,
3889 &ett_smb_pipe_fragments,
3892 proto_smb_pipe = proto_register_protocol(
3893 "SMB Pipe Protocol", "SMB Pipe", "pipe");
3895 proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3896 proto_register_subtree_array(ett, array_length(ett));
3900 proto_reg_handoff_smb_pipe(void)
3902 data_handle = find_dissector("data");