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
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-windows-common.h"
50 #include "packet-dcerpc.h"
51 #include <epan/reassemble.h>
53 static int proto_smb_pipe = -1;
54 static int hf_pipe_function = -1;
55 static int hf_pipe_priority = -1;
56 static int hf_pipe_peek_available = -1;
57 static int hf_pipe_peek_remaining = -1;
58 static int hf_pipe_peek_status = -1;
59 static int hf_pipe_getinfo_info_level = -1;
60 static int hf_pipe_getinfo_output_buffer_size = -1;
61 static int hf_pipe_getinfo_input_buffer_size = -1;
62 static int hf_pipe_getinfo_maximum_instances = -1;
63 static int hf_pipe_getinfo_current_instances = -1;
64 static int hf_pipe_getinfo_pipe_name_length = -1;
65 static int hf_pipe_getinfo_pipe_name = -1;
66 static int hf_pipe_write_raw_bytes_written = -1;
67 static int hf_pipe_fragments = -1;
68 static int hf_pipe_fragment = -1;
69 static int hf_pipe_fragment_overlap = -1;
70 static int hf_pipe_fragment_overlap_conflict = -1;
71 static int hf_pipe_fragment_multiple_tails = -1;
72 static int hf_pipe_fragment_too_long_fragment = -1;
73 static int hf_pipe_fragment_error = -1;
74 static int hf_pipe_reassembled_in = -1;
76 static gint ett_smb_pipe = -1;
77 static gint ett_smb_pipe_fragment = -1;
78 static gint ett_smb_pipe_fragments = -1;
80 static const fragment_items smb_pipe_frag_items = {
81 &ett_smb_pipe_fragment,
82 &ett_smb_pipe_fragments,
85 &hf_pipe_fragment_overlap,
86 &hf_pipe_fragment_overlap_conflict,
87 &hf_pipe_fragment_multiple_tails,
88 &hf_pipe_fragment_too_long_fragment,
89 &hf_pipe_fragment_error,
94 static int proto_smb_lanman = -1;
95 static int hf_function_code = -1;
96 static int hf_param_desc = -1;
97 static int hf_return_desc = -1;
98 static int hf_aux_data_desc = -1;
99 static int hf_detail_level = -1;
100 static int hf_recv_buf_len = -1;
101 static int hf_send_buf_len = -1;
102 static int hf_continuation_from = -1;
103 static int hf_status = -1;
104 static int hf_convert = -1;
105 static int hf_ecount = -1;
106 static int hf_acount = -1;
107 static int hf_share_name = -1;
108 static int hf_share_type = -1;
109 static int hf_share_comment = -1;
110 static int hf_share_permissions = -1;
111 static int hf_share_max_uses = -1;
112 static int hf_share_current_uses = -1;
113 static int hf_share_path = -1;
114 static int hf_share_password = -1;
115 static int hf_server_name = -1;
116 static int hf_server_major = -1;
117 static int hf_server_minor = -1;
118 static int hf_server_comment = -1;
119 static int hf_abytes = -1;
120 static int hf_current_time = -1;
121 static int hf_msecs = -1;
122 static int hf_hour = -1;
123 static int hf_minute = -1;
124 static int hf_second = -1;
125 static int hf_hundredths = -1;
126 static int hf_tzoffset = -1;
127 static int hf_timeinterval = -1;
128 static int hf_day = -1;
129 static int hf_month = -1;
130 static int hf_year = -1;
131 static int hf_weekday = -1;
132 static int hf_enumeration_domain = -1;
133 static int hf_last_entry = -1;
134 static int hf_computer_name = -1;
135 static int hf_user_name = -1;
136 static int hf_group_name = -1;
137 static int hf_workstation_domain = -1;
138 static int hf_workstation_major = -1;
139 static int hf_workstation_minor = -1;
140 static int hf_logon_domain = -1;
141 static int hf_other_domains = -1;
142 static int hf_password = -1;
143 static int hf_workstation_name = -1;
144 static int hf_ustruct_size = -1;
145 static int hf_logon_code = -1;
146 static int hf_privilege_level = -1;
147 static int hf_operator_privileges = -1;
148 static int hf_num_logons = -1;
149 static int hf_bad_pw_count = -1;
150 static int hf_last_logon = -1;
151 static int hf_last_logoff = -1;
152 static int hf_logoff_time = -1;
153 static int hf_kickoff_time = -1;
154 static int hf_password_age = -1;
155 static int hf_password_can_change = -1;
156 static int hf_password_must_change = -1;
157 static int hf_script_path = -1;
158 static int hf_logoff_code = -1;
159 static int hf_duration = -1;
160 static int hf_comment = -1;
161 static int hf_user_comment = -1;
162 static int hf_full_name = -1;
163 static int hf_homedir = -1;
164 static int hf_parameters = -1;
165 static int hf_logon_server = -1;
166 static int hf_country_code = -1;
167 static int hf_workstations = -1;
168 static int hf_max_storage = -1;
169 static int hf_units_per_week = -1;
170 static int hf_logon_hours = -1;
171 static int hf_code_page = -1;
172 static int hf_new_password = -1;
173 static int hf_old_password = -1;
174 static int hf_reserved = -1;
176 static gint ett_lanman = -1;
177 static gint ett_lanman_unknown_entries = -1;
178 static gint ett_lanman_unknown_entry = -1;
179 static gint ett_lanman_shares = -1;
180 static gint ett_lanman_share = -1;
181 static gint ett_lanman_groups = -1;
182 static gint ett_lanman_servers = -1;
183 static gint ett_lanman_server = -1;
185 static dissector_handle_t data_handle;
190 * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
192 * among other documents.
195 static const value_string status_vals[] = {
197 {5, "User has insufficient privilege"},
198 {65, "Network access is denied"},
199 {86, "The specified password is invalid"},
200 {SMBE_moredata, "Additional data is available"},
201 {2114, "Service is not running on the remote computer"},
202 {2123, "Supplied buffer is too small"},
203 {2141, "Server is not configured for transactions (IPC$ not shared)"},
204 {2212, "An error occurred while loading or running the logon script"},
205 {2214, "The logon was not validated by any server"},
206 {2217, "The logon server is running an older software version"},
207 {2221, "The user name was not found"},
208 {2226, "Operation not permitted on Backup Domain Controller"},
209 {2240, "The user is not allowed to logon from this computer"},
210 {2241, "The user is not allowed to logon at this time"},
211 {2242, "The user password has expired"},
212 {2243, "The password cannot be changed"},
213 {2246, "The password is too short"},
217 static const value_string privilege_vals[] = {
220 {2, "Administrator"},
224 static const value_string op_privilege_vals[] = {
225 {0, "Print operator"},
226 {1, "Communications operator"},
227 {2, "Server operator"},
228 {3, "Accounts operator"},
232 static const value_string weekday_vals[] = {
244 add_word_param(tvbuff_t *tvb, int offset, int count _U_,
245 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
250 proto_tree_add_item(tree, hf_index, tvb, offset, 2, TRUE);
252 WParam = tvb_get_letohs(tvb, offset);
253 proto_tree_add_text(tree, tvb, offset, 2,
254 "Word Param: %u (0x%04X)", WParam, WParam);
261 add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
262 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
267 proto_tree_add_item(tree, hf_index, tvb, offset, 4, TRUE);
269 LParam = tvb_get_letohl(tvb, offset);
270 proto_tree_add_text(tree, tvb, offset, 4,
271 "Doubleword Param: %u (0x%08X)", LParam, LParam);
278 add_byte_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
279 proto_tree *tree, int convert _U_, int hf_index)
282 header_field_info *hfinfo;
284 if (hf_index != -1) {
285 hfinfo = proto_registrar_get_nth(hf_index);
286 if (hfinfo && count != 1 &&
287 (hfinfo->type == FT_INT8 || hfinfo->type == FT_UINT8)
289 THROW(ReportedBoundsError);
291 proto_tree_add_item(tree, hf_index, tvb, offset, count, TRUE);
294 BParam = tvb_get_guint8(tvb, offset);
295 proto_tree_add_text(tree, tvb, offset, count,
296 "Byte Param: %u (0x%02X)",
299 proto_tree_add_text(tree, tvb, offset, count,
301 tvb_bytes_to_str(tvb, offset, count));
309 add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
310 proto_tree *tree _U_, int convert _U_, int hf_index _U_)
313 * This is for parameters that have descriptor entries but that
314 * are, in practice, just padding.
321 add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
322 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
324 if (hf_index != -1) {
325 proto_tree_add_text(tree, tvb, offset, 0,
327 proto_registrar_get_name(hf_index));
329 proto_tree_add_text(tree, tvb, offset, 0,
330 "String Param (Null pointer)");
335 add_string_param(tvbuff_t *tvb, int offset, int count _U_,
336 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
340 string_len = tvb_strsize(tvb, offset);
341 if (hf_index != -1) {
342 proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
345 proto_tree_add_text(tree, tvb, offset, string_len,
347 tvb_format_text(tvb, offset, string_len));
349 offset += string_len;
354 get_stringz_pointer_value(tvbuff_t *tvb, int offset, int convert, int *cptrp,
360 /* pointer to string */
361 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
365 if (tvb_offset_exists(tvb, cptr) &&
366 (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
367 string_len++; /* include the terminating '\0' */
369 return tvb_format_text(tvb, cptr, string_len - 1);
375 add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
376 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
382 string = get_stringz_pointer_value(tvb, offset, convert, &cptr,
387 if (string != NULL) {
388 if (hf_index != -1) {
389 proto_tree_add_item(tree, hf_index, tvb, cptr,
392 proto_tree_add_text(tree, tvb, cptr, string_len,
393 "String Param: %s", string);
396 if (hf_index != -1) {
397 proto_tree_add_text(tree, tvb, 0, 0,
398 "%s: <String goes past end of frame>",
399 proto_registrar_get_name(hf_index));
401 proto_tree_add_text(tree, tvb, 0, 0,
402 "String Param: <String goes past end of frame>");
410 add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
411 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
415 /* pointer to byte array */
416 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
420 if (tvb_bytes_exist(tvb, cptr, count)) {
421 if (hf_index != -1) {
422 proto_tree_add_item(tree, hf_index, tvb, cptr,
425 proto_tree_add_text(tree, tvb, cptr, count,
427 tvb_bytes_to_str(tvb, cptr, count));
430 if (hf_index != -1) {
431 proto_tree_add_text(tree, tvb, 0, 0,
432 "%s: <Bytes go past end of frame>",
433 proto_registrar_get_name(hf_index));
435 proto_tree_add_text(tree, tvb, 0, 0,
436 "Byte Param: <Bytes goes past end of frame>");
444 add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
445 proto_tree *tree, int convert _U_, int hf_index)
447 struct smb_info *smb_info = pinfo->private_data;
448 smb_transact_info_t *trp = NULL;
451 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
452 trp = smb_info->sip->extra_info;
454 level = tvb_get_letohs(tvb, offset);
455 if (!pinfo->fd->flags.visited)
456 trp->info_level = level; /* remember this for the response */
457 proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
463 add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
464 proto_tree *tree, int convert _U_, int hf_index)
468 WParam = tvb_get_letohs(tvb, offset);
469 if (WParam == 0xffff) { /* -1 */
470 proto_tree_add_uint_format(tree, hf_index, tvb,
473 proto_registrar_get_name(hf_index));
475 proto_tree_add_uint(tree, hf_index, tvb,
483 add_server_type(tvbuff_t *tvb, int offset, int count _U_,
484 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
486 offset = dissect_smb_server_type_flags(
487 tvb, offset, pinfo, tree, NULL, FALSE);
492 add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
493 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
495 offset = dissect_smb_server_type_flags(
496 tvb, offset, pinfo, tree, NULL, TRUE);
501 add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
502 proto_tree *tree, int convert _U_, int hf_index)
506 nstime.secs = tvb_get_letohl(tvb, offset);
508 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
509 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
510 time_secs_to_str(nstime.secs));
516 * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but-
517 * it's-local-time-not-UTC time.
520 add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
521 const char *absent_name)
526 nstime.secs = tvb_get_letohl(tvb, offset);
529 * Sigh. Sometimes it appears that -1 means "unknown", and
530 * sometimes it appears that 0 means "unknown", for the last
533 if (nstime.secs == -1 || nstime.secs == 0) {
534 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
535 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
539 * Run it through "gmtime()" to break it down, and then
540 * run it through "mktime()" to put it back together
543 tmp = gmtime(&nstime.secs);
544 tmp->tm_isdst = -1; /* we don't know if it's DST or not */
545 nstime.secs = mktime(tmp);
546 proto_tree_add_time(tree, hf_index, tvb, offset, 4,
554 add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
555 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
557 return add_abstime_common(tvb, offset, tree, hf_index, "Never");
561 add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
562 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
564 return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
568 add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
569 proto_tree *tree, int convert _U_, int hf_index)
573 nlogons = tvb_get_letohs(tvb, offset);
574 if (nlogons == 0xffff) /* -1 */
575 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 2,
576 nlogons, "%s: Unknown",
577 proto_registrar_get_name(hf_index));
579 proto_tree_add_uint(tree, hf_index, tvb, offset, 2,
586 add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
587 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
591 max_storage = tvb_get_letohl(tvb, offset);
592 if (max_storage == 0xffffffff)
593 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
594 max_storage, "%s: No limit",
595 proto_registrar_get_name(hf_index));
597 proto_tree_add_uint(tree, hf_index, tvb, offset, 4,
604 add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
605 proto_tree *tree, int convert, int hf_index)
609 /* pointer to byte array */
610 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
614 if (tvb_bytes_exist(tvb, cptr, count)) {
617 * The logon hours should be exactly 21 bytes long.
619 * XXX - should actually carve up the bits;
620 * we need the units per week to do that, though.
622 proto_tree_add_item(tree, hf_index, tvb, cptr, count,
625 proto_tree_add_bytes_format(tree, hf_index, tvb,
626 cptr, count, tvb_get_ptr(tvb, cptr, count),
627 "%s: %s (wrong length, should be 21, is %d",
628 proto_registrar_get_name(hf_index),
629 tvb_bytes_to_str(tvb, cptr, count), count);
632 proto_tree_add_text(tree, tvb, 0, 0,
633 "%s: <Bytes go past end of frame>",
634 proto_registrar_get_name(hf_index));
641 add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
642 proto_tree *tree, int convert _U_, int hf_index)
646 tzoffset = tvb_get_letohs(tvb, offset);
648 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
649 tzoffset, "%s: %s east of UTC",
650 proto_registrar_get_name(hf_index),
651 time_secs_to_str(-tzoffset*60));
652 } else if (tzoffset > 0) {
653 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
654 tzoffset, "%s: %s west of UTC",
655 proto_registrar_get_name(hf_index),
656 time_secs_to_str(tzoffset*60));
658 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
659 tzoffset, "%s: at UTC",
660 proto_registrar_get_name(hf_index));
667 add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
668 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
670 guint16 timeinterval;
672 timeinterval = tvb_get_letohs(tvb, offset);
673 proto_tree_add_uint_format(tree, hf_timeinterval, tvb, offset, 2,
674 timeinterval, "%s: %f seconds", proto_registrar_get_name(hf_index),
681 add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
682 proto_tree *tree, int convert _U_, int hf_index _U_)
685 proto_tree_add_text(tree, tvb, offset, count,
686 "Bogus NetWkstaUserLogon parameters: length is %d, should be 54",
693 proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, TRUE);
700 proto_tree_add_item(tree, hf_password, tvb, offset, 15, TRUE);
706 /* workstation name */
707 proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, TRUE);
713 * The following data structure describes the Remote API requests we
716 * Simply fill in the number and parameter information.
717 * Try to keep them in order.
719 * We will extend this data structure as we try to decode more.
723 * This is a pointer to a function to process an item.
725 typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
729 * Type of an item; determines what parameter strings are valid for
733 PARAM_NONE, /* for the end-of-list stopper */
734 PARAM_WORD, /* 'W' or 'h' - 16-bit word */
735 PARAM_DWORD, /* 'D' or 'i' - 32-bit word */
736 PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
737 PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
741 * This structure describes an item; "hf_index" points to the index
742 * for the field corresponding to that item, "func" points to the
743 * function to use to add that item to the tree, and "type" is the
744 * type that the item is supposed to have.
753 * This structure describes a list of items; each list of items
754 * has a corresponding detail level.
758 const item_t *item_list;
764 proto_item *(*req_data_item)(tvbuff_t *, packet_info *,
767 const item_t *req_data;
768 const item_t *req_aux_data;
770 const gchar *resp_data_entry_list_label;
771 gint *ett_data_entry_list;
772 proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
774 gint *ett_resp_data_element_item;
775 const item_list_t *resp_data_list;
776 const item_t *resp_aux_data;
779 static int no_hf = -1; /* for padding crap */
781 static const item_t lm_params_req_netshareenum[] = {
782 { &hf_detail_level, add_detail_level, PARAM_WORD },
783 { &hf_recv_buf_len, add_word_param, PARAM_WORD },
784 { NULL, NULL, PARAM_NONE }
787 static const item_t lm_params_resp_netshareenum[] = {
788 { &hf_acount, add_word_param, PARAM_WORD },
789 { NULL, NULL, PARAM_NONE }
793 * Create a subtree for a share.
796 netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
799 return proto_tree_add_text(tree, tvb, offset, -1,
800 "Share %.13s", tvb_get_ptr(tvb, offset, 13));
805 static const item_t lm_null[] = {
806 { NULL, NULL, PARAM_NONE }
809 static const item_list_t lm_null_list[] = {
813 static const item_t lm_data_resp_netshareenum_1[] = {
814 { &hf_share_name, add_byte_param, PARAM_BYTES },
815 { &no_hf, add_pad_param, PARAM_BYTES },
816 { &hf_share_type, add_word_param, PARAM_WORD },
817 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
818 { NULL, NULL, PARAM_NONE }
821 static const item_list_t lm_data_resp_netshareenum[] = {
822 { 1, lm_data_resp_netshareenum_1 },
826 static const item_t lm_params_req_netsharegetinfo[] = {
827 { &hf_share_name, add_string_param, PARAM_STRINGZ },
828 { &hf_detail_level, add_detail_level, PARAM_WORD },
829 { NULL, NULL, PARAM_NONE }
832 static const item_t lm_params_resp_netsharegetinfo[] = {
833 { &hf_abytes, add_word_param, PARAM_WORD },
834 { NULL, NULL, PARAM_NONE }
837 static const item_t lm_data_resp_netsharegetinfo_0[] = {
838 { &hf_share_name, add_byte_param, PARAM_BYTES },
839 { NULL, NULL, PARAM_NONE }
842 static const item_t lm_data_resp_netsharegetinfo_1[] = {
843 { &hf_share_name, add_byte_param, PARAM_BYTES },
844 { &no_hf, add_pad_param, PARAM_BYTES },
845 { &hf_share_type, add_word_param, PARAM_WORD },
846 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
847 { NULL, NULL, PARAM_NONE }
850 static const item_t lm_data_resp_netsharegetinfo_2[] = {
851 { &hf_share_name, add_byte_param, PARAM_BYTES },
852 { &no_hf, add_pad_param, PARAM_BYTES },
853 { &hf_share_type, add_word_param, PARAM_WORD },
854 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
855 { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
856 { &hf_share_max_uses, add_max_uses, PARAM_WORD },
857 { &hf_share_current_uses, add_word_param, PARAM_WORD },
858 { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
859 { &hf_share_password, add_byte_param, PARAM_BYTES },
860 { NULL, NULL, PARAM_NONE }
863 static const item_list_t lm_data_resp_netsharegetinfo[] = {
864 { 0, lm_data_resp_netsharegetinfo_0 },
865 { 1, lm_data_resp_netsharegetinfo_1 },
866 { 2, lm_data_resp_netsharegetinfo_2 },
870 static const item_t lm_params_req_netservergetinfo[] = {
871 { &hf_detail_level, add_detail_level, PARAM_WORD },
872 { NULL, NULL, PARAM_NONE }
875 static const item_t lm_params_resp_netservergetinfo[] = {
876 { &hf_abytes, add_word_param, PARAM_WORD },
877 { NULL, NULL, PARAM_NONE }
880 static const item_t lm_data_serverinfo_0[] = {
881 { &hf_server_name, add_byte_param, PARAM_BYTES },
882 { NULL, NULL, PARAM_NONE }
885 static const item_t lm_data_serverinfo_1[] = {
886 { &hf_server_name, add_byte_param, PARAM_BYTES },
887 { &hf_server_major, add_byte_param, PARAM_BYTES },
888 { &hf_server_minor, add_byte_param, PARAM_BYTES },
889 { &no_hf, add_server_type, PARAM_DWORD },
890 { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
891 { NULL, NULL, PARAM_NONE }
894 static const item_list_t lm_data_serverinfo[] = {
895 { 0, lm_data_serverinfo_0 },
896 { 1, lm_data_serverinfo_1 },
900 static const item_t lm_params_req_netusergetinfo[] = {
901 { &hf_user_name, add_string_param, PARAM_STRINGZ },
902 { &hf_detail_level, add_detail_level, PARAM_WORD },
903 { NULL, NULL, PARAM_NONE }
906 static const item_t lm_params_resp_netusergetinfo[] = {
907 { &hf_abytes, add_word_param, PARAM_WORD },
908 { NULL, NULL, PARAM_NONE }
911 static const item_t lm_data_resp_netusergetinfo_11[] = {
912 { &hf_user_name, add_byte_param, PARAM_BYTES },
913 { &no_hf, add_pad_param, PARAM_BYTES },
914 { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
915 { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
916 { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
917 { &hf_privilege_level, add_word_param, PARAM_WORD },
918 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
919 { &hf_password_age, add_reltime, PARAM_DWORD },
920 { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
921 { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
922 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
923 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
924 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
925 { &hf_num_logons, add_nlogons, PARAM_WORD },
926 { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
927 { &hf_country_code, add_word_param, PARAM_WORD },
928 { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
929 { &hf_max_storage, add_max_storage, PARAM_DWORD },
930 { &hf_units_per_week, add_word_param, PARAM_WORD },
931 { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
932 { &hf_code_page, add_word_param, PARAM_WORD },
933 { NULL, NULL, PARAM_NONE }
936 static const item_list_t lm_data_resp_netusergetinfo[] = {
937 { 11, lm_data_resp_netusergetinfo_11 },
941 static const item_t lm_params_req_netusergetgroups[] = {
942 { &hf_user_name, add_string_param, PARAM_STRINGZ },
943 { &hf_detail_level, add_detail_level, PARAM_WORD },
944 { NULL, NULL, PARAM_NONE }
947 static const item_t lm_params_resp_netusergetgroups[] = {
948 { &hf_abytes, add_word_param, PARAM_WORD },
949 { NULL, NULL, PARAM_NONE }
952 static const item_t lm_data_resp_netusergetgroups_0[] = {
953 { &hf_group_name, add_byte_param, PARAM_BYTES },
954 { NULL, NULL, PARAM_NONE }
957 static const item_list_t lm_data_resp_netusergetgroups[] = {
958 { 0, lm_data_resp_netusergetgroups_0 },
963 * Has no detail level; make it the default.
965 static const item_t lm_data_resp_netremotetod_nolevel[] = {
966 { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
967 { &hf_msecs, add_dword_param, PARAM_DWORD },
968 { &hf_hour, add_byte_param, PARAM_BYTES },
969 { &hf_minute, add_byte_param, PARAM_BYTES },
970 { &hf_second, add_byte_param, PARAM_BYTES },
971 { &hf_hundredths, add_byte_param, PARAM_BYTES },
972 { &hf_tzoffset, add_tzoffset, PARAM_WORD },
973 { &hf_timeinterval, add_timeinterval, PARAM_WORD },
974 { &hf_day, add_byte_param, PARAM_BYTES },
975 { &hf_month, add_byte_param, PARAM_BYTES },
976 { &hf_year, add_word_param, PARAM_WORD },
977 { &hf_weekday, add_byte_param, PARAM_BYTES },
978 { NULL, NULL, PARAM_NONE }
981 static const item_list_t lm_data_resp_netremotetod[] = {
982 { -1, lm_data_resp_netremotetod_nolevel },
985 static const item_t lm_params_req_netserverenum2[] = {
986 { &hf_detail_level, add_detail_level, PARAM_WORD },
987 { &no_hf, add_server_type_info, PARAM_DWORD },
988 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
989 { NULL, NULL, PARAM_NONE }
993 * Create a subtree for a server.
996 netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
999 return proto_tree_add_text(tree, tvb, offset, -1,
1000 "Server %.16s", tvb_get_ptr(tvb, offset, 16));
1005 static const item_t lm_params_resp_netserverenum2[] = {
1006 { &hf_acount, add_word_param, PARAM_WORD },
1007 { NULL, NULL, PARAM_NONE }
1011 static const item_t lm_params_req_netserverenum3[] = {
1012 { &hf_detail_level, add_detail_level, PARAM_WORD },
1013 { &no_hf, add_server_type_info, PARAM_DWORD },
1014 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
1015 { &hf_last_entry, add_string_param, PARAM_STRINGZ },
1016 { NULL, NULL, PARAM_NONE }
1020 static const item_t lm_params_req_netwkstagetinfo[] = {
1021 { &hf_detail_level, add_detail_level, PARAM_WORD },
1022 { NULL, NULL, PARAM_NONE }
1025 static const item_t lm_params_resp_netwkstagetinfo[] = {
1026 { &hf_abytes, add_word_param, PARAM_WORD },
1027 { NULL, NULL, PARAM_NONE }
1030 static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1031 { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1032 { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1033 { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1034 { &hf_workstation_major, add_byte_param, PARAM_BYTES },
1035 { &hf_workstation_minor, add_byte_param, PARAM_BYTES },
1036 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1037 { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1038 { NULL, NULL, PARAM_NONE }
1041 static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1042 { 10, lm_data_resp_netwkstagetinfo_10 },
1046 static const item_t lm_params_req_netwkstauserlogon[] = {
1047 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1048 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1049 { &hf_detail_level, add_detail_level, PARAM_WORD },
1050 { &no_hf, add_logon_args, PARAM_BYTES },
1051 { &hf_ustruct_size, add_word_param, PARAM_WORD },
1052 { NULL, NULL, PARAM_NONE }
1055 static const item_t lm_params_resp_netwkstauserlogon[] = {
1056 { &hf_abytes, add_word_param, PARAM_WORD },
1057 { NULL, NULL, PARAM_NONE }
1060 static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1061 { &hf_logon_code, add_word_param, PARAM_WORD },
1062 { &hf_user_name, add_byte_param, PARAM_BYTES },
1063 { &no_hf, add_pad_param, PARAM_BYTES },
1064 { &hf_privilege_level, add_word_param, PARAM_WORD },
1065 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1066 { &hf_num_logons, add_nlogons, PARAM_WORD },
1067 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1068 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1069 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1070 { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1071 { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1072 { &hf_password_age, add_reltime, PARAM_DWORD },
1073 { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1074 { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1075 { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1076 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1077 { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1078 { &hf_reserved, add_dword_param, PARAM_DWORD },
1079 { NULL, NULL, PARAM_NONE }
1082 static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1083 { 1, lm_data_resp_netwkstauserlogon_1 },
1087 static const item_t lm_params_req_netwkstauserlogoff[] = {
1088 { &hf_user_name, add_byte_param, PARAM_BYTES },
1089 { &no_hf, add_pad_param, PARAM_BYTES },
1090 { &hf_workstation_name, add_byte_param, PARAM_BYTES },
1091 { NULL, NULL, PARAM_NONE }
1094 static const item_t lm_params_resp_netwkstauserlogoff[] = {
1095 { &hf_abytes, add_word_param, PARAM_WORD },
1096 { NULL, NULL, PARAM_NONE }
1099 static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1100 { &hf_logoff_code, add_word_param, PARAM_WORD },
1101 { &hf_duration, add_reltime, PARAM_DWORD },
1102 { &hf_num_logons, add_nlogons, PARAM_WORD },
1103 { NULL, NULL, PARAM_NONE }
1106 static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1107 { 1, lm_data_resp_netwkstauserlogoff_1 },
1111 static const item_t lm_params_req_samoemchangepassword[] = {
1112 { &hf_user_name, add_string_param, PARAM_STRINGZ },
1113 { NULL, NULL, PARAM_NONE }
1116 static const item_t lm_data_req_samoemchangepassword[] = {
1117 { &hf_new_password, add_byte_param, PARAM_BYTES },
1118 { &hf_old_password, add_byte_param, PARAM_BYTES },
1119 { NULL, NULL, PARAM_NONE }
1122 #define API_NetShareEnum 0
1123 #define API_NetShareGetInfo 1
1124 #define API_NetShareSetInfo 2
1125 #define API_NetShareAdd 3
1126 #define API_NetShareDel 4
1127 #define API_NetShareCheck 5
1128 #define API_NetSessionEnum 6
1129 #define API_NetSessionGetInfo 7
1130 #define API_NetSessionDel 8
1131 #define API_WconnectionEnum 9
1132 #define API_NetFileEnum 10
1133 #define API_NetFileGetInfo 11
1134 #define API_NetFileClose 12
1135 #define API_NetServerGetInfo 13
1136 #define API_NetServerSetInfo 14
1137 #define API_NetServerDiskEnum 15
1138 #define API_NetServerAdminCommand 16
1139 #define API_NetAuditOpen 17
1140 #define API_NetAuditClear 18
1141 #define API_NetErrorLogOpen 19
1142 #define API_NetErrorLogClear 20
1143 #define API_NetCharDevEnum 21
1144 #define API_NetCharDevGetInfo 22
1145 #define API_NetCharDevControl 23
1146 #define API_NetCharDevQEnum 24
1147 #define API_NetCharDevQGetInfo 25
1148 #define API_NetCharDevQSetInfo 26
1149 #define API_NetCharDevQPurge 27
1150 #define API_NetCharDevQPurgeSelf 28
1151 #define API_NetMessageNameEnum 29
1152 #define API_NetMessageNameGetInfo 30
1153 #define API_NetMessageNameAdd 31
1154 #define API_NetMessageNameDel 32
1155 #define API_NetMessageNameFwd 33
1156 #define API_NetMessageNameUnFwd 34
1157 #define API_NetMessageBufferSend 35
1158 #define API_NetMessageFileSend 36
1159 #define API_NetMessageLogFileSet 37
1160 #define API_NetMessageLogFileGet 38
1161 #define API_NetServiceEnum 39
1162 #define API_NetServiceInstall 40
1163 #define API_NetServiceControl 41
1164 #define API_NetAccessEnum 42
1165 #define API_NetAccessGetInfo 43
1166 #define API_NetAccessSetInfo 44
1167 #define API_NetAccessAdd 45
1168 #define API_NetAccessDel 46
1169 #define API_NetGroupEnum 47
1170 #define API_NetGroupAdd 48
1171 #define API_NetGroupDel 49
1172 #define API_NetGroupAddUser 50
1173 #define API_NetGroupDelUser 51
1174 #define API_NetGroupGetUsers 52
1175 #define API_NetUserEnum 53
1176 #define API_NetUserAdd 54
1177 #define API_NetUserDel 55
1178 #define API_NetUserGetInfo 56
1179 #define API_NetUserSetInfo 57
1180 #define API_NetUserPasswordSet 58
1181 #define API_NetUserGetGroups 59
1182 /*This line and number replaced a Dead Entry for 60 */
1183 /*This line and number replaced a Dead Entry for 61 */
1184 #define API_NetWkstaSetUID 62
1185 #define API_NetWkstaGetInfo 63
1186 #define API_NetWkstaSetInfo 64
1187 #define API_NetUseEnum 65
1188 #define API_NetUseAdd 66
1189 #define API_NetUseDel 67
1190 #define API_NetUseGetInfo 68
1191 #define API_WPrintQEnum 69
1192 #define API_WPrintQGetInfo 70
1193 #define API_WPrintQSetInfo 71
1194 #define API_WPrintQAdd 72
1195 #define API_WPrintQDel 73
1196 #define API_WPrintQPause 74
1197 #define API_WPrintQContinue 75
1198 #define API_WPrintJobEnum 76
1199 #define API_WPrintJobGetInfo 77
1200 #define API_WPrintJobSetInfo_OLD 78
1201 /* This line and number replaced a Dead Entry for 79 */
1202 /* This line and number replaced a Dead Entry for 80 */
1203 #define API_WPrintJobDel 81
1204 #define API_WPrintJobPause 82
1205 #define API_WPrintJobContinue 83
1206 #define API_WPrintDestEnum 84
1207 #define API_WPrintDestGetInfo 85
1208 #define API_WPrintDestControl 86
1209 #define API_NetProfileSave 87
1210 #define API_NetProfileLoad 88
1211 #define API_NetStatisticsGet 89
1212 #define API_NetStatisticsClear 90
1213 #define API_NetRemoteTOD 91
1214 #define API_WNetBiosEnum 92
1215 #define API_WNetBiosGetInfo 93
1216 #define API_NetServerEnum 94
1217 #define API_I_NetServerEnum 95
1218 #define API_NetServiceGetInfo 96
1219 /* This line and number replaced a Dead Entry for 97 */
1220 /* This line and number replaced a Dead Entry for 98 */
1221 /* This line and number replaced a Dead Entry for 99 */
1222 /* This line and number replaced a Dead Entry for 100 */
1223 /* This line and number replaced a Dead Entry for 101 */
1224 /* This line and number replaced a Dead Entry for 102 */
1225 #define API_WPrintQPurge 103
1226 #define API_NetServerEnum2 104
1227 #define API_NetAccessGetUserPerms 105
1228 #define API_NetGroupGetInfo 106
1229 #define API_NetGroupSetInfo 107
1230 #define API_NetGroupSetUsers 108
1231 #define API_NetUserSetGroups 109
1232 #define API_NetUserModalsGet 110
1233 #define API_NetUserModalsSet 111
1234 #define API_NetFileEnum2 112
1235 #define API_NetUserAdd2 113
1236 #define API_NetUserSetInfo2 114
1237 #define API_NetUserPasswordSet2 115
1238 #define API_I_NetServerEnum2 116
1239 #define API_NetConfigGet2 117
1240 #define API_NetConfigGetAll2 118
1241 #define API_NetGetDCName 119
1242 #define API_NetHandleGetInfo 120
1243 #define API_NetHandleSetInfo 121
1244 #define API_NetStatisticsGet2 122
1245 #define API_WBuildGetInfo 123
1246 #define API_NetFileGetInfo2 124
1247 #define API_NetFileClose2 125
1248 #define API_NetServerReqChallenge 126
1249 #define API_NetServerAuthenticate 127
1250 #define API_NetServerPasswordSet 128
1251 #define API_WNetAccountDeltas 129
1252 #define API_WNetAccountSync 130
1253 #define API_NetUserEnum2 131
1254 #define API_NetWkstaUserLogon 132
1255 #define API_NetWkstaUserLogoff 133
1256 #define API_NetLogonEnum 134
1257 #define API_NetErrorLogRead 135
1258 #define API_I_NetPathType 136
1259 #define API_I_NetPathCanonicalize 137
1260 #define API_I_NetPathCompare 138
1261 #define API_I_NetNameValidate 139
1262 #define API_I_NetNameCanonicalize 140
1263 #define API_I_NetNameCompare 141
1264 #define API_NetAuditRead 142
1265 #define API_WPrintDestAdd 143
1266 #define API_WPrintDestSetInfo 144
1267 #define API_WPrintDestDel 145
1268 #define API_NetUserValidate2 146
1269 #define API_WPrintJobSetInfo 147
1270 #define API_TI_NetServerDiskEnum 148
1271 #define API_TI_NetServerDiskGetInfo 149
1272 #define API_TI_FTVerifyMirror 150
1273 #define API_TI_FTAbortVerify 151
1274 #define API_TI_FTGetInfo 152
1275 #define API_TI_FTSetInfo 153
1276 #define API_TI_FTLockDisk 154
1277 #define API_TI_FTFixError 155
1278 #define API_TI_FTAbortFix 156
1279 #define API_TI_FTDiagnoseError 157
1280 #define API_TI_FTGetDriveStats 158
1281 /* This line and number replaced a Dead Entry for 159 */
1282 #define API_TI_FTErrorGetInfo 160
1283 /* This line and number replaced a Dead Entry for 161 */
1284 /* This line and number replaced a Dead Entry for 162 */
1285 #define API_NetAccessCheck 163
1286 #define API_NetAlertRaise 164
1287 #define API_NetAlertStart 165
1288 #define API_NetAlertStop 166
1289 #define API_NetAuditWrite 167
1290 #define API_NetIRemoteAPI 168
1291 #define API_NetServiceStatus 169
1292 #define API_I_NetServerRegister 170
1293 #define API_I_NetServerDeregister 171
1294 #define API_I_NetSessionEntryMake 172
1295 #define API_I_NetSessionEntryClear 173
1296 #define API_I_NetSessionEntryGetInfo 174
1297 #define API_I_NetSessionEntrySetInfo 175
1298 #define API_I_NetConnectionEntryMake 176
1299 #define API_I_NetConnectionEntryClear 177
1300 #define API_I_NetConnectionEntrySetInfo 178
1301 #define API_I_NetConnectionEntryGetInfo 179
1302 #define API_I_NetFileEntryMake 180
1303 #define API_I_NetFileEntryClear 181
1304 #define API_I_NetFileEntrySetInfo 182
1305 #define API_I_NetFileEntryGetInfo 183
1306 #define API_AltSrvMessageBufferSend 184
1307 #define API_AltSrvMessageFileSend 185
1308 #define API_wI_NetRplWkstaEnum 186
1309 #define API_wI_NetRplWkstaGetInfo 187
1310 #define API_wI_NetRplWkstaSetInfo 188
1311 #define API_wI_NetRplWkstaAdd 189
1312 #define API_wI_NetRplWkstaDel 190
1313 #define API_wI_NetRplProfileEnum 191
1314 #define API_wI_NetRplProfileGetInfo 192
1315 #define API_wI_NetRplProfileSetInfo 193
1316 #define API_wI_NetRplProfileAdd 194
1317 #define API_wI_NetRplProfileDel 195
1318 #define API_wI_NetRplProfileClone 196
1319 #define API_wI_NetRplBaseProfileEnum 197
1320 /* This line and number replaced a Dead Entry for 198 */
1321 /* This line and number replaced a Dead Entry for 199 */
1322 /* This line and number replaced a Dead Entry for 200 */
1323 #define API_WIServerSetInfo 201
1324 /* This line and number replaced a Dead Entry for 202 */
1325 /* This line and number replaced a Dead Entry for 203 */
1326 /* This line and number replaced a Dead Entry for 204 */
1327 #define API_WPrintDriverEnum 205
1328 #define API_WPrintQProcessorEnum 206
1329 #define API_WPrintPortEnum 207
1330 #define API_WNetWriteUpdateLog 208
1331 #define API_WNetAccountUpdate 209
1332 #define API_WNetAccountConfirmUpdate 210
1333 #define API_NetConfigSet 211
1334 #define API_WAccountsReplicate 212
1335 /* 213 is used by WfW */
1336 #define API_SamOEMChgPasswordUser2_P 214
1337 #define API_NetServerEnum3 215
1338 /* XXX - what about 216 through 249? */
1339 #define API_WPrintDriverGetInfo 250
1340 #define API_WPrintDriverSetInfo 251
1341 #define API_NetAliasAdd 252
1342 #define API_NetAliasDel 253
1343 #define API_NetAliasGetInfo 254
1344 #define API_NetAliasSetInfo 255
1345 #define API_NetAliasEnum 256
1346 #define API_NetUserGetLogonAsn 257
1347 #define API_NetUserSetLogonAsn 258
1348 #define API_NetUserGetAppSel 259
1349 #define API_NetUserSetAppSel 260
1350 #define API_NetAppAdd 261
1351 #define API_NetAppDel 262
1352 #define API_NetAppGetInfo 263
1353 #define API_NetAppSetInfo 264
1354 #define API_NetAppEnum 265
1355 #define API_NetUserDCDBInit 266
1356 #define API_NetDASDAdd 267
1357 #define API_NetDASDDel 268
1358 #define API_NetDASDGetInfo 269
1359 #define API_NetDASDSetInfo 270
1360 #define API_NetDASDEnum 271
1361 #define API_NetDASDCheck 272
1362 #define API_NetDASDCtl 273
1363 #define API_NetUserRemoteLogonCheck 274
1364 #define API_NetUserPasswordSet3 275
1365 #define API_NetCreateRIPLMachine 276
1366 #define API_NetDeleteRIPLMachine 277
1367 #define API_NetGetRIPLMachineInfo 278
1368 #define API_NetSetRIPLMachineInfo 279
1369 #define API_NetEnumRIPLMachine 280
1370 #define API_I_ShareAdd 281
1371 #define API_I_AliasEnum 282
1372 #define API_NetAccessApply 283
1373 #define API_WPrt16Query 284
1374 #define API_WPrt16Set 285
1375 #define API_NetUserDel100 286
1376 #define API_NetUserRemoteLogonCheck2 287
1377 #define API_WRemoteTODSet 294
1378 #define API_WPrintJobMoveAll 295
1379 #define API_W16AppParmAdd 296
1380 #define API_W16AppParmDel 297
1381 #define API_W16AppParmGet 298
1382 #define API_W16AppParmSet 299
1383 #define API_W16RIPLMachineCreate 300
1384 #define API_W16RIPLMachineGetInfo 301
1385 #define API_W16RIPLMachineSetInfo 302
1386 #define API_W16RIPLMachineEnum 303
1387 #define API_W16RIPLMachineListParmEnum 304
1388 #define API_W16RIPLMachClassGetInfo 305
1389 #define API_W16RIPLMachClassEnum 306
1390 #define API_W16RIPLMachClassCreate 307
1391 #define API_W16RIPLMachClassSetInfo 308
1392 #define API_W16RIPLMachClassDelete 309
1393 #define API_W16RIPLMachClassLPEnum 310
1394 #define API_W16RIPLMachineDelete 311
1395 #define API_W16WSLevelGetInfo 312
1396 #define API_NetServerNameAdd 313
1397 #define API_NetServerNameDel 314
1398 #define API_NetServerNameEnum 315
1399 #define API_I_WDASDEnum 316
1400 #define API_I_WDASDEnumTerminate 317
1401 #define API_I_WDASDSetInfo2 318
1403 static const struct lanman_desc lmd[] = {
1405 lm_params_req_netshareenum,
1410 lm_params_resp_netshareenum,
1413 netshareenum_share_entry,
1415 lm_data_resp_netshareenum,
1418 { API_NetShareGetInfo,
1419 lm_params_req_netsharegetinfo,
1424 lm_params_resp_netsharegetinfo,
1429 lm_data_resp_netsharegetinfo,
1432 { API_NetServerGetInfo,
1433 lm_params_req_netservergetinfo,
1438 lm_params_resp_netservergetinfo,
1446 { API_NetUserGetInfo,
1447 lm_params_req_netusergetinfo,
1452 lm_params_resp_netusergetinfo,
1457 lm_data_resp_netusergetinfo,
1460 { API_NetUserGetGroups,
1461 lm_params_req_netusergetgroups,
1466 lm_params_resp_netusergetgroups,
1471 lm_data_resp_netusergetgroups,
1485 lm_data_resp_netremotetod,
1488 { API_NetServerEnum2,
1489 lm_params_req_netserverenum2,
1494 lm_params_resp_netserverenum2,
1496 &ett_lanman_servers,
1497 netserverenum2_server_entry,
1502 { API_NetWkstaGetInfo,
1503 lm_params_req_netwkstagetinfo,
1508 lm_params_resp_netwkstagetinfo,
1513 lm_data_resp_netwkstagetinfo,
1516 { API_NetWkstaUserLogon,
1517 lm_params_req_netwkstauserlogon,
1522 lm_params_resp_netwkstauserlogon,
1527 lm_data_resp_netwkstauserlogon,
1530 { API_NetWkstaUserLogoff,
1531 lm_params_req_netwkstauserlogoff,
1536 lm_params_resp_netwkstauserlogoff,
1541 lm_data_resp_netwkstauserlogoff,
1544 { API_SamOEMChgPasswordUser2_P,
1545 lm_params_req_samoemchangepassword,
1548 lm_data_req_samoemchangepassword,
1558 { API_NetServerEnum3,
1559 lm_params_req_netserverenum3,
1564 lm_params_resp_netserverenum2,
1566 &ett_lanman_servers,
1567 netserverenum2_server_entry,
1582 &ett_lanman_unknown_entry,
1587 static const struct lanman_desc *
1588 find_lanman(int lanman_num)
1592 for (i = 0; lmd[i].lanman_num != -1; i++) {
1593 if (lmd[i].lanman_num == lanman_num)
1599 static const guchar *
1600 get_count(const guchar *desc, int *countp)
1605 if (!isdigit(*desc)) {
1606 *countp = 1; /* no count was supplied */
1610 while ((c = *desc) != '\0' && isdigit(c)) {
1611 count = (count * 10) + c - '0';
1615 *countp = count; /* XXX - what if it's 0? */
1620 dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1621 proto_tree *tree, const guchar *desc, const item_t *items,
1622 gboolean *has_data_p)
1630 *has_data_p = FALSE;
1631 while ((c = *desc++) != '\0') {
1636 * A 16-bit word value in the request.
1638 if (items->func == NULL) {
1640 * We've run out of items in the table;
1641 * fall back on the default.
1643 offset = add_word_param(tvb, offset, 0, pinfo,
1645 } else if (items->type != PARAM_WORD) {
1647 * Descriptor character is 'W', but this
1648 * isn't a word parameter.
1650 WParam = tvb_get_letohs(tvb, offset);
1651 proto_tree_add_text(tree, tvb, offset, 2,
1652 "%s: Value is %u (0x%04X), type is wrong (W)",
1653 (*items->hf_index == -1) ?
1655 proto_registrar_get_name(*items->hf_index),
1660 offset = (*items->func)(tvb, offset, 0, pinfo,
1661 tree, 0, *items->hf_index);
1668 * A 32-bit doubleword value in the request.
1670 if (items->func == NULL) {
1672 * We've run out of items in the table;
1673 * fall back on the default.
1675 offset = add_dword_param(tvb, offset, 0, pinfo,
1677 } else if (items->type != PARAM_DWORD) {
1679 * Descriptor character is 'D', but this
1680 * isn't a doubleword parameter.
1682 LParam = tvb_get_letohl(tvb, offset);
1683 proto_tree_add_text(tree, tvb, offset, 2,
1684 "%s: Value is %u (0x%08X), type is wrong (D)",
1685 (*items->hf_index == -1) ?
1686 "Doubleword Param" :
1687 proto_registrar_get_name(*items->hf_index),
1692 offset = (*items->func)(tvb, offset, 0, pinfo,
1693 tree, 0, *items->hf_index);
1700 * A byte or multi-byte value in the request.
1702 desc = get_count(desc, &count);
1703 if (items->func == NULL) {
1705 * We've run out of items in the table;
1706 * fall back on the default.
1708 offset = add_byte_param(tvb, offset, count,
1709 pinfo, tree, 0, -1);
1710 } else if (items->type != PARAM_BYTES) {
1712 * Descriptor character is 'b', but this
1713 * isn't a byte/bytes parameter.
1715 proto_tree_add_text(tree, tvb, offset, count,
1716 "%s: Value is %s, type is wrong (b)",
1717 (*items->hf_index == -1) ?
1719 proto_registrar_get_name(*items->hf_index),
1720 tvb_bytes_to_str(tvb, offset, count));
1724 offset = (*items->func)(tvb, offset, count,
1725 pinfo, tree, 0, *items->hf_index);
1734 if (items->func == NULL) {
1736 * We've run out of items in the table;
1737 * fall back on the default.
1739 add_null_pointer_param(tvb, offset, 0,
1740 pinfo, tree, 0, -1);
1743 * If "*items->hf_index" is -1, this is
1744 * a reserved must-be-null field; don't
1745 * clutter the protocol tree by putting
1748 if (*items->hf_index != -1) {
1749 add_null_pointer_param(tvb,
1750 offset, 0, pinfo, tree, 0,
1759 * A null-terminated ASCII string.
1761 if (items->func == NULL) {
1763 * We've run out of items in the table;
1764 * fall back on the default.
1766 offset = add_string_param(tvb, offset, 0,
1767 pinfo, tree, 0, -1);
1768 } else if (items->type != PARAM_STRINGZ) {
1770 * Descriptor character is 'z', but this
1771 * isn't a string parameter.
1773 string_len = tvb_strsize(tvb, offset);
1774 proto_tree_add_text(tree, tvb, offset, string_len,
1775 "%s: Value is %s, type is wrong (z)",
1776 (*items->hf_index == -1) ?
1778 proto_registrar_get_name(*items->hf_index),
1779 tvb_format_text(tvb, offset, string_len));
1780 offset += string_len;
1783 offset = (*items->func)(tvb, offset, 0,
1784 pinfo, tree, 0, *items->hf_index);
1791 * One or more pad bytes.
1793 desc = get_count(desc, &count);
1794 proto_tree_add_text(tree, tvb, offset, count,
1801 * 16-bit receive buffer length.
1803 proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1810 * 32-bit send buffer offset.
1811 * This appears not to be sent over the wire.
1818 * 16-bit send buffer length.
1820 proto_tree_add_item(tree, hf_send_buf_len, tvb,
1833 dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1834 proto_tree *tree, const guchar *desc, const item_t *items,
1835 gboolean *has_data_p, gboolean *has_ent_count_p, guint16 *ent_count_p)
1842 *has_data_p = FALSE;
1843 *has_ent_count_p = FALSE;
1844 while ((c = *desc++) != '\0') {
1849 * 32-bit receive buffer offset.
1856 * A byte or series of bytes is returned.
1858 desc = get_count(desc, &count);
1859 if (items->func == NULL) {
1861 * We've run out of items in the table;
1862 * fall back on the default.
1864 offset = add_byte_param(tvb, offset, count,
1865 pinfo, tree, 0, -1);
1866 } else if (items->type != PARAM_BYTES) {
1868 * Descriptor character is 'b', but this
1869 * isn't a byte/bytes parameter.
1871 proto_tree_add_text(tree, tvb, offset, count,
1872 "%s: Value is %s, type is wrong (g)",
1873 (*items->hf_index == -1) ?
1875 proto_registrar_get_name(*items->hf_index),
1876 tvb_bytes_to_str(tvb, offset, count));
1880 offset = (*items->func)(tvb, offset, count,
1881 pinfo, tree, 0, *items->hf_index);
1888 * A 16-bit word is received.
1890 if (items->func == NULL) {
1892 * We've run out of items in the table;
1893 * fall back on the default.
1895 offset = add_word_param(tvb, offset, 0, pinfo,
1897 } else if (items->type != PARAM_WORD) {
1899 * Descriptor character is 'h', but this
1900 * isn't a word parameter.
1902 WParam = tvb_get_letohs(tvb, offset);
1903 proto_tree_add_text(tree, tvb, offset, 2,
1904 "%s: Value is %u (0x%04X), type is wrong (W)",
1905 (*items->hf_index == -1) ?
1907 proto_registrar_get_name(*items->hf_index),
1912 offset = (*items->func)(tvb, offset, 0, pinfo,
1913 tree, 0, *items->hf_index);
1920 * A 32-bit doubleword is received.
1922 if (items->func == NULL) {
1924 * We've run out of items in the table;
1925 * fall back on the default.
1927 offset = add_dword_param(tvb, offset, 0, pinfo,
1929 } else if (items->type != PARAM_DWORD) {
1931 * Descriptor character is 'i', but this
1932 * isn't a doubleword parameter.
1934 LParam = tvb_get_letohl(tvb, offset);
1935 proto_tree_add_text(tree, tvb, offset, 2,
1936 "%s: Value is %u (0x%08X), type is wrong (i)",
1937 (*items->hf_index == -1) ?
1938 "Doubleword Param" :
1939 proto_registrar_get_name(*items->hf_index),
1944 offset = (*items->func)(tvb, offset, 0, pinfo,
1945 tree, 0, *items->hf_index);
1952 * A 16-bit entry count is returned.
1954 WParam = tvb_get_letohs(tvb, offset);
1955 proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1958 *has_ent_count_p = TRUE;
1959 *ent_count_p = WParam; /* Save this for later retrieval */
1970 dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1971 packet_info *pinfo, proto_tree *tree, const guchar *desc,
1972 const item_t *items, guint16 *aux_count_p)
1982 if (aux_count_p != NULL)
1985 while ((c = *desc++) != '\0') {
1990 * A 16-bit word value.
1991 * XXX - handle the count?
1993 desc = get_count(desc, &count);
1994 if (items->func == NULL) {
1996 * We've run out of items in the table;
1997 * fall back on the default.
1999 offset = add_word_param(tvb, offset, 0, pinfo,
2001 } else if (items->type != PARAM_WORD) {
2003 * Descriptor character is 'W', but this
2004 * isn't a word parameter.
2006 WParam = tvb_get_letohs(tvb, offset);
2007 proto_tree_add_text(tree, tvb, offset, 2,
2008 "%s: Value is %u (0x%04X), type is wrong (W)",
2009 (*items->hf_index == -1) ?
2011 proto_registrar_get_name(*items->hf_index),
2016 offset = (*items->func)(tvb, offset, 0, pinfo,
2017 tree, convert, *items->hf_index);
2024 * A 32-bit doubleword value.
2025 * XXX - handle the count?
2027 desc = get_count(desc, &count);
2028 if (items->func == NULL) {
2030 * We've run out of items in the table;
2031 * fall back on the default.
2033 offset = add_dword_param(tvb, offset, 0, pinfo,
2035 } else if (items->type != PARAM_DWORD) {
2037 * Descriptor character is 'D', but this
2038 * isn't a doubleword parameter.
2040 LParam = tvb_get_letohl(tvb, offset);
2041 proto_tree_add_text(tree, tvb, offset, 2,
2042 "%s: Value is %u (0x%08X), type is wrong (D)",
2043 (*items->hf_index == -1) ?
2044 "Doubleword Param" :
2045 proto_registrar_get_name(*items->hf_index),
2050 offset = (*items->func)(tvb, offset, 0, pinfo,
2051 tree, convert, *items->hf_index);
2058 * A byte or multi-byte value.
2060 desc = get_count(desc, &count);
2061 if (items->func == NULL) {
2063 * We've run out of items in the table;
2064 * fall back on the default.
2066 offset = add_byte_param(tvb, offset, count,
2067 pinfo, tree, convert, -1);
2068 } else if (items->type != PARAM_BYTES) {
2070 * Descriptor character is 'B', but this
2071 * isn't a byte/bytes parameter.
2073 proto_tree_add_text(tree, tvb, offset, count,
2074 "%s: Value is %s, type is wrong (B)",
2075 (*items->hf_index == -1) ?
2077 proto_registrar_get_name(*items->hf_index),
2078 tvb_bytes_to_str(tvb, offset, count));
2082 offset = (*items->func)(tvb, offset, count,
2083 pinfo, tree, convert, *items->hf_index);
2092 if (items->func == NULL) {
2094 * We've run out of items in the table;
2095 * fall back on the default.
2097 add_null_pointer_param(tvb, offset, 0,
2098 pinfo, tree, convert, -1);
2101 * If "*items->hf_index" is -1, this is
2102 * a reserved must-be-null field; don't
2103 * clutter the protocol tree by putting
2106 if (*items->hf_index != -1) {
2107 add_null_pointer_param(tvb,
2108 offset, 0, pinfo, tree, convert,
2117 * A pointer to a null-terminated ASCII string.
2119 if (items->func == NULL) {
2121 * We've run out of items in the table;
2122 * fall back on the default.
2124 offset = add_stringz_pointer_param(tvb, offset,
2125 0, pinfo, tree, convert, -1);
2126 } else if (items->type != PARAM_STRINGZ) {
2128 * Descriptor character is 'z', but this
2129 * isn't a string parameter.
2131 string = get_stringz_pointer_value(tvb, offset,
2132 convert, &cptr, &string_len);
2134 proto_tree_add_text(tree, tvb, cptr, string_len,
2135 "%s: Value is %s, type is wrong (z)",
2136 (*items->hf_index == -1) ?
2138 proto_registrar_get_name(*items->hf_index),
2142 offset = (*items->func)(tvb, offset, 0,
2143 pinfo, tree, convert, *items->hf_index);
2150 * A pointer to a byte or multi-byte value.
2152 desc = get_count(desc, &count);
2153 if (items->func == NULL) {
2155 * We've run out of items in the table;
2156 * fall back on the default.
2158 offset = add_bytes_pointer_param(tvb, offset,
2159 count, pinfo, tree, convert, -1);
2160 } else if (items->type != PARAM_BYTES) {
2162 * Descriptor character is 'b', but this
2163 * isn't a byte/bytes parameter.
2165 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2167 proto_tree_add_text(tree, tvb, offset, count,
2168 "%s: Value is %s, type is wrong (b)",
2169 (*items->hf_index == -1) ?
2171 proto_registrar_get_name(*items->hf_index),
2172 tvb_bytes_to_str(tvb, cptr, count));
2175 offset = (*items->func)(tvb, offset, count,
2176 pinfo, tree, convert, *items->hf_index);
2183 * 16-bit auxiliary data structure count.
2186 WParam = tvb_get_letohs(tvb, offset);
2187 proto_tree_add_text(tree, tvb, offset, 2,
2189 "Auxiliary data structure count",
2192 if (aux_count_p != NULL)
2193 *aux_count_p = WParam; /* Save this for later retrieval */
2203 static const value_string commands[] = {
2204 {API_NetShareEnum, "NetShareEnum"},
2205 {API_NetShareGetInfo, "NetShareGetInfo"},
2206 {API_NetShareSetInfo, "NetShareSetInfo"},
2207 {API_NetShareAdd, "NetShareAdd"},
2208 {API_NetShareDel, "NetShareDel"},
2209 {API_NetShareCheck, "NetShareCheck"},
2210 {API_NetSessionEnum, "NetSessionEnum"},
2211 {API_NetSessionGetInfo, "NetSessionGetInfo"},
2212 {API_NetSessionDel, "NetSessionDel"},
2213 {API_WconnectionEnum, "NetConnectionEnum"},
2214 {API_NetFileEnum, "NetFileEnum"},
2215 {API_NetFileGetInfo, "NetFileGetInfo"},
2216 {API_NetFileClose, "NetFileClose"},
2217 {API_NetServerGetInfo, "NetServerGetInfo"},
2218 {API_NetServerSetInfo, "NetServerSetInfo"},
2219 {API_NetServerDiskEnum, "NetServerDiskEnum"},
2220 {API_NetServerAdminCommand, "NetServerAdminCommand"},
2221 {API_NetAuditOpen, "NetAuditOpen"},
2222 {API_NetAuditClear, "NetAuditClear"},
2223 {API_NetErrorLogOpen, "NetErrorLogOpen"},
2224 {API_NetErrorLogClear, "NetErrorLogClear"},
2225 {API_NetCharDevEnum, "NetCharDevEnum"},
2226 {API_NetCharDevGetInfo, "NetCharDevGetInfo"},
2227 {API_NetCharDevControl, "NetCharDevControl"},
2228 {API_NetCharDevQEnum, "NetCharDevQEnum"},
2229 {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"},
2230 {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"},
2231 {API_NetCharDevQPurge, "NetCharDevQPurge"},
2232 {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"},
2233 {API_NetMessageNameEnum, "NetMessageNameEnum"},
2234 {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"},
2235 {API_NetMessageNameAdd, "NetMessageNameAdd"},
2236 {API_NetMessageNameDel, "NetMessageNameDel"},
2237 {API_NetMessageNameFwd, "NetMessageNameFwd"},
2238 {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"},
2239 {API_NetMessageBufferSend, "NetMessageBufferSend"},
2240 {API_NetMessageFileSend, "NetMessageFileSend"},
2241 {API_NetMessageLogFileSet, "NetMessageLogFileSet"},
2242 {API_NetMessageLogFileGet, "NetMessageLogFileGet"},
2243 {API_NetServiceEnum, "NetServiceEnum"},
2244 {API_NetServiceInstall, "NetServiceInstall"},
2245 {API_NetServiceControl, "NetServiceControl"},
2246 {API_NetAccessEnum, "NetAccessEnum"},
2247 {API_NetAccessGetInfo, "NetAccessGetInfo"},
2248 {API_NetAccessSetInfo, "NetAccessSetInfo"},
2249 {API_NetAccessAdd, "NetAccessAdd"},
2250 {API_NetAccessDel, "NetAccessDel"},
2251 {API_NetGroupEnum, "NetGroupEnum"},
2252 {API_NetGroupAdd, "NetGroupAdd"},
2253 {API_NetGroupDel, "NetGroupDel"},
2254 {API_NetGroupAddUser, "NetGroupAddUser"},
2255 {API_NetGroupDelUser, "NetGroupDelUser"},
2256 {API_NetGroupGetUsers, "NetGroupGetUsers"},
2257 {API_NetUserEnum, "NetUserEnum"},
2258 {API_NetUserAdd, "NetUserAdd"},
2259 {API_NetUserDel, "NetUserDel"},
2260 {API_NetUserGetInfo, "NetUserGetInfo"},
2261 {API_NetUserSetInfo, "NetUserSetInfo"},
2262 {API_NetUserPasswordSet, "NetUserPasswordSet"},
2263 {API_NetUserGetGroups, "NetUserGetGroups"},
2264 {API_NetWkstaSetUID, "NetWkstaSetUID"},
2265 {API_NetWkstaGetInfo, "NetWkstaGetInfo"},
2266 {API_NetWkstaSetInfo, "NetWkstaSetInfo"},
2267 {API_NetUseEnum, "NetUseEnum"},
2268 {API_NetUseAdd, "NetUseAdd"},
2269 {API_NetUseDel, "NetUseDel"},
2270 {API_NetUseGetInfo, "NetUseGetInfo"},
2271 {API_WPrintQEnum, "WPrintQEnum"},
2272 {API_WPrintQGetInfo, "WPrintQGetInfo"},
2273 {API_WPrintQSetInfo, "WPrintQSetInfo"},
2274 {API_WPrintQAdd, "WPrintQAdd"},
2275 {API_WPrintQDel, "WPrintQDel"},
2276 {API_WPrintQPause, "WPrintQPause"},
2277 {API_WPrintQContinue, "WPrintQContinue"},
2278 {API_WPrintJobEnum, "WPrintJobEnum"},
2279 {API_WPrintJobGetInfo, "WPrintJobGetInfo"},
2280 {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"},
2281 {API_WPrintJobDel, "WPrintJobDel"},
2282 {API_WPrintJobPause, "WPrintJobPause"},
2283 {API_WPrintJobContinue, "WPrintJobContinue"},
2284 {API_WPrintDestEnum, "WPrintDestEnum"},
2285 {API_WPrintDestGetInfo, "WPrintDestGetInfo"},
2286 {API_WPrintDestControl, "WPrintDestControl"},
2287 {API_NetProfileSave, "NetProfileSave"},
2288 {API_NetProfileLoad, "NetProfileLoad"},
2289 {API_NetStatisticsGet, "NetStatisticsGet"},
2290 {API_NetStatisticsClear, "NetStatisticsClear"},
2291 {API_NetRemoteTOD, "NetRemoteTOD"},
2292 {API_WNetBiosEnum, "WNetBiosEnum"},
2293 {API_WNetBiosGetInfo, "WNetBiosGetInfo"},
2294 {API_NetServerEnum, "NetServerEnum"},
2295 {API_I_NetServerEnum, "I_NetServerEnum"},
2296 {API_NetServiceGetInfo, "NetServiceGetInfo"},
2297 {API_WPrintQPurge, "WPrintQPurge"},
2298 {API_NetServerEnum2, "NetServerEnum2"},
2299 {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"},
2300 {API_NetGroupGetInfo, "NetGroupGetInfo"},
2301 {API_NetGroupSetInfo, "NetGroupSetInfo"},
2302 {API_NetGroupSetUsers, "NetGroupSetUsers"},
2303 {API_NetUserSetGroups, "NetUserSetGroups"},
2304 {API_NetUserModalsGet, "NetUserModalsGet"},
2305 {API_NetUserModalsSet, "NetUserModalsSet"},
2306 {API_NetFileEnum2, "NetFileEnum2"},
2307 {API_NetUserAdd2, "NetUserAdd2"},
2308 {API_NetUserSetInfo2, "NetUserSetInfo2"},
2309 {API_NetUserPasswordSet2, "SetUserPassword"},
2310 {API_I_NetServerEnum2, "I_NetServerEnum2"},
2311 {API_NetConfigGet2, "NetConfigGet2"},
2312 {API_NetConfigGetAll2, "NetConfigGetAll2"},
2313 {API_NetGetDCName, "NetGetDCName"},
2314 {API_NetHandleGetInfo, "NetHandleGetInfo"},
2315 {API_NetHandleSetInfo, "NetHandleSetInfo"},
2316 {API_NetStatisticsGet2, "NetStatisticsGet2"},
2317 {API_WBuildGetInfo, "WBuildGetInfo"},
2318 {API_NetFileGetInfo2, "NetFileGetInfo2"},
2319 {API_NetFileClose2, "NetFileClose2"},
2320 {API_NetServerReqChallenge, "NetServerReqChallenge"},
2321 {API_NetServerAuthenticate, "NetServerAuthenticate"},
2322 {API_NetServerPasswordSet, "NetServerPasswordSet"},
2323 {API_WNetAccountDeltas, "WNetAccountDeltas"},
2324 {API_WNetAccountSync, "WNetAccountSync"},
2325 {API_NetUserEnum2, "NetUserEnum2"},
2326 {API_NetWkstaUserLogon, "NetWkstaUserLogon"},
2327 {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"},
2328 {API_NetLogonEnum, "NetLogonEnum"},
2329 {API_NetErrorLogRead, "NetErrorLogRead"},
2330 {API_I_NetPathType, "I_NetPathType"},
2331 {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"},
2332 {API_I_NetPathCompare, "I_NetPathCompare"},
2333 {API_I_NetNameValidate, "I_NetNameValidate"},
2334 {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"},
2335 {API_I_NetNameCompare, "I_NetNameCompare"},
2336 {API_NetAuditRead, "NetAuditRead"},
2337 {API_WPrintDestAdd, "WPrintDestAdd"},
2338 {API_WPrintDestSetInfo, "WPrintDestSetInfo"},
2339 {API_WPrintDestDel, "WPrintDestDel"},
2340 {API_NetUserValidate2, "NetUserValidate2"},
2341 {API_WPrintJobSetInfo, "WPrintJobSetInfo"},
2342 {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"},
2343 {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"},
2344 {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"},
2345 {API_TI_FTAbortVerify, "TI_FTAbortVerify"},
2346 {API_TI_FTGetInfo, "TI_FTGetInfo"},
2347 {API_TI_FTSetInfo, "TI_FTSetInfo"},
2348 {API_TI_FTLockDisk, "TI_FTLockDisk"},
2349 {API_TI_FTFixError, "TI_FTFixError"},
2350 {API_TI_FTAbortFix, "TI_FTAbortFix"},
2351 {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"},
2352 {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"},
2353 {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"},
2354 {API_NetAccessCheck, "NetAccessCheck"},
2355 {API_NetAlertRaise, "NetAlertRaise"},
2356 {API_NetAlertStart, "NetAlertStart"},
2357 {API_NetAlertStop, "NetAlertStop"},
2358 {API_NetAuditWrite, "NetAuditWrite"},
2359 {API_NetIRemoteAPI, "NetIRemoteAPI"},
2360 {API_NetServiceStatus, "NetServiceStatus"},
2361 {API_I_NetServerRegister, "I_NetServerRegister"},
2362 {API_I_NetServerDeregister, "I_NetServerDeregister"},
2363 {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"},
2364 {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"},
2365 {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"},
2366 {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"},
2367 {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"},
2368 {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"},
2369 {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2370 {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2371 {API_I_NetFileEntryMake, "I_NetFileEntryMake"},
2372 {API_I_NetFileEntryClear, "I_NetFileEntryClear"},
2373 {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"},
2374 {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"},
2375 {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"},
2376 {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"},
2377 {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"},
2378 {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"},
2379 {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"},
2380 {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"},
2381 {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"},
2382 {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"},
2383 {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"},
2384 {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"},
2385 {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"},
2386 {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"},
2387 {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"},
2388 {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"},
2389 {API_WIServerSetInfo, "WIServerSetInfo"},
2390 {API_WPrintDriverEnum, "WPrintDriverEnum"},
2391 {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"},
2392 {API_WPrintPortEnum, "WPrintPortEnum"},
2393 {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"},
2394 {API_WNetAccountUpdate, "WNetAccountUpdate"},
2395 {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"},
2396 {API_NetConfigSet, "NetConfigSet"},
2397 {API_WAccountsReplicate, "WAccountsReplicate"},
2398 {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"},
2399 {API_NetServerEnum3, "NetServerEnum3"},
2400 {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"},
2401 {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"},
2402 {API_NetAliasAdd, "NetAliasAdd"},
2403 {API_NetAliasDel, "NetAliasDel"},
2404 {API_NetAliasGetInfo, "NetAliasGetInfo"},
2405 {API_NetAliasSetInfo, "NetAliasSetInfo"},
2406 {API_NetAliasEnum, "NetAliasEnum"},
2407 {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"},
2408 {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"},
2409 {API_NetUserGetAppSel, "NetUserGetAppSel"},
2410 {API_NetUserSetAppSel, "NetUserSetAppSel"},
2411 {API_NetAppAdd, "NetAppAdd"},
2412 {API_NetAppDel, "NetAppDel"},
2413 {API_NetAppGetInfo, "NetAppGetInfo"},
2414 {API_NetAppSetInfo, "NetAppSetInfo"},
2415 {API_NetAppEnum, "NetAppEnum"},
2416 {API_NetUserDCDBInit, "NetUserDCDBInit"},
2417 {API_NetDASDAdd, "NetDASDAdd"},
2418 {API_NetDASDDel, "NetDASDDel"},
2419 {API_NetDASDGetInfo, "NetDASDGetInfo"},
2420 {API_NetDASDSetInfo, "NetDASDSetInfo"},
2421 {API_NetDASDEnum, "NetDASDEnum"},
2422 {API_NetDASDCheck, "NetDASDCheck"},
2423 {API_NetDASDCtl, "NetDASDCtl"},
2424 {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"},
2425 {API_NetUserPasswordSet3, "NetUserPasswordSet3"},
2426 {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"},
2427 {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"},
2428 {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"},
2429 {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"},
2430 {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"},
2431 {API_I_ShareAdd, "I_ShareAdd"},
2432 {API_I_AliasEnum, "I_AliasEnum"},
2433 {API_NetAccessApply, "NetAccessApply"},
2434 {API_WPrt16Query, "WPrt16Query"},
2435 {API_WPrt16Set, "WPrt16Set"},
2436 {API_NetUserDel100, "NetUserDel100"},
2437 {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"},
2438 {API_WRemoteTODSet, "WRemoteTODSet"},
2439 {API_WPrintJobMoveAll, "WPrintJobMoveAll"},
2440 {API_W16AppParmAdd, "W16AppParmAdd"},
2441 {API_W16AppParmDel, "W16AppParmDel"},
2442 {API_W16AppParmGet, "W16AppParmGet"},
2443 {API_W16AppParmSet, "W16AppParmSet"},
2444 {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"},
2445 {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"},
2446 {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"},
2447 {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"},
2448 {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"},
2449 {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"},
2450 {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"},
2451 {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"},
2452 {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"},
2453 {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"},
2454 {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"},
2455 {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"},
2456 {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"},
2457 {API_NetServerNameAdd, "NetServerNameAdd"},
2458 {API_NetServerNameDel, "NetServerNameDel"},
2459 {API_NetServerNameEnum, "NetServerNameEnum"},
2460 {API_I_WDASDEnum, "I_WDASDEnum"},
2461 {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"},
2462 {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"},
2467 dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2468 proto_tree *tree, struct smb_info *smb_info,
2469 const struct lanman_desc *lanman, gboolean has_ent_count,
2472 smb_transact_info_t *trp = NULL;
2473 const item_list_t *resp_data_list;
2474 int offset, start_offset;
2477 const item_t *resp_data;
2478 proto_item *data_item;
2479 proto_tree *data_tree;
2480 proto_item *entry_item;
2481 proto_tree *entry_tree;
2485 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
2486 trp = smb_info->sip->extra_info;
2489 * Find the item table for the matching request's detail level.
2491 for (resp_data_list = lanman->resp_data_list;
2492 resp_data_list->level != -1; resp_data_list++) {
2493 if (resp_data_list->level == trp->info_level)
2496 resp_data = resp_data_list->item_list;
2499 if (has_ent_count) {
2501 * The data is a list of entries; create a protocol tree item
2505 label = lanman->resp_data_entry_list_label;
2508 if (lanman->ett_data_entry_list != NULL)
2509 ett = *lanman->ett_data_entry_list;
2511 ett = ett_lanman_unknown_entries;
2512 data_item = proto_tree_add_text(tree, tvb, offset, -1,
2514 data_tree = proto_item_add_subtree(data_item, ett);
2521 * Just leave it at the top level.
2527 if (trp->data_descrip == NULL) {
2529 * This could happen if we only dissected
2530 * part of the request to which this is a
2531 * reply, e.g. if the request was split
2532 * across TCP segments and we weren't doing
2533 * TCP desegmentation, or if we had a snapshot
2534 * length that was too short.
2536 * We can't dissect the data; just show it as raw data or,
2537 * if we've already created a top-level item, note that
2538 * no descriptor is available.
2540 if (has_ent_count) {
2541 if (data_item != NULL) {
2542 proto_item_append_text(data_item,
2543 " (No descriptor available)");
2546 proto_tree_add_text(data_tree, tvb, offset, -1,
2547 "Data (no descriptor available)");
2549 offset += tvb_length_remaining(tvb, offset);
2552 * If we have an entry count, show all the entries,
2553 * with each one having a protocol tree item.
2555 * Otherwise, we just show one returned item, with
2556 * no protocol tree item.
2560 for (i = 0; i < ent_count; i++) {
2561 start_offset = offset;
2562 if (has_ent_count &&
2563 lanman->resp_data_element_item != NULL) {
2565 * Create a protocol tree item for the
2569 (*lanman->resp_data_element_item)
2570 (tvb, data_tree, offset);
2571 entry_tree = proto_item_add_subtree(
2573 *lanman->ett_resp_data_element_item);
2576 * Just leave it at the current
2580 entry_tree = data_tree;
2583 offset = dissect_transact_data(tvb, offset,
2584 convert, pinfo, entry_tree,
2585 trp->data_descrip, resp_data, &aux_count);
2587 /* auxiliary data */
2588 if (trp->aux_data_descrip != NULL) {
2589 for (j = 0; j < aux_count; j++) {
2590 offset = dissect_transact_data(
2591 tvb, offset, convert,
2594 lanman->resp_aux_data, NULL);
2598 if (entry_item != NULL) {
2600 * Set the length of the protocol tree
2601 * item for the entry.
2603 proto_item_set_len(entry_item,
2604 offset - start_offset);
2609 if (data_item != NULL) {
2611 * Set the length of the protocol tree item
2614 proto_item_set_len(data_item, offset);
2619 dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2620 packet_info *pinfo, proto_tree *parent_tree)
2622 smb_info_t *smb_info = pinfo->private_data;
2623 smb_transact_info_t *trp = NULL;
2624 int offset = 0, start_offset;
2628 const struct lanman_desc *lanman;
2629 proto_item *item = NULL;
2630 proto_tree *tree = NULL;
2631 guint descriptor_len;
2632 const gchar *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2634 gboolean has_ent_count;
2635 guint16 ent_count, aux_count;
2637 proto_item *data_item;
2638 proto_tree *data_tree;
2640 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
2641 trp = smb_info->sip->extra_info;
2643 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2645 if (p_tvb == NULL) {
2647 * Requests must have parameters.
2651 pinfo->current_proto = "LANMAN";
2653 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2654 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2658 item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2659 pd_tvb, 0, -1, FALSE);
2660 tree = proto_item_add_subtree(item, ett_lanman);
2663 if (smb_info->request) { /* this is a request */
2665 cmd = tvb_get_letohs(p_tvb, offset);
2666 if (check_col(pinfo->cinfo, COL_INFO)) {
2667 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str(cmd, commands, "Unknown Command (%u)"));
2669 proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2674 * If we haven't already done so, save the function code in
2675 * the structure we were handed, so that it's available to
2676 * the code parsing the reply, and initialize the detail
2677 * level to -1, meaning "unknown".
2679 if (!pinfo->fd->flags.visited) {
2680 trp->lanman_cmd = cmd;
2681 trp->info_level = -1;
2682 trp->param_descrip=NULL;
2683 trp->data_descrip=NULL;
2684 trp->aux_data_descrip=NULL;
2687 /* parameter descriptor */
2688 descriptor_len = tvb_strsize(p_tvb, offset);
2689 proto_tree_add_item(tree, hf_param_desc, p_tvb, offset,
2690 descriptor_len, TRUE);
2691 param_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2692 if (!pinfo->fd->flags.visited) {
2694 * Save the parameter descriptor for future use.
2696 DISSECTOR_ASSERT(trp->param_descrip == NULL);
2697 trp->param_descrip = g_strdup(param_descrip);
2699 offset += descriptor_len;
2701 /* return descriptor */
2702 descriptor_len = tvb_strsize(p_tvb, offset);
2703 proto_tree_add_item(tree, hf_return_desc, p_tvb, offset,
2704 descriptor_len, TRUE);
2705 data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2706 if (!pinfo->fd->flags.visited) {
2708 * Save the return descriptor for future use.
2710 DISSECTOR_ASSERT(trp->data_descrip == NULL);
2711 trp->data_descrip = g_strdup(data_descrip);
2713 offset += descriptor_len;
2715 lanman = find_lanman(cmd);
2717 /* request parameters */
2718 start_offset = offset;
2719 offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2720 param_descrip, lanman->req, &has_data);
2722 /* auxiliary data descriptor */
2723 if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2725 * There are more parameters left, so the next
2726 * item is the auxiliary data descriptor.
2728 descriptor_len = tvb_strsize(p_tvb, offset);
2729 proto_tree_add_item(tree, hf_aux_data_desc, p_tvb, offset,
2730 descriptor_len, TRUE);
2731 aux_data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2732 if (!pinfo->fd->flags.visited) {
2734 * Save the auxiliary data descriptor for
2737 DISSECTOR_ASSERT(trp->aux_data_descrip == NULL);
2738 trp->aux_data_descrip =
2739 g_strdup(aux_data_descrip);
2741 offset += descriptor_len;
2744 /* reset offset, we now start dissecting the data area */
2746 if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2748 * There's a send buffer item in the descriptor
2749 * string, and the data count in the transaction
2750 * is non-zero, so there's data to dissect.
2753 if (lanman->req_data_item != NULL) {
2755 * Create a protocol tree item for the data.
2757 data_item = (*lanman->req_data_item)(d_tvb,
2758 pinfo, tree, offset);
2759 data_tree = proto_item_add_subtree(data_item,
2760 *lanman->ett_req_data);
2763 * Just leave it at the top level.
2770 offset = dissect_transact_data(d_tvb, offset, -1,
2771 pinfo, data_tree, data_descrip, lanman->req_data,
2772 &aux_count); /* XXX - what about strings? */
2774 /* auxiliary data */
2775 if (aux_data_descrip != NULL) {
2776 for (i = 0; i < aux_count; i++) {
2777 offset = dissect_transact_data(d_tvb,
2778 offset, -1, pinfo, data_tree,
2780 lanman->req_aux_data, NULL);
2784 if (data_item != NULL) {
2786 * Set the length of the protocol tree item
2789 proto_item_set_len(data_item, offset);
2794 * This is a response.
2795 * Have we seen the request to which it's a response?
2798 return FALSE; /* no - can't dissect it */
2800 /* ok we have seen this one before */
2802 /* if it looks like an interim response, update COL_INFO and return */
2803 if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
2804 && ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
2806 if (check_col(pinfo->cinfo, COL_INFO)) {
2807 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2808 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2810 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2815 if (check_col(pinfo->cinfo, COL_INFO)) {
2816 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2817 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2819 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2822 lanman = find_lanman(trp->lanman_cmd);
2824 /* response parameters */
2827 status = tvb_get_letohs(p_tvb, offset);
2828 proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2832 convert = tvb_get_letohs(p_tvb, offset);
2833 proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2836 if (trp->param_descrip == NULL) {
2838 * This could happen if we only dissected
2839 * part of the request to which this is a
2840 * reply, e.g. if the request was split
2841 * across TCP segments and we weren't doing
2842 * TCP desegmentation, or if we had a snapshot
2843 * length that was too short.
2845 * We can't dissect the parameters; just show them
2848 proto_tree_add_text(tree, p_tvb, offset, -1,
2849 "Parameters (no descriptor available)");
2852 * We don't know whether we have a receive buffer,
2853 * as we don't have the descriptor; just show what
2854 * bytes purport to be data.
2856 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2857 proto_tree_add_text(tree, d_tvb, 0, -1,
2858 "Data (no descriptor available)");
2861 /* rest of the parameters */
2862 offset = dissect_response_parameters(p_tvb, offset,
2863 pinfo, tree, trp->param_descrip, lanman->resp,
2864 &has_data, &has_ent_count, &ent_count);
2866 /* reset offset, we now start dissecting the data area */
2869 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2871 * Well, there are bytes that purport to
2872 * be data, at least.
2876 * There's a receive buffer item
2877 * in the descriptor string, so
2878 * dissect it as response data.
2880 dissect_response_data(d_tvb, pinfo,
2881 convert, tree, smb_info, lanman,
2882 has_ent_count, ent_count);
2885 * There's no receive buffer item,
2886 * but we do have data, so just
2887 * show what bytes are data.
2889 proto_tree_add_text(tree, d_tvb, 0, -1,
2890 "Data (no receive buffer)");
2900 proto_register_pipe_lanman(void)
2902 static hf_register_info hf[] = {
2903 { &hf_function_code,
2904 { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC,
2905 VALS(commands), 0, "LANMAN Function Code/Command", HFILL }},
2908 { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2909 NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2912 { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2913 NULL, 0, "LANMAN Return Descriptor", HFILL }},
2915 { &hf_aux_data_desc,
2916 { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2917 NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2920 { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2921 NULL, 0, "LANMAN Detail Level", HFILL }},
2924 { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2925 NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2928 { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2929 NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2931 { &hf_continuation_from,
2932 { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2933 NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2936 { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2937 VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2940 { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2941 NULL, 0, "LANMAN Convert", HFILL }},
2944 { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2945 NULL, 0, "LANMAN Number of Entries", HFILL }},
2948 { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2949 NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2952 { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2953 NULL, 0, "LANMAN Name of Share", HFILL }},
2956 { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2957 VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2959 { &hf_share_comment,
2960 { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2961 NULL, 0, "LANMAN Share Comment", HFILL }},
2963 { &hf_share_permissions,
2964 { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2965 NULL, 0, "LANMAN Permissions on share", HFILL }},
2967 { &hf_share_max_uses,
2968 { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2969 NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2971 { &hf_share_current_uses,
2972 { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2973 NULL, 0, "LANMAN Current connections to share", HFILL }},
2976 { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2977 NULL, 0, "LANMAN Share Path", HFILL }},
2979 { &hf_share_password,
2980 { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2981 NULL, 0, "LANMAN Share Password", HFILL }},
2984 { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2985 NULL, 0, "LANMAN Name of Server", HFILL }},
2988 { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2989 NULL, 0, "LANMAN Server Major Version", HFILL }},
2992 { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2993 NULL, 0, "LANMAN Server Minor Version", HFILL }},
2995 { &hf_server_comment,
2996 { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
2997 NULL, 0, "LANMAN Server Comment", HFILL }},
3000 { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
3001 NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
3004 { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, BASE_NONE,
3005 NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
3008 { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
3009 NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
3012 { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
3013 NULL, 0, "LANMAN Current hour", HFILL }},
3016 { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
3017 NULL, 0, "LANMAN Current minute", HFILL }},
3020 { "Second", "lanman.second", FT_UINT8, BASE_DEC,
3021 NULL, 0, "LANMAN Current second", HFILL }},
3024 { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
3025 NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
3028 { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
3029 NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
3032 { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
3033 NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
3036 { "Day", "lanman.day", FT_UINT8, BASE_DEC,
3037 NULL, 0, "LANMAN Current day", HFILL }},
3040 { "Month", "lanman.month", FT_UINT8, BASE_DEC,
3041 NULL, 0, "LANMAN Current month", HFILL }},
3044 { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3045 NULL, 0, "LANMAN Current year", HFILL }},
3048 { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3049 VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3051 { &hf_enumeration_domain,
3052 { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3053 NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3056 { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE,
3057 NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }},
3059 { &hf_computer_name,
3060 { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3061 NULL, 0, "LANMAN Computer Name", HFILL }},
3064 { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3065 NULL, 0, "LANMAN User Name", HFILL }},
3068 { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3069 NULL, 0, "LANMAN Group Name", HFILL }},
3071 { &hf_workstation_domain,
3072 { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3073 NULL, 0, "LANMAN Workstation Domain", HFILL }},
3075 { &hf_workstation_major,
3076 { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3077 NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3079 { &hf_workstation_minor,
3080 { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3081 NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3084 { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3085 NULL, 0, "LANMAN Logon Domain", HFILL }},
3087 { &hf_other_domains,
3088 { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3089 NULL, 0, "LANMAN Other Domains", HFILL }},
3092 { "Password", "lanman.password", FT_STRING, BASE_NONE,
3093 NULL, 0, "LANMAN Password", HFILL }},
3095 { &hf_workstation_name,
3096 { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3097 NULL, 0, "LANMAN Workstation Name", HFILL }},
3100 { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3101 NULL, 0, "LANMAN UStruct Length", HFILL }},
3104 { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3105 VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3107 { &hf_privilege_level,
3108 { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3109 VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3111 { &hf_operator_privileges,
3112 { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3113 VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3116 { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3117 NULL, 0, "LANMAN Number of Logons", HFILL }},
3120 { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3121 NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3124 { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, BASE_NONE,
3125 NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3128 { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, BASE_NONE,
3129 NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3132 { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3133 NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3136 { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3137 NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3140 { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3141 NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3143 { &hf_password_can_change,
3144 { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, BASE_NONE,
3145 NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3147 { &hf_password_must_change,
3148 { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, BASE_NONE,
3149 NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3152 { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3153 NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3156 { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3157 VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3160 { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3161 NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3164 { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3165 NULL, 0, "LANMAN Comment", HFILL }},
3168 { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3169 NULL, 0, "LANMAN User Comment", HFILL }},
3172 { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3173 NULL, 0, "LANMAN Full Name", HFILL }},
3176 { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3177 NULL, 0, "LANMAN Home Directory", HFILL }},
3180 { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3181 NULL, 0, "LANMAN Parameters", HFILL }},
3184 { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3185 NULL, 0, "LANMAN Logon Server", HFILL }},
3187 /* XXX - we should have a value_string table for this */
3189 { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC,
3190 VALS(ms_country_codes), 0, "LANMAN Country Code", HFILL }},
3193 { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3194 NULL, 0, "LANMAN Workstations", HFILL }},
3197 { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3198 NULL, 0, "LANMAN Max Storage", HFILL }},
3200 { &hf_units_per_week,
3201 { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3202 NULL, 0, "LANMAN Units Per Week", HFILL }},
3205 { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3206 NULL, 0, "LANMAN Logon Hours", HFILL }},
3208 /* XXX - we should have a value_string table for this */
3210 { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3211 NULL, 0, "LANMAN Code Page", HFILL }},
3214 { "New Password", "lanman.new_password", FT_BYTES, BASE_HEX,
3215 NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3218 { "Old Password", "lanman.old_password", FT_BYTES, BASE_HEX,
3219 NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3222 { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3223 NULL, 0, "LANMAN Reserved", HFILL }},
3226 static gint *ett[] = {
3228 &ett_lanman_unknown_entries,
3229 &ett_lanman_unknown_entry,
3230 &ett_lanman_servers,
3237 proto_smb_lanman = proto_register_protocol(
3238 "Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3239 proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3240 proto_register_subtree_array(ett, array_length(ett));
3243 static heur_dissector_list_t smb_transact_heur_subdissector_list;
3245 static GHashTable *dcerpc_fragment_table = NULL;
3246 static GHashTable *dcerpc_reassembled_table = NULL;
3249 smb_dcerpc_reassembly_init(void)
3251 fragment_table_init(&dcerpc_fragment_table);
3252 reassembled_table_init(&dcerpc_reassembled_table);
3256 dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3257 proto_tree *tree, guint32 fid)
3259 smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
3261 gboolean save_fragmented;
3264 fragment_data *fd_head;
3266 proto_item *frag_tree_item;
3268 pinfo->dcetransportsalt = fid;
3271 * Offer desegmentation service to DCERPC if we have all the
3272 * data. Otherwise, reassembly is (probably) impossible.
3274 pinfo->can_desegment=0;
3275 pinfo->desegment_offset = 0;
3276 pinfo->desegment_len = 0;
3277 reported_len = tvb_reported_length(d_tvb);
3278 if(smb_dcerpc_reassembly && tvb_bytes_exist(d_tvb, 0, reported_len)){
3279 pinfo->can_desegment=2;
3282 save_fragmented = pinfo->fragmented;
3285 /* if we are not offering desegmentation, just try the heuristics
3288 if(!pinfo->can_desegment){
3289 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3290 goto clean_up_and_exit;
3294 /* below this line, we know we are doing reassembly */
3297 * We have to keep track of reassemblies by FID, because
3298 * we could have more than one pipe operation in a frame
3299 * with NetBIOS-over-TCP.
3301 * We also have to keep track of them by direction, as
3302 * we might have reassemblies in progress in both directions.
3304 * We do that by combining the FID and the direction and
3305 * using that as the reassembly ID.
3307 * The direction is indicated by the SMB request/reply flag - data
3308 * from client to server is carried in requests, data from server
3309 * to client is carried in replies.
3311 * We know that the FID is only 16 bits long, so we put the
3312 * direction in bit 17.
3315 if (smb_priv->request)
3316 hash_key |= 0x10000;
3318 /* this is a new packet, see if we are already reassembling this
3319 pdu and if not, check if the dissector wants us
3322 if(!pinfo->fd->flags.visited){
3324 * This is the first pass.
3326 * Check if we are already reassembling this PDU or not;
3327 * we check for an in-progress reassembly for this FID
3328 * in this direction, by searching for its reassembly
3331 fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
3333 /* No reassembly, so this is a new pdu. check if the
3334 dissector wants us to reassemble it or if we
3335 already got the full pdu in this tvb.
3339 * First, just check if it looks like dcerpc or not.
3341 * XXX - this assumes that the dissector is idempotent,
3342 * as it's doing a "trial" dissection building no
3343 * tree; that's not necessarily the case.
3345 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, NULL);
3347 /* no this didnt look like something we know */
3349 goto clean_up_and_exit;
3352 /* did the subdissector want us to reassemble any
3355 if(pinfo->desegment_len){
3356 fragment_add_check(d_tvb, 0, pinfo, fid,
3357 dcerpc_fragment_table,
3358 dcerpc_reassembled_table,
3359 0, reported_len, TRUE);
3360 fragment_set_tot_len(pinfo, fid,
3361 dcerpc_fragment_table,
3362 pinfo->desegment_len+reported_len);
3363 goto clean_up_and_exit;
3366 /* guess we have the full pdu in this tvb then,
3367 just dissect it and continue.
3369 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3370 goto clean_up_and_exit;
3373 /* OK, we're already doing a reassembly for this FID.
3374 skip to last segment in the existing reassembly structure
3375 and add this fragment there
3377 XXX we might add code here to use any offset values
3378 we might pick up from the Read/Write calls instead of
3379 assuming we always get them in the correct order
3381 while(fd_head->next){
3382 fd_head=fd_head->next;
3384 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
3385 dcerpc_fragment_table, dcerpc_reassembled_table,
3386 fd_head->offset+fd_head->len,
3387 reported_len, TRUE);
3389 /* if we completed reassembly */
3391 new_tvb = tvb_new_real_data(fd_head->data,
3392 fd_head->datalen, fd_head->datalen);
3393 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3394 add_new_data_source(pinfo, new_tvb,
3396 pinfo->fragmented=FALSE;
3400 /* list what segments we have */
3401 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3402 tree, pinfo, d_tvb, &frag_tree_item);
3404 /* dissect the full PDU */
3405 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3407 goto clean_up_and_exit;
3411 * This is not the first pass; see if it's in the table of
3412 * reassembled packets.
3414 * XXX - we know that several of the arguments aren't going to
3415 * be used, so we pass bogus variables. Can we clean this
3416 * up so that we don't have to distinguish between the first
3417 * pass and subsequent passes?
3419 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
3420 dcerpc_reassembled_table, 0, 0, TRUE);
3422 /* we didnt find it, try any of the heuristic dissectors
3425 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3426 goto clean_up_and_exit;
3428 if(!fd_head->flags&FD_DEFRAGMENTED){
3429 /* we dont have a fully reassembled frame */
3430 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3431 goto clean_up_and_exit;
3434 /* it is reassembled but it was reassembled in a different frame */
3435 if(pinfo->fd->num!=fd_head->reassembled_in){
3436 proto_tree_add_uint(parent_tree, hf_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3437 goto clean_up_and_exit;
3441 /* display the reassembled pdu */
3442 new_tvb = tvb_new_real_data(fd_head->data,
3443 fd_head->datalen, fd_head->datalen);
3444 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3445 add_new_data_source(pinfo, new_tvb,
3447 pinfo->fragmented=FALSE;
3451 /* list what segments we have */
3452 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3453 tree, pinfo, d_tvb, &frag_tree_item);
3455 /* dissect the full PDU */
3456 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3461 /* clear out the variables */
3462 pinfo->private_data = smb_priv;
3463 pinfo->can_desegment=0;
3464 pinfo->desegment_offset = 0;
3465 pinfo->desegment_len = 0;
3468 call_dissector(data_handle, d_tvb, pinfo, parent_tree);
3470 pinfo->fragmented = save_fragmented;
3475 proto_register_pipe_dcerpc(void)
3477 register_heur_dissector_list("smb_transact", &smb_transact_heur_subdissector_list);
3478 register_init_routine(smb_dcerpc_reassembly_init);
3481 #define CALL_NAMED_PIPE 0x54
3482 #define WAIT_NAMED_PIPE 0x53
3483 #define PEEK_NAMED_PIPE 0x23
3484 #define Q_NM_P_HAND_STATE 0x21
3485 #define SET_NM_P_HAND_STATE 0x01
3486 #define Q_NM_PIPE_INFO 0x22
3487 #define TRANSACT_NM_PIPE 0x26
3488 #define RAW_READ_NM_PIPE 0x11
3489 #define RAW_WRITE_NM_PIPE 0x31
3491 static const value_string functions[] = {
3492 {CALL_NAMED_PIPE, "CallNamedPipe"},
3493 {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3494 {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3495 {Q_NM_P_HAND_STATE, "QNmPHandState"},
3496 {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3497 {Q_NM_PIPE_INFO, "QNmPipeInfo"},
3498 {TRANSACT_NM_PIPE, "TransactNmPipe"},
3499 {RAW_READ_NM_PIPE, "RawReadNmPipe"},
3500 {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3504 static const value_string pipe_status[] = {
3505 {1, "Disconnected by server"},
3507 {3, "Connection to server is OK"},
3508 {4, "Server end of pipe is closed"},
3512 #define PIPE_LANMAN 1
3513 #define PIPE_DCERPC 2
3515 /* decode the SMB pipe protocol
3517 pipe is the name of the pipe, e.g. LANMAN
3518 smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3521 smb_info->trans_subcmd gives us which pipe this response is for
3524 dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3525 tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3526 packet_info *pinfo, proto_tree *tree)
3528 smb_info_t *smb_info;
3529 smb_transact_info_t *tri;
3531 proto_item *pipe_item = NULL;
3532 proto_tree *pipe_tree = NULL;
3539 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3541 pinfo->current_proto = "SMB Pipe";
3543 smb_info = pinfo->private_data;
3548 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
3549 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3551 if (check_col(pinfo->cinfo, COL_INFO)) {
3552 col_set_str(pinfo->cinfo, COL_INFO,
3553 smb_info->request ? "Request" : "Response");
3556 if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI)
3557 tri = smb_info->sip->extra_info;
3562 * Set up a subtree for the pipe protocol. (It might not contain
3566 sp_len = tvb_length(sp_tvb);
3570 pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3571 sp_tvb, 0, sp_len, FALSE);
3572 pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3577 * Do we have any setup words at all?
3579 if (s_tvb != NULL && tvb_length(s_tvb) != 0) {
3581 * Yes. The first of them is the function.
3583 function = tvb_get_letohs(s_tvb, offset);
3584 proto_tree_add_uint(pipe_tree, hf_pipe_function, s_tvb,
3585 offset, 2, function);
3587 if (check_col(pinfo->cinfo, COL_INFO)) {
3588 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3589 val_to_str(function, functions, "Unknown function (0x%04x)"),
3590 smb_info->request ? "Request" : "Response");
3593 tri->function = function;
3596 * The second of them depends on the function.
3600 case CALL_NAMED_PIPE:
3601 case WAIT_NAMED_PIPE:
3605 proto_tree_add_item(pipe_tree, hf_pipe_priority, s_tvb,
3609 case PEEK_NAMED_PIPE:
3610 case Q_NM_P_HAND_STATE:
3611 case SET_NM_P_HAND_STATE:
3612 case Q_NM_PIPE_INFO:
3613 case TRANSACT_NM_PIPE:
3614 case RAW_READ_NM_PIPE:
3615 case RAW_WRITE_NM_PIPE:
3619 fid = tvb_get_letohs(s_tvb, 2);
3620 add_fid(s_tvb, pinfo, pipe_tree, offset, 2, (guint16) fid);
3627 * It's something unknown.
3628 * XXX - put it into the tree?
3635 * This is either a response or a pipe transaction with
3636 * no setup information.
3638 * In the former case, we can get that information from
3639 * the matching request, if we saw it.
3641 * In the latter case, there is no function or FID.
3643 if (tri != NULL && tri->function != -1) {
3644 function = tri->function;
3645 proto_tree_add_uint(pipe_tree, hf_pipe_function, NULL,
3647 if (check_col(pinfo->cinfo, COL_INFO)) {
3648 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3649 val_to_str(function, functions, "Unknown function (0x%04x)"),
3650 smb_info->request ? "Request" : "Response");
3654 add_fid(NULL, pinfo, pipe_tree, 0, 0, (guint16) fid);
3662 * XXX - put the byte count and the pipe name into the tree as well;
3663 * that requires us to fetch a possibly-Unicode string.
3666 if(smb_info->request){
3667 if(strncmp(pipe,"LANMAN",6) == 0){
3668 trans_subcmd=PIPE_LANMAN;
3670 /* assume it is DCERPC */
3671 trans_subcmd=PIPE_DCERPC;
3674 if (!pinfo->fd->flags.visited)
3675 tri->trans_subcmd = trans_subcmd;
3677 trans_subcmd = tri->trans_subcmd;
3681 * We don't know what type of pipe transaction this
3682 * was, so indicate that we didn't dissect it.
3689 case CALL_NAMED_PIPE:
3690 case TRANSACT_NM_PIPE:
3691 switch(trans_subcmd){
3694 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3700 * Only dissect this if we know the FID.
3705 return dissect_pipe_dcerpc(d_tvb, pinfo, tree,
3714 * We don't know the function; we dissect only LANMAN
3715 * pipe messages, not RPC pipe messages, in that case.
3717 switch(trans_subcmd){
3719 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3725 case WAIT_NAMED_PIPE:
3728 case PEEK_NAMED_PIPE:
3730 * Request contains no parameters or data.
3732 if (!smb_info->request) {
3736 proto_tree_add_item(pipe_tree, hf_pipe_peek_available,
3737 p_tvb, offset, 2, TRUE);
3739 proto_tree_add_item(pipe_tree, hf_pipe_peek_remaining,
3740 p_tvb, offset, 2, TRUE);
3742 proto_tree_add_item(pipe_tree, hf_pipe_peek_status,
3743 p_tvb, offset, 2, TRUE);
3748 case Q_NM_P_HAND_STATE:
3750 * Request contains no parameters or data.
3752 if (!smb_info->request) {
3755 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, FALSE);
3759 case SET_NM_P_HAND_STATE:
3761 * Response contains no parameters or data.
3763 if (smb_info->request) {
3766 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, TRUE);
3770 case Q_NM_PIPE_INFO:
3772 if (smb_info->request) {
3777 * Request contains an information level.
3779 info_level = tvb_get_letohs(p_tvb, offset);
3780 proto_tree_add_uint(pipe_tree, hf_pipe_getinfo_info_level,
3781 p_tvb, offset, 2, info_level);
3783 if (!pinfo->fd->flags.visited)
3784 tri->info_level = info_level;
3786 guint8 pipe_namelen;
3791 switch (tri->info_level) {
3794 proto_tree_add_item(pipe_tree,
3795 hf_pipe_getinfo_output_buffer_size,
3796 d_tvb, offset, 2, TRUE);
3798 proto_tree_add_item(pipe_tree,
3799 hf_pipe_getinfo_input_buffer_size,
3800 d_tvb, offset, 2, TRUE);
3802 proto_tree_add_item(pipe_tree,
3803 hf_pipe_getinfo_maximum_instances,
3804 d_tvb, offset, 1, TRUE);
3806 proto_tree_add_item(pipe_tree,
3807 hf_pipe_getinfo_current_instances,
3808 d_tvb, offset, 1, TRUE);
3810 pipe_namelen = tvb_get_guint8(d_tvb, offset);
3811 proto_tree_add_uint(pipe_tree,
3812 hf_pipe_getinfo_pipe_name_length,
3813 d_tvb, offset, 1, pipe_namelen);
3815 /* XXX - can this be Unicode? */
3816 proto_tree_add_item(pipe_tree,
3817 hf_pipe_getinfo_pipe_name,
3818 d_tvb, offset, pipe_namelen, TRUE);
3824 case RAW_READ_NM_PIPE:
3826 * Request contains no parameters or data.
3828 if (!smb_info->request) {
3832 offset = dissect_file_data(d_tvb, pipe_tree, 0,
3833 (guint16) tvb_reported_length(d_tvb),
3834 (guint16) tvb_reported_length(d_tvb));
3838 case RAW_WRITE_NM_PIPE:
3840 if (smb_info->request) {
3844 offset = dissect_file_data(d_tvb, pipe_tree,
3845 offset, (guint16) tvb_reported_length(d_tvb),
3846 (guint16) tvb_reported_length(d_tvb));
3850 proto_tree_add_item(pipe_tree,
3851 hf_pipe_write_raw_bytes_written,
3852 p_tvb, offset, 2, TRUE);
3861 proto_register_smb_pipe(void)
3863 static hf_register_info hf[] = {
3864 { &hf_pipe_function,
3865 { "Function", "pipe.function", FT_UINT16, BASE_HEX,
3866 VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3867 { &hf_pipe_priority,
3868 { "Priority", "pipe.priority", FT_UINT16, BASE_DEC,
3869 NULL, 0, "SMB Pipe Priority", HFILL }},
3870 { &hf_pipe_peek_available,
3871 { "Available Bytes", "pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3872 NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3873 { &hf_pipe_peek_remaining,
3874 { "Bytes Remaining", "pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3875 NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3876 { &hf_pipe_peek_status,
3877 { "Pipe Status", "pipe.peek.status", FT_UINT16, BASE_DEC,
3878 VALS(pipe_status), 0, "Pipe status", HFILL }},
3879 { &hf_pipe_getinfo_info_level,
3880 { "Information Level", "pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3881 NULL, 0, "Information level of information to return", HFILL }},
3882 { &hf_pipe_getinfo_output_buffer_size,
3883 { "Output Buffer Size", "pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3884 NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3885 { &hf_pipe_getinfo_input_buffer_size,
3886 { "Input Buffer Size", "pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3887 NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3888 { &hf_pipe_getinfo_maximum_instances,
3889 { "Maximum Instances", "pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3890 NULL, 0, "Maximum allowed number of instances", HFILL }},
3891 { &hf_pipe_getinfo_current_instances,
3892 { "Current Instances", "pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3893 NULL, 0, "Current number of instances", HFILL }},
3894 { &hf_pipe_getinfo_pipe_name_length,
3895 { "Pipe Name Length", "pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3896 NULL, 0, "Length of pipe name", HFILL }},
3897 { &hf_pipe_getinfo_pipe_name,
3898 { "Pipe Name", "pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3899 NULL, 0, "Name of pipe", HFILL }},
3900 { &hf_pipe_write_raw_bytes_written,
3901 { "Bytes Written", "pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3902 NULL, 0, "Number of bytes written to the pipe", HFILL }},
3903 { &hf_pipe_fragment_overlap,
3904 { "Fragment overlap", "pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3905 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3906 { &hf_pipe_fragment_overlap_conflict,
3907 { "Conflicting data in fragment overlap", "pipe.fragment.overlap.conflict", FT_BOOLEAN,
3908 BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3909 { &hf_pipe_fragment_multiple_tails,
3910 { "Multiple tail fragments found", "pipe.fragment.multipletails", FT_BOOLEAN,
3911 BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3912 { &hf_pipe_fragment_too_long_fragment,
3913 { "Fragment too long", "pipe.fragment.toolongfragment", FT_BOOLEAN,
3914 BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3915 { &hf_pipe_fragment_error,
3916 { "Defragmentation error", "pipe.fragment.error", FT_FRAMENUM,
3917 BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3918 { &hf_pipe_fragment,
3919 { "Fragment", "pipe.fragment", FT_FRAMENUM,
3920 BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3921 { &hf_pipe_fragments,
3922 { "Fragments", "pipe.fragments", FT_NONE,
3923 BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3924 { &hf_pipe_reassembled_in,
3925 { "This PDU is reassembled in", "pipe.reassembled_in", FT_FRAMENUM,
3926 BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3928 static gint *ett[] = {
3930 &ett_smb_pipe_fragment,
3931 &ett_smb_pipe_fragments,
3934 proto_smb_pipe = proto_register_protocol(
3935 "SMB Pipe Protocol", "SMB Pipe", "pipe");
3937 proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3938 proto_register_subtree_array(ett, array_length(ett));
3942 proto_reg_handoff_smb_pipe(void)
3944 data_handle = find_dissector("data");