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>
45 #include <epan/emem.h>
46 #include <epan/dissectors/packet-smb.h>
47 #include "packet-smb-pipe.h"
48 #include "packet-smb-browse.h"
49 #include "packet-smb-common.h"
50 #include "packet-windows-common.h"
51 #include "packet-dcerpc.h"
52 #include <epan/reassemble.h>
54 static int proto_smb_pipe = -1;
55 static int hf_pipe_function = -1;
56 static int hf_pipe_priority = -1;
57 static int hf_pipe_peek_available = -1;
58 static int hf_pipe_peek_remaining = -1;
59 static int hf_pipe_peek_status = -1;
60 static int hf_pipe_getinfo_info_level = -1;
61 static int hf_pipe_getinfo_output_buffer_size = -1;
62 static int hf_pipe_getinfo_input_buffer_size = -1;
63 static int hf_pipe_getinfo_maximum_instances = -1;
64 static int hf_pipe_getinfo_current_instances = -1;
65 static int hf_pipe_getinfo_pipe_name_length = -1;
66 static int hf_pipe_getinfo_pipe_name = -1;
67 static int hf_pipe_write_raw_bytes_written = -1;
68 static int hf_pipe_fragments = -1;
69 static int hf_pipe_fragment = -1;
70 static int hf_pipe_fragment_overlap = -1;
71 static int hf_pipe_fragment_overlap_conflict = -1;
72 static int hf_pipe_fragment_multiple_tails = -1;
73 static int hf_pipe_fragment_too_long_fragment = -1;
74 static int hf_pipe_fragment_error = -1;
75 static int hf_pipe_reassembled_in = -1;
77 static gint ett_smb_pipe = -1;
78 static gint ett_smb_pipe_fragment = -1;
79 static gint ett_smb_pipe_fragments = -1;
81 static const fragment_items smb_pipe_frag_items = {
82 &ett_smb_pipe_fragment,
83 &ett_smb_pipe_fragments,
86 &hf_pipe_fragment_overlap,
87 &hf_pipe_fragment_overlap_conflict,
88 &hf_pipe_fragment_multiple_tails,
89 &hf_pipe_fragment_too_long_fragment,
90 &hf_pipe_fragment_error,
95 static int proto_smb_lanman = -1;
96 static int hf_function_code = -1;
97 static int hf_param_desc = -1;
98 static int hf_return_desc = -1;
99 static int hf_aux_data_desc = -1;
100 static int hf_detail_level = -1;
101 static int hf_recv_buf_len = -1;
102 static int hf_send_buf_len = -1;
103 static int hf_continuation_from = -1;
104 static int hf_status = -1;
105 static int hf_convert = -1;
106 static int hf_ecount = -1;
107 static int hf_acount = -1;
108 static int hf_share_name = -1;
109 static int hf_share_type = -1;
110 static int hf_share_comment = -1;
111 static int hf_share_permissions = -1;
112 static int hf_share_max_uses = -1;
113 static int hf_share_current_uses = -1;
114 static int hf_share_path = -1;
115 static int hf_share_password = -1;
116 static int hf_server_name = -1;
117 static int hf_server_major = -1;
118 static int hf_server_minor = -1;
119 static int hf_server_comment = -1;
120 static int hf_abytes = -1;
121 static int hf_current_time = -1;
122 static int hf_msecs = -1;
123 static int hf_hour = -1;
124 static int hf_minute = -1;
125 static int hf_second = -1;
126 static int hf_hundredths = -1;
127 static int hf_tzoffset = -1;
128 static int hf_timeinterval = -1;
129 static int hf_day = -1;
130 static int hf_month = -1;
131 static int hf_year = -1;
132 static int hf_weekday = -1;
133 static int hf_enumeration_domain = -1;
134 static int hf_last_entry = -1;
135 static int hf_computer_name = -1;
136 static int hf_user_name = -1;
137 static int hf_group_name = -1;
138 static int hf_workstation_domain = -1;
139 static int hf_workstation_major = -1;
140 static int hf_workstation_minor = -1;
141 static int hf_logon_domain = -1;
142 static int hf_other_domains = -1;
143 static int hf_password = -1;
144 static int hf_workstation_name = -1;
145 static int hf_ustruct_size = -1;
146 static int hf_logon_code = -1;
147 static int hf_privilege_level = -1;
148 static int hf_operator_privileges = -1;
149 static int hf_num_logons = -1;
150 static int hf_bad_pw_count = -1;
151 static int hf_last_logon = -1;
152 static int hf_last_logoff = -1;
153 static int hf_logoff_time = -1;
154 static int hf_kickoff_time = -1;
155 static int hf_password_age = -1;
156 static int hf_password_can_change = -1;
157 static int hf_password_must_change = -1;
158 static int hf_script_path = -1;
159 static int hf_logoff_code = -1;
160 static int hf_duration = -1;
161 static int hf_comment = -1;
162 static int hf_user_comment = -1;
163 static int hf_full_name = -1;
164 static int hf_homedir = -1;
165 static int hf_parameters = -1;
166 static int hf_logon_server = -1;
167 static int hf_country_code = -1;
168 static int hf_workstations = -1;
169 static int hf_max_storage = -1;
170 static int hf_units_per_week = -1;
171 static int hf_logon_hours = -1;
172 static int hf_code_page = -1;
173 static int hf_new_password = -1;
174 static int hf_old_password = -1;
175 static int hf_reserved = -1;
177 static gint ett_lanman = -1;
178 static gint ett_lanman_unknown_entries = -1;
179 static gint ett_lanman_unknown_entry = -1;
180 static gint ett_lanman_shares = -1;
181 static gint ett_lanman_share = -1;
182 static gint ett_lanman_groups = -1;
183 static gint ett_lanman_servers = -1;
184 static gint ett_lanman_server = -1;
186 static dissector_handle_t data_handle;
191 * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
193 * among other documents.
196 static const value_string status_vals[] = {
198 {5, "User has insufficient privilege"},
199 {65, "Network access is denied"},
200 {86, "The specified password is invalid"},
201 {SMBE_moredata, "Additional data is available"},
202 {2114, "Service is not running on the remote computer"},
203 {2123, "Supplied buffer is too small"},
204 {2141, "Server is not configured for transactions (IPC$ not shared)"},
205 {2212, "An error occurred while loading or running the logon script"},
206 {2214, "The logon was not validated by any server"},
207 {2217, "The logon server is running an older software version"},
208 {2221, "The user name was not found"},
209 {2226, "Operation not permitted on Backup Domain Controller"},
210 {2240, "The user is not allowed to logon from this computer"},
211 {2241, "The user is not allowed to logon at this time"},
212 {2242, "The user password has expired"},
213 {2243, "The password cannot be changed"},
214 {2246, "The password is too short"},
218 static const value_string privilege_vals[] = {
221 {2, "Administrator"},
225 static const value_string op_privilege_vals[] = {
226 {0, "Print operator"},
227 {1, "Communications operator"},
228 {2, "Server operator"},
229 {3, "Accounts operator"},
233 static const value_string weekday_vals[] = {
245 add_word_param(tvbuff_t *tvb, int offset, int count _U_,
246 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
251 proto_tree_add_item(tree, hf_index, tvb, offset, 2, TRUE);
253 WParam = tvb_get_letohs(tvb, offset);
254 proto_tree_add_text(tree, tvb, offset, 2,
255 "Word Param: %u (0x%04X)", WParam, WParam);
262 add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
263 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
268 proto_tree_add_item(tree, hf_index, tvb, offset, 4, TRUE);
270 LParam = tvb_get_letohl(tvb, offset);
271 proto_tree_add_text(tree, tvb, offset, 4,
272 "Doubleword Param: %u (0x%08X)", LParam, LParam);
279 add_byte_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
280 proto_tree *tree, int convert _U_, int hf_index)
283 header_field_info *hfinfo;
285 if (hf_index != -1) {
286 hfinfo = proto_registrar_get_nth(hf_index);
287 if (hfinfo && count != 1 &&
288 (hfinfo->type == FT_INT8 || hfinfo->type == FT_UINT8)
290 THROW(ReportedBoundsError);
292 proto_tree_add_item(tree, hf_index, tvb, offset, count, TRUE);
295 BParam = tvb_get_guint8(tvb, offset);
296 proto_tree_add_text(tree, tvb, offset, count,
297 "Byte Param: %u (0x%02X)",
300 proto_tree_add_text(tree, tvb, offset, count,
302 tvb_bytes_to_str(tvb, offset, count));
310 add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
311 proto_tree *tree _U_, int convert _U_, int hf_index _U_)
314 * This is for parameters that have descriptor entries but that
315 * are, in practice, just padding.
322 add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
323 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
325 if (hf_index != -1) {
326 proto_tree_add_text(tree, tvb, offset, 0,
328 proto_registrar_get_name(hf_index));
330 proto_tree_add_text(tree, tvb, offset, 0,
331 "String Param (Null pointer)");
336 add_string_param(tvbuff_t *tvb, int offset, int count _U_,
337 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
341 string_len = tvb_strsize(tvb, offset);
342 if (hf_index != -1) {
343 proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
346 proto_tree_add_text(tree, tvb, offset, string_len,
348 tvb_format_text(tvb, offset, string_len));
350 offset += string_len;
355 get_stringz_pointer_value(tvbuff_t *tvb, int offset, int convert, int *cptrp,
361 /* pointer to string */
362 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
366 if (tvb_offset_exists(tvb, cptr) &&
367 (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
368 string_len++; /* include the terminating '\0' */
370 return tvb_format_text(tvb, cptr, string_len - 1);
376 add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
377 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
383 string = get_stringz_pointer_value(tvb, offset, convert, &cptr,
388 if (string != NULL) {
389 if (hf_index != -1) {
390 proto_tree_add_item(tree, hf_index, tvb, cptr,
393 proto_tree_add_text(tree, tvb, cptr, string_len,
394 "String Param: %s", string);
397 if (hf_index != -1) {
398 proto_tree_add_text(tree, tvb, 0, 0,
399 "%s: <String goes past end of frame>",
400 proto_registrar_get_name(hf_index));
402 proto_tree_add_text(tree, tvb, 0, 0,
403 "String Param: <String goes past end of frame>");
411 add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
412 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
416 /* pointer to byte array */
417 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
421 if (tvb_bytes_exist(tvb, cptr, count)) {
422 if (hf_index != -1) {
423 proto_tree_add_item(tree, hf_index, tvb, cptr,
426 proto_tree_add_text(tree, tvb, cptr, count,
428 tvb_bytes_to_str(tvb, cptr, count));
431 if (hf_index != -1) {
432 proto_tree_add_text(tree, tvb, 0, 0,
433 "%s: <Bytes go past end of frame>",
434 proto_registrar_get_name(hf_index));
436 proto_tree_add_text(tree, tvb, 0, 0,
437 "Byte Param: <Bytes goes past end of frame>");
445 add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
446 proto_tree *tree, int convert _U_, int hf_index)
448 struct smb_info *smb_info = pinfo->private_data;
449 smb_transact_info_t *trp = NULL;
452 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
453 trp = smb_info->sip->extra_info;
455 level = tvb_get_letohs(tvb, offset);
456 if (!pinfo->fd->flags.visited)
458 trp->info_level = level; /* remember this for the response */
460 proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
466 add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
467 proto_tree *tree, int convert _U_, int hf_index)
471 WParam = tvb_get_letohs(tvb, offset);
472 if (WParam == 0xffff) { /* -1 */
473 proto_tree_add_uint_format(tree, hf_index, tvb,
476 proto_registrar_get_name(hf_index));
478 proto_tree_add_uint(tree, hf_index, tvb,
486 add_server_type(tvbuff_t *tvb, int offset, int count _U_,
487 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
489 offset = dissect_smb_server_type_flags(
490 tvb, offset, pinfo, tree, NULL, FALSE);
495 add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
496 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
498 offset = dissect_smb_server_type_flags(
499 tvb, offset, pinfo, tree, NULL, TRUE);
504 add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
505 proto_tree *tree, int convert _U_, int hf_index)
509 nstime.secs = tvb_get_letohl(tvb, offset);
511 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
512 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
513 time_secs_to_str(nstime.secs));
519 * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but-
520 * it's-local-time-not-UTC time.
523 add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
524 const char *absent_name)
529 nstime.secs = tvb_get_letohl(tvb, offset);
532 * Sigh. Sometimes it appears that -1 means "unknown", and
533 * sometimes it appears that 0 means "unknown", for the last
536 if (nstime.secs == -1 || nstime.secs == 0) {
537 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
538 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
542 * Run it through "gmtime()" to break it down, and then
543 * run it through "mktime()" to put it back together
546 tmp = gmtime(&nstime.secs);
547 tmp->tm_isdst = -1; /* we don't know if it's DST or not */
548 nstime.secs = mktime(tmp);
549 proto_tree_add_time(tree, hf_index, tvb, offset, 4,
557 add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
558 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
560 return add_abstime_common(tvb, offset, tree, hf_index, "Never");
564 add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
565 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
567 return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
571 add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
572 proto_tree *tree, int convert _U_, int hf_index)
576 nlogons = tvb_get_letohs(tvb, offset);
577 if (nlogons == 0xffff) /* -1 */
578 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 2,
579 nlogons, "%s: Unknown",
580 proto_registrar_get_name(hf_index));
582 proto_tree_add_uint(tree, hf_index, tvb, offset, 2,
589 add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
590 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
594 max_storage = tvb_get_letohl(tvb, offset);
595 if (max_storage == 0xffffffff)
596 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
597 max_storage, "%s: No limit",
598 proto_registrar_get_name(hf_index));
600 proto_tree_add_uint(tree, hf_index, tvb, offset, 4,
607 add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
608 proto_tree *tree, int convert, int hf_index)
612 /* pointer to byte array */
613 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
617 if (tvb_bytes_exist(tvb, cptr, count)) {
620 * The logon hours should be exactly 21 bytes long.
622 * XXX - should actually carve up the bits;
623 * we need the units per week to do that, though.
625 proto_tree_add_item(tree, hf_index, tvb, cptr, count,
628 proto_tree_add_bytes_format(tree, hf_index, tvb,
629 cptr, count, tvb_get_ptr(tvb, cptr, count),
630 "%s: %s (wrong length, should be 21, is %d",
631 proto_registrar_get_name(hf_index),
632 tvb_bytes_to_str(tvb, cptr, count), count);
635 proto_tree_add_text(tree, tvb, 0, 0,
636 "%s: <Bytes go past end of frame>",
637 proto_registrar_get_name(hf_index));
644 add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
645 proto_tree *tree, int convert _U_, int hf_index)
649 tzoffset = tvb_get_letohs(tvb, offset);
651 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
652 tzoffset, "%s: %s east of UTC",
653 proto_registrar_get_name(hf_index),
654 time_secs_to_str(-tzoffset*60));
655 } else if (tzoffset > 0) {
656 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
657 tzoffset, "%s: %s west of UTC",
658 proto_registrar_get_name(hf_index),
659 time_secs_to_str(tzoffset*60));
661 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
662 tzoffset, "%s: at UTC",
663 proto_registrar_get_name(hf_index));
670 add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
671 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
673 guint16 timeinterval;
675 timeinterval = tvb_get_letohs(tvb, offset);
676 proto_tree_add_uint_format(tree, hf_timeinterval, tvb, offset, 2,
677 timeinterval, "%s: %f seconds", proto_registrar_get_name(hf_index),
684 add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
685 proto_tree *tree, int convert _U_, int hf_index _U_)
688 proto_tree_add_text(tree, tvb, offset, count,
689 "Bogus NetWkstaUserLogon parameters: length is %d, should be 54",
696 proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, TRUE);
703 proto_tree_add_item(tree, hf_password, tvb, offset, 15, TRUE);
709 /* workstation name */
710 proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, TRUE);
716 * The following data structure describes the Remote API requests we
719 * Simply fill in the number and parameter information.
720 * Try to keep them in order.
722 * We will extend this data structure as we try to decode more.
726 * This is a pointer to a function to process an item.
728 typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
732 * Type of an item; determines what parameter strings are valid for
736 PARAM_NONE, /* for the end-of-list stopper */
737 PARAM_WORD, /* 'W' or 'h' - 16-bit word */
738 PARAM_DWORD, /* 'D' or 'i' - 32-bit word */
739 PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
740 PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
744 * This structure describes an item; "hf_index" points to the index
745 * for the field corresponding to that item, "func" points to the
746 * function to use to add that item to the tree, and "type" is the
747 * type that the item is supposed to have.
756 * This structure describes a list of items; each list of items
757 * has a corresponding detail level.
761 const item_t *item_list;
767 proto_item *(*req_data_item)(tvbuff_t *, packet_info *,
770 const item_t *req_data;
771 const item_t *req_aux_data;
773 const gchar *resp_data_entry_list_label;
774 gint *ett_data_entry_list;
775 proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
777 gint *ett_resp_data_element_item;
778 const item_list_t *resp_data_list;
779 const item_t *resp_aux_data;
782 static int no_hf = -1; /* for padding crap */
784 static const item_t lm_params_req_netshareenum[] = {
785 { &hf_detail_level, add_detail_level, PARAM_WORD },
786 { &hf_recv_buf_len, add_word_param, PARAM_WORD },
787 { NULL, NULL, PARAM_NONE }
790 static const item_t lm_params_resp_netshareenum[] = {
791 { &hf_acount, add_word_param, PARAM_WORD },
792 { NULL, NULL, PARAM_NONE }
796 * Create a subtree for a share.
799 netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
802 return proto_tree_add_text(tree, tvb, offset, -1,
803 "Share %.13s", tvb_get_ptr(tvb, offset, 13));
808 static const item_t lm_null[] = {
809 { NULL, NULL, PARAM_NONE }
812 static const item_list_t lm_null_list[] = {
816 static const item_t lm_data_resp_netshareenum_1[] = {
817 { &hf_share_name, add_byte_param, PARAM_BYTES },
818 { &no_hf, add_pad_param, PARAM_BYTES },
819 { &hf_share_type, add_word_param, PARAM_WORD },
820 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
821 { NULL, NULL, PARAM_NONE }
824 static const item_list_t lm_data_resp_netshareenum[] = {
825 { 1, lm_data_resp_netshareenum_1 },
829 static const item_t lm_params_req_netsharegetinfo[] = {
830 { &hf_share_name, add_string_param, PARAM_STRINGZ },
831 { &hf_detail_level, add_detail_level, PARAM_WORD },
832 { NULL, NULL, PARAM_NONE }
835 static const item_t lm_params_resp_netsharegetinfo[] = {
836 { &hf_abytes, add_word_param, PARAM_WORD },
837 { NULL, NULL, PARAM_NONE }
840 static const item_t lm_data_resp_netsharegetinfo_0[] = {
841 { &hf_share_name, add_byte_param, PARAM_BYTES },
842 { NULL, NULL, PARAM_NONE }
845 static const item_t lm_data_resp_netsharegetinfo_1[] = {
846 { &hf_share_name, add_byte_param, PARAM_BYTES },
847 { &no_hf, add_pad_param, PARAM_BYTES },
848 { &hf_share_type, add_word_param, PARAM_WORD },
849 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
850 { NULL, NULL, PARAM_NONE }
853 static const item_t lm_data_resp_netsharegetinfo_2[] = {
854 { &hf_share_name, add_byte_param, PARAM_BYTES },
855 { &no_hf, add_pad_param, PARAM_BYTES },
856 { &hf_share_type, add_word_param, PARAM_WORD },
857 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
858 { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
859 { &hf_share_max_uses, add_max_uses, PARAM_WORD },
860 { &hf_share_current_uses, add_word_param, PARAM_WORD },
861 { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
862 { &hf_share_password, add_byte_param, PARAM_BYTES },
863 { NULL, NULL, PARAM_NONE }
866 static const item_list_t lm_data_resp_netsharegetinfo[] = {
867 { 0, lm_data_resp_netsharegetinfo_0 },
868 { 1, lm_data_resp_netsharegetinfo_1 },
869 { 2, lm_data_resp_netsharegetinfo_2 },
873 static const item_t lm_params_req_netservergetinfo[] = {
874 { &hf_detail_level, add_detail_level, PARAM_WORD },
875 { NULL, NULL, PARAM_NONE }
878 static const item_t lm_params_resp_netservergetinfo[] = {
879 { &hf_abytes, add_word_param, PARAM_WORD },
880 { NULL, NULL, PARAM_NONE }
883 static const item_t lm_data_serverinfo_0[] = {
884 { &hf_server_name, add_byte_param, PARAM_BYTES },
885 { NULL, NULL, PARAM_NONE }
888 static const item_t lm_data_serverinfo_1[] = {
889 { &hf_server_name, add_byte_param, PARAM_BYTES },
890 { &hf_server_major, add_byte_param, PARAM_BYTES },
891 { &hf_server_minor, add_byte_param, PARAM_BYTES },
892 { &no_hf, add_server_type, PARAM_DWORD },
893 { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
894 { NULL, NULL, PARAM_NONE }
897 static const item_list_t lm_data_serverinfo[] = {
898 { 0, lm_data_serverinfo_0 },
899 { 1, lm_data_serverinfo_1 },
903 static const item_t lm_params_req_netusergetinfo[] = {
904 { &hf_user_name, add_string_param, PARAM_STRINGZ },
905 { &hf_detail_level, add_detail_level, PARAM_WORD },
906 { NULL, NULL, PARAM_NONE }
909 static const item_t lm_params_resp_netusergetinfo[] = {
910 { &hf_abytes, add_word_param, PARAM_WORD },
911 { NULL, NULL, PARAM_NONE }
914 static const item_t lm_data_resp_netusergetinfo_11[] = {
915 { &hf_user_name, add_byte_param, PARAM_BYTES },
916 { &no_hf, add_pad_param, PARAM_BYTES },
917 { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
918 { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
919 { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
920 { &hf_privilege_level, add_word_param, PARAM_WORD },
921 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
922 { &hf_password_age, add_reltime, PARAM_DWORD },
923 { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
924 { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
925 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
926 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
927 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
928 { &hf_num_logons, add_nlogons, PARAM_WORD },
929 { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
930 { &hf_country_code, add_word_param, PARAM_WORD },
931 { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
932 { &hf_max_storage, add_max_storage, PARAM_DWORD },
933 { &hf_units_per_week, add_word_param, PARAM_WORD },
934 { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
935 { &hf_code_page, add_word_param, PARAM_WORD },
936 { NULL, NULL, PARAM_NONE }
939 static const item_list_t lm_data_resp_netusergetinfo[] = {
940 { 11, lm_data_resp_netusergetinfo_11 },
944 static const item_t lm_params_req_netusergetgroups[] = {
945 { &hf_user_name, add_string_param, PARAM_STRINGZ },
946 { &hf_detail_level, add_detail_level, PARAM_WORD },
947 { NULL, NULL, PARAM_NONE }
950 static const item_t lm_params_resp_netusergetgroups[] = {
951 { &hf_abytes, add_word_param, PARAM_WORD },
952 { NULL, NULL, PARAM_NONE }
955 static const item_t lm_data_resp_netusergetgroups_0[] = {
956 { &hf_group_name, add_byte_param, PARAM_BYTES },
957 { NULL, NULL, PARAM_NONE }
960 static const item_list_t lm_data_resp_netusergetgroups[] = {
961 { 0, lm_data_resp_netusergetgroups_0 },
966 * Has no detail level; make it the default.
968 static const item_t lm_data_resp_netremotetod_nolevel[] = {
969 { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
970 { &hf_msecs, add_dword_param, PARAM_DWORD },
971 { &hf_hour, add_byte_param, PARAM_BYTES },
972 { &hf_minute, add_byte_param, PARAM_BYTES },
973 { &hf_second, add_byte_param, PARAM_BYTES },
974 { &hf_hundredths, add_byte_param, PARAM_BYTES },
975 { &hf_tzoffset, add_tzoffset, PARAM_WORD },
976 { &hf_timeinterval, add_timeinterval, PARAM_WORD },
977 { &hf_day, add_byte_param, PARAM_BYTES },
978 { &hf_month, add_byte_param, PARAM_BYTES },
979 { &hf_year, add_word_param, PARAM_WORD },
980 { &hf_weekday, add_byte_param, PARAM_BYTES },
981 { NULL, NULL, PARAM_NONE }
984 static const item_list_t lm_data_resp_netremotetod[] = {
985 { -1, lm_data_resp_netremotetod_nolevel },
988 static const item_t lm_params_req_netserverenum2[] = {
989 { &hf_detail_level, add_detail_level, PARAM_WORD },
990 { &no_hf, add_server_type_info, PARAM_DWORD },
991 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
992 { NULL, NULL, PARAM_NONE }
996 * Create a subtree for a server.
999 netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
1002 return proto_tree_add_text(tree, tvb, offset, -1,
1003 "Server %.16s", tvb_get_ptr(tvb, offset, 16));
1008 static const item_t lm_params_resp_netserverenum2[] = {
1009 { &hf_acount, add_word_param, PARAM_WORD },
1010 { NULL, NULL, PARAM_NONE }
1014 static const item_t lm_params_req_netserverenum3[] = {
1015 { &hf_detail_level, add_detail_level, PARAM_WORD },
1016 { &no_hf, add_server_type_info, PARAM_DWORD },
1017 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
1018 { &hf_last_entry, add_string_param, PARAM_STRINGZ },
1019 { NULL, NULL, PARAM_NONE }
1023 static const item_t lm_params_req_netwkstagetinfo[] = {
1024 { &hf_detail_level, add_detail_level, PARAM_WORD },
1025 { NULL, NULL, PARAM_NONE }
1028 static const item_t lm_params_resp_netwkstagetinfo[] = {
1029 { &hf_abytes, add_word_param, PARAM_WORD },
1030 { NULL, NULL, PARAM_NONE }
1033 static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1034 { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1035 { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1036 { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1037 { &hf_workstation_major, add_byte_param, PARAM_BYTES },
1038 { &hf_workstation_minor, add_byte_param, PARAM_BYTES },
1039 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1040 { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1041 { NULL, NULL, PARAM_NONE }
1044 static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1045 { 10, lm_data_resp_netwkstagetinfo_10 },
1049 static const item_t lm_params_req_netwkstauserlogon[] = {
1050 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1051 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1052 { &hf_detail_level, add_detail_level, PARAM_WORD },
1053 { &no_hf, add_logon_args, PARAM_BYTES },
1054 { &hf_ustruct_size, add_word_param, PARAM_WORD },
1055 { NULL, NULL, PARAM_NONE }
1058 static const item_t lm_params_resp_netwkstauserlogon[] = {
1059 { &hf_abytes, add_word_param, PARAM_WORD },
1060 { NULL, NULL, PARAM_NONE }
1063 static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1064 { &hf_logon_code, add_word_param, PARAM_WORD },
1065 { &hf_user_name, add_byte_param, PARAM_BYTES },
1066 { &no_hf, add_pad_param, PARAM_BYTES },
1067 { &hf_privilege_level, add_word_param, PARAM_WORD },
1068 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1069 { &hf_num_logons, add_nlogons, PARAM_WORD },
1070 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1071 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1072 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1073 { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1074 { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1075 { &hf_password_age, add_reltime, PARAM_DWORD },
1076 { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1077 { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1078 { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1079 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1080 { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1081 { &hf_reserved, add_dword_param, PARAM_DWORD },
1082 { NULL, NULL, PARAM_NONE }
1085 static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1086 { 1, lm_data_resp_netwkstauserlogon_1 },
1090 static const item_t lm_params_req_netwkstauserlogoff[] = {
1091 { &hf_user_name, add_byte_param, PARAM_BYTES },
1092 { &no_hf, add_pad_param, PARAM_BYTES },
1093 { &hf_workstation_name, add_byte_param, PARAM_BYTES },
1094 { NULL, NULL, PARAM_NONE }
1097 static const item_t lm_params_resp_netwkstauserlogoff[] = {
1098 { &hf_abytes, add_word_param, PARAM_WORD },
1099 { NULL, NULL, PARAM_NONE }
1102 static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1103 { &hf_logoff_code, add_word_param, PARAM_WORD },
1104 { &hf_duration, add_reltime, PARAM_DWORD },
1105 { &hf_num_logons, add_nlogons, PARAM_WORD },
1106 { NULL, NULL, PARAM_NONE }
1109 static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1110 { 1, lm_data_resp_netwkstauserlogoff_1 },
1114 static const item_t lm_params_req_samoemchangepassword[] = {
1115 { &hf_user_name, add_string_param, PARAM_STRINGZ },
1116 { NULL, NULL, PARAM_NONE }
1119 static const item_t lm_data_req_samoemchangepassword[] = {
1120 { &hf_new_password, add_byte_param, PARAM_BYTES },
1121 { &hf_old_password, add_byte_param, PARAM_BYTES },
1122 { NULL, NULL, PARAM_NONE }
1125 #define API_NetShareEnum 0
1126 #define API_NetShareGetInfo 1
1127 #define API_NetShareSetInfo 2
1128 #define API_NetShareAdd 3
1129 #define API_NetShareDel 4
1130 #define API_NetShareCheck 5
1131 #define API_NetSessionEnum 6
1132 #define API_NetSessionGetInfo 7
1133 #define API_NetSessionDel 8
1134 #define API_WconnectionEnum 9
1135 #define API_NetFileEnum 10
1136 #define API_NetFileGetInfo 11
1137 #define API_NetFileClose 12
1138 #define API_NetServerGetInfo 13
1139 #define API_NetServerSetInfo 14
1140 #define API_NetServerDiskEnum 15
1141 #define API_NetServerAdminCommand 16
1142 #define API_NetAuditOpen 17
1143 #define API_NetAuditClear 18
1144 #define API_NetErrorLogOpen 19
1145 #define API_NetErrorLogClear 20
1146 #define API_NetCharDevEnum 21
1147 #define API_NetCharDevGetInfo 22
1148 #define API_NetCharDevControl 23
1149 #define API_NetCharDevQEnum 24
1150 #define API_NetCharDevQGetInfo 25
1151 #define API_NetCharDevQSetInfo 26
1152 #define API_NetCharDevQPurge 27
1153 #define API_NetCharDevQPurgeSelf 28
1154 #define API_NetMessageNameEnum 29
1155 #define API_NetMessageNameGetInfo 30
1156 #define API_NetMessageNameAdd 31
1157 #define API_NetMessageNameDel 32
1158 #define API_NetMessageNameFwd 33
1159 #define API_NetMessageNameUnFwd 34
1160 #define API_NetMessageBufferSend 35
1161 #define API_NetMessageFileSend 36
1162 #define API_NetMessageLogFileSet 37
1163 #define API_NetMessageLogFileGet 38
1164 #define API_NetServiceEnum 39
1165 #define API_NetServiceInstall 40
1166 #define API_NetServiceControl 41
1167 #define API_NetAccessEnum 42
1168 #define API_NetAccessGetInfo 43
1169 #define API_NetAccessSetInfo 44
1170 #define API_NetAccessAdd 45
1171 #define API_NetAccessDel 46
1172 #define API_NetGroupEnum 47
1173 #define API_NetGroupAdd 48
1174 #define API_NetGroupDel 49
1175 #define API_NetGroupAddUser 50
1176 #define API_NetGroupDelUser 51
1177 #define API_NetGroupGetUsers 52
1178 #define API_NetUserEnum 53
1179 #define API_NetUserAdd 54
1180 #define API_NetUserDel 55
1181 #define API_NetUserGetInfo 56
1182 #define API_NetUserSetInfo 57
1183 #define API_NetUserPasswordSet 58
1184 #define API_NetUserGetGroups 59
1185 /*This line and number replaced a Dead Entry for 60 */
1186 /*This line and number replaced a Dead Entry for 61 */
1187 #define API_NetWkstaSetUID 62
1188 #define API_NetWkstaGetInfo 63
1189 #define API_NetWkstaSetInfo 64
1190 #define API_NetUseEnum 65
1191 #define API_NetUseAdd 66
1192 #define API_NetUseDel 67
1193 #define API_NetUseGetInfo 68
1194 #define API_WPrintQEnum 69
1195 #define API_WPrintQGetInfo 70
1196 #define API_WPrintQSetInfo 71
1197 #define API_WPrintQAdd 72
1198 #define API_WPrintQDel 73
1199 #define API_WPrintQPause 74
1200 #define API_WPrintQContinue 75
1201 #define API_WPrintJobEnum 76
1202 #define API_WPrintJobGetInfo 77
1203 #define API_WPrintJobSetInfo_OLD 78
1204 /* This line and number replaced a Dead Entry for 79 */
1205 /* This line and number replaced a Dead Entry for 80 */
1206 #define API_WPrintJobDel 81
1207 #define API_WPrintJobPause 82
1208 #define API_WPrintJobContinue 83
1209 #define API_WPrintDestEnum 84
1210 #define API_WPrintDestGetInfo 85
1211 #define API_WPrintDestControl 86
1212 #define API_NetProfileSave 87
1213 #define API_NetProfileLoad 88
1214 #define API_NetStatisticsGet 89
1215 #define API_NetStatisticsClear 90
1216 #define API_NetRemoteTOD 91
1217 #define API_WNetBiosEnum 92
1218 #define API_WNetBiosGetInfo 93
1219 #define API_NetServerEnum 94
1220 #define API_I_NetServerEnum 95
1221 #define API_NetServiceGetInfo 96
1222 /* This line and number replaced a Dead Entry for 97 */
1223 /* This line and number replaced a Dead Entry for 98 */
1224 /* This line and number replaced a Dead Entry for 99 */
1225 /* This line and number replaced a Dead Entry for 100 */
1226 /* This line and number replaced a Dead Entry for 101 */
1227 /* This line and number replaced a Dead Entry for 102 */
1228 #define API_WPrintQPurge 103
1229 #define API_NetServerEnum2 104
1230 #define API_NetAccessGetUserPerms 105
1231 #define API_NetGroupGetInfo 106
1232 #define API_NetGroupSetInfo 107
1233 #define API_NetGroupSetUsers 108
1234 #define API_NetUserSetGroups 109
1235 #define API_NetUserModalsGet 110
1236 #define API_NetUserModalsSet 111
1237 #define API_NetFileEnum2 112
1238 #define API_NetUserAdd2 113
1239 #define API_NetUserSetInfo2 114
1240 #define API_NetUserPasswordSet2 115
1241 #define API_I_NetServerEnum2 116
1242 #define API_NetConfigGet2 117
1243 #define API_NetConfigGetAll2 118
1244 #define API_NetGetDCName 119
1245 #define API_NetHandleGetInfo 120
1246 #define API_NetHandleSetInfo 121
1247 #define API_NetStatisticsGet2 122
1248 #define API_WBuildGetInfo 123
1249 #define API_NetFileGetInfo2 124
1250 #define API_NetFileClose2 125
1251 #define API_NetServerReqChallenge 126
1252 #define API_NetServerAuthenticate 127
1253 #define API_NetServerPasswordSet 128
1254 #define API_WNetAccountDeltas 129
1255 #define API_WNetAccountSync 130
1256 #define API_NetUserEnum2 131
1257 #define API_NetWkstaUserLogon 132
1258 #define API_NetWkstaUserLogoff 133
1259 #define API_NetLogonEnum 134
1260 #define API_NetErrorLogRead 135
1261 #define API_I_NetPathType 136
1262 #define API_I_NetPathCanonicalize 137
1263 #define API_I_NetPathCompare 138
1264 #define API_I_NetNameValidate 139
1265 #define API_I_NetNameCanonicalize 140
1266 #define API_I_NetNameCompare 141
1267 #define API_NetAuditRead 142
1268 #define API_WPrintDestAdd 143
1269 #define API_WPrintDestSetInfo 144
1270 #define API_WPrintDestDel 145
1271 #define API_NetUserValidate2 146
1272 #define API_WPrintJobSetInfo 147
1273 #define API_TI_NetServerDiskEnum 148
1274 #define API_TI_NetServerDiskGetInfo 149
1275 #define API_TI_FTVerifyMirror 150
1276 #define API_TI_FTAbortVerify 151
1277 #define API_TI_FTGetInfo 152
1278 #define API_TI_FTSetInfo 153
1279 #define API_TI_FTLockDisk 154
1280 #define API_TI_FTFixError 155
1281 #define API_TI_FTAbortFix 156
1282 #define API_TI_FTDiagnoseError 157
1283 #define API_TI_FTGetDriveStats 158
1284 /* This line and number replaced a Dead Entry for 159 */
1285 #define API_TI_FTErrorGetInfo 160
1286 /* This line and number replaced a Dead Entry for 161 */
1287 /* This line and number replaced a Dead Entry for 162 */
1288 #define API_NetAccessCheck 163
1289 #define API_NetAlertRaise 164
1290 #define API_NetAlertStart 165
1291 #define API_NetAlertStop 166
1292 #define API_NetAuditWrite 167
1293 #define API_NetIRemoteAPI 168
1294 #define API_NetServiceStatus 169
1295 #define API_I_NetServerRegister 170
1296 #define API_I_NetServerDeregister 171
1297 #define API_I_NetSessionEntryMake 172
1298 #define API_I_NetSessionEntryClear 173
1299 #define API_I_NetSessionEntryGetInfo 174
1300 #define API_I_NetSessionEntrySetInfo 175
1301 #define API_I_NetConnectionEntryMake 176
1302 #define API_I_NetConnectionEntryClear 177
1303 #define API_I_NetConnectionEntrySetInfo 178
1304 #define API_I_NetConnectionEntryGetInfo 179
1305 #define API_I_NetFileEntryMake 180
1306 #define API_I_NetFileEntryClear 181
1307 #define API_I_NetFileEntrySetInfo 182
1308 #define API_I_NetFileEntryGetInfo 183
1309 #define API_AltSrvMessageBufferSend 184
1310 #define API_AltSrvMessageFileSend 185
1311 #define API_wI_NetRplWkstaEnum 186
1312 #define API_wI_NetRplWkstaGetInfo 187
1313 #define API_wI_NetRplWkstaSetInfo 188
1314 #define API_wI_NetRplWkstaAdd 189
1315 #define API_wI_NetRplWkstaDel 190
1316 #define API_wI_NetRplProfileEnum 191
1317 #define API_wI_NetRplProfileGetInfo 192
1318 #define API_wI_NetRplProfileSetInfo 193
1319 #define API_wI_NetRplProfileAdd 194
1320 #define API_wI_NetRplProfileDel 195
1321 #define API_wI_NetRplProfileClone 196
1322 #define API_wI_NetRplBaseProfileEnum 197
1323 /* This line and number replaced a Dead Entry for 198 */
1324 /* This line and number replaced a Dead Entry for 199 */
1325 /* This line and number replaced a Dead Entry for 200 */
1326 #define API_WIServerSetInfo 201
1327 /* This line and number replaced a Dead Entry for 202 */
1328 /* This line and number replaced a Dead Entry for 203 */
1329 /* This line and number replaced a Dead Entry for 204 */
1330 #define API_WPrintDriverEnum 205
1331 #define API_WPrintQProcessorEnum 206
1332 #define API_WPrintPortEnum 207
1333 #define API_WNetWriteUpdateLog 208
1334 #define API_WNetAccountUpdate 209
1335 #define API_WNetAccountConfirmUpdate 210
1336 #define API_NetConfigSet 211
1337 #define API_WAccountsReplicate 212
1338 /* 213 is used by WfW */
1339 #define API_SamOEMChgPasswordUser2_P 214
1340 #define API_NetServerEnum3 215
1341 /* XXX - what about 216 through 249? */
1342 #define API_WPrintDriverGetInfo 250
1343 #define API_WPrintDriverSetInfo 251
1344 #define API_NetAliasAdd 252
1345 #define API_NetAliasDel 253
1346 #define API_NetAliasGetInfo 254
1347 #define API_NetAliasSetInfo 255
1348 #define API_NetAliasEnum 256
1349 #define API_NetUserGetLogonAsn 257
1350 #define API_NetUserSetLogonAsn 258
1351 #define API_NetUserGetAppSel 259
1352 #define API_NetUserSetAppSel 260
1353 #define API_NetAppAdd 261
1354 #define API_NetAppDel 262
1355 #define API_NetAppGetInfo 263
1356 #define API_NetAppSetInfo 264
1357 #define API_NetAppEnum 265
1358 #define API_NetUserDCDBInit 266
1359 #define API_NetDASDAdd 267
1360 #define API_NetDASDDel 268
1361 #define API_NetDASDGetInfo 269
1362 #define API_NetDASDSetInfo 270
1363 #define API_NetDASDEnum 271
1364 #define API_NetDASDCheck 272
1365 #define API_NetDASDCtl 273
1366 #define API_NetUserRemoteLogonCheck 274
1367 #define API_NetUserPasswordSet3 275
1368 #define API_NetCreateRIPLMachine 276
1369 #define API_NetDeleteRIPLMachine 277
1370 #define API_NetGetRIPLMachineInfo 278
1371 #define API_NetSetRIPLMachineInfo 279
1372 #define API_NetEnumRIPLMachine 280
1373 #define API_I_ShareAdd 281
1374 #define API_I_AliasEnum 282
1375 #define API_NetAccessApply 283
1376 #define API_WPrt16Query 284
1377 #define API_WPrt16Set 285
1378 #define API_NetUserDel100 286
1379 #define API_NetUserRemoteLogonCheck2 287
1380 #define API_WRemoteTODSet 294
1381 #define API_WPrintJobMoveAll 295
1382 #define API_W16AppParmAdd 296
1383 #define API_W16AppParmDel 297
1384 #define API_W16AppParmGet 298
1385 #define API_W16AppParmSet 299
1386 #define API_W16RIPLMachineCreate 300
1387 #define API_W16RIPLMachineGetInfo 301
1388 #define API_W16RIPLMachineSetInfo 302
1389 #define API_W16RIPLMachineEnum 303
1390 #define API_W16RIPLMachineListParmEnum 304
1391 #define API_W16RIPLMachClassGetInfo 305
1392 #define API_W16RIPLMachClassEnum 306
1393 #define API_W16RIPLMachClassCreate 307
1394 #define API_W16RIPLMachClassSetInfo 308
1395 #define API_W16RIPLMachClassDelete 309
1396 #define API_W16RIPLMachClassLPEnum 310
1397 #define API_W16RIPLMachineDelete 311
1398 #define API_W16WSLevelGetInfo 312
1399 #define API_NetServerNameAdd 313
1400 #define API_NetServerNameDel 314
1401 #define API_NetServerNameEnum 315
1402 #define API_I_WDASDEnum 316
1403 #define API_I_WDASDEnumTerminate 317
1404 #define API_I_WDASDSetInfo2 318
1406 static const struct lanman_desc lmd[] = {
1408 lm_params_req_netshareenum,
1413 lm_params_resp_netshareenum,
1416 netshareenum_share_entry,
1418 lm_data_resp_netshareenum,
1421 { API_NetShareGetInfo,
1422 lm_params_req_netsharegetinfo,
1427 lm_params_resp_netsharegetinfo,
1432 lm_data_resp_netsharegetinfo,
1435 { API_NetServerGetInfo,
1436 lm_params_req_netservergetinfo,
1441 lm_params_resp_netservergetinfo,
1449 { API_NetUserGetInfo,
1450 lm_params_req_netusergetinfo,
1455 lm_params_resp_netusergetinfo,
1460 lm_data_resp_netusergetinfo,
1463 { API_NetUserGetGroups,
1464 lm_params_req_netusergetgroups,
1469 lm_params_resp_netusergetgroups,
1474 lm_data_resp_netusergetgroups,
1488 lm_data_resp_netremotetod,
1491 { API_NetServerEnum2,
1492 lm_params_req_netserverenum2,
1497 lm_params_resp_netserverenum2,
1499 &ett_lanman_servers,
1500 netserverenum2_server_entry,
1505 { API_NetWkstaGetInfo,
1506 lm_params_req_netwkstagetinfo,
1511 lm_params_resp_netwkstagetinfo,
1516 lm_data_resp_netwkstagetinfo,
1519 { API_NetWkstaUserLogon,
1520 lm_params_req_netwkstauserlogon,
1525 lm_params_resp_netwkstauserlogon,
1530 lm_data_resp_netwkstauserlogon,
1533 { API_NetWkstaUserLogoff,
1534 lm_params_req_netwkstauserlogoff,
1539 lm_params_resp_netwkstauserlogoff,
1544 lm_data_resp_netwkstauserlogoff,
1547 { API_SamOEMChgPasswordUser2_P,
1548 lm_params_req_samoemchangepassword,
1551 lm_data_req_samoemchangepassword,
1561 { API_NetServerEnum3,
1562 lm_params_req_netserverenum3,
1567 lm_params_resp_netserverenum2,
1569 &ett_lanman_servers,
1570 netserverenum2_server_entry,
1585 &ett_lanman_unknown_entry,
1590 static const struct lanman_desc *
1591 find_lanman(int lanman_num)
1595 for (i = 0; lmd[i].lanman_num != -1; i++) {
1596 if (lmd[i].lanman_num == lanman_num)
1602 static const guchar *
1603 get_count(const guchar *desc, int *countp)
1608 if (!isdigit(*desc)) {
1609 *countp = 1; /* no count was supplied */
1613 while ((c = *desc) != '\0' && isdigit(c)) {
1614 count = (count * 10) + c - '0';
1618 *countp = count; /* XXX - what if it's 0? */
1623 dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1624 proto_tree *tree, const guchar *desc, const item_t *items,
1625 gboolean *has_data_p)
1633 *has_data_p = FALSE;
1634 while ((c = *desc++) != '\0') {
1639 * A 16-bit word value in the request.
1641 if (items->func == NULL) {
1643 * We've run out of items in the table;
1644 * fall back on the default.
1646 offset = add_word_param(tvb, offset, 0, pinfo,
1648 } else if (items->type != PARAM_WORD) {
1650 * Descriptor character is 'W', but this
1651 * isn't a word parameter.
1653 WParam = tvb_get_letohs(tvb, offset);
1654 proto_tree_add_text(tree, tvb, offset, 2,
1655 "%s: Value is %u (0x%04X), type is wrong (W)",
1656 (*items->hf_index == -1) ?
1658 proto_registrar_get_name(*items->hf_index),
1663 offset = (*items->func)(tvb, offset, 0, pinfo,
1664 tree, 0, *items->hf_index);
1671 * A 32-bit doubleword value in the request.
1673 if (items->func == NULL) {
1675 * We've run out of items in the table;
1676 * fall back on the default.
1678 offset = add_dword_param(tvb, offset, 0, pinfo,
1680 } else if (items->type != PARAM_DWORD) {
1682 * Descriptor character is 'D', but this
1683 * isn't a doubleword parameter.
1685 LParam = tvb_get_letohl(tvb, offset);
1686 proto_tree_add_text(tree, tvb, offset, 2,
1687 "%s: Value is %u (0x%08X), type is wrong (D)",
1688 (*items->hf_index == -1) ?
1689 "Doubleword Param" :
1690 proto_registrar_get_name(*items->hf_index),
1695 offset = (*items->func)(tvb, offset, 0, pinfo,
1696 tree, 0, *items->hf_index);
1703 * A byte or multi-byte value in the request.
1705 desc = get_count(desc, &count);
1706 if (items->func == NULL) {
1708 * We've run out of items in the table;
1709 * fall back on the default.
1711 offset = add_byte_param(tvb, offset, count,
1712 pinfo, tree, 0, -1);
1713 } else if (items->type != PARAM_BYTES) {
1715 * Descriptor character is 'b', but this
1716 * isn't a byte/bytes parameter.
1718 proto_tree_add_text(tree, tvb, offset, count,
1719 "%s: Value is %s, type is wrong (b)",
1720 (*items->hf_index == -1) ?
1722 proto_registrar_get_name(*items->hf_index),
1723 tvb_bytes_to_str(tvb, offset, count));
1727 offset = (*items->func)(tvb, offset, count,
1728 pinfo, tree, 0, *items->hf_index);
1737 if (items->func == NULL) {
1739 * We've run out of items in the table;
1740 * fall back on the default.
1742 add_null_pointer_param(tvb, offset, 0,
1743 pinfo, tree, 0, -1);
1746 * If "*items->hf_index" is -1, this is
1747 * a reserved must-be-null field; don't
1748 * clutter the protocol tree by putting
1751 if (*items->hf_index != -1) {
1752 add_null_pointer_param(tvb,
1753 offset, 0, pinfo, tree, 0,
1762 * A null-terminated ASCII string.
1764 if (items->func == NULL) {
1766 * We've run out of items in the table;
1767 * fall back on the default.
1769 offset = add_string_param(tvb, offset, 0,
1770 pinfo, tree, 0, -1);
1771 } else if (items->type != PARAM_STRINGZ) {
1773 * Descriptor character is 'z', but this
1774 * isn't a string parameter.
1776 string_len = tvb_strsize(tvb, offset);
1777 proto_tree_add_text(tree, tvb, offset, string_len,
1778 "%s: Value is %s, type is wrong (z)",
1779 (*items->hf_index == -1) ?
1781 proto_registrar_get_name(*items->hf_index),
1782 tvb_format_text(tvb, offset, string_len));
1783 offset += string_len;
1786 offset = (*items->func)(tvb, offset, 0,
1787 pinfo, tree, 0, *items->hf_index);
1794 * One or more pad bytes.
1796 desc = get_count(desc, &count);
1797 proto_tree_add_text(tree, tvb, offset, count,
1804 * 16-bit receive buffer length.
1806 proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1813 * 32-bit send buffer offset.
1814 * This appears not to be sent over the wire.
1821 * 16-bit send buffer length.
1823 proto_tree_add_item(tree, hf_send_buf_len, tvb,
1836 dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1837 proto_tree *tree, const guchar *desc, const item_t *items,
1838 gboolean *has_data_p, gboolean *has_ent_count_p, guint16 *ent_count_p)
1845 *has_data_p = FALSE;
1846 *has_ent_count_p = FALSE;
1847 while ((c = *desc++) != '\0') {
1852 * 32-bit receive buffer offset.
1859 * A byte or series of bytes is returned.
1861 desc = get_count(desc, &count);
1862 if (items->func == NULL) {
1864 * We've run out of items in the table;
1865 * fall back on the default.
1867 offset = add_byte_param(tvb, offset, count,
1868 pinfo, tree, 0, -1);
1869 } else if (items->type != PARAM_BYTES) {
1871 * Descriptor character is 'b', but this
1872 * isn't a byte/bytes parameter.
1874 proto_tree_add_text(tree, tvb, offset, count,
1875 "%s: Value is %s, type is wrong (g)",
1876 (*items->hf_index == -1) ?
1878 proto_registrar_get_name(*items->hf_index),
1879 tvb_bytes_to_str(tvb, offset, count));
1883 offset = (*items->func)(tvb, offset, count,
1884 pinfo, tree, 0, *items->hf_index);
1891 * A 16-bit word is received.
1893 if (items->func == NULL) {
1895 * We've run out of items in the table;
1896 * fall back on the default.
1898 offset = add_word_param(tvb, offset, 0, pinfo,
1900 } else if (items->type != PARAM_WORD) {
1902 * Descriptor character is 'h', but this
1903 * isn't a word parameter.
1905 WParam = tvb_get_letohs(tvb, offset);
1906 proto_tree_add_text(tree, tvb, offset, 2,
1907 "%s: Value is %u (0x%04X), type is wrong (W)",
1908 (*items->hf_index == -1) ?
1910 proto_registrar_get_name(*items->hf_index),
1915 offset = (*items->func)(tvb, offset, 0, pinfo,
1916 tree, 0, *items->hf_index);
1923 * A 32-bit doubleword is received.
1925 if (items->func == NULL) {
1927 * We've run out of items in the table;
1928 * fall back on the default.
1930 offset = add_dword_param(tvb, offset, 0, pinfo,
1932 } else if (items->type != PARAM_DWORD) {
1934 * Descriptor character is 'i', but this
1935 * isn't a doubleword parameter.
1937 LParam = tvb_get_letohl(tvb, offset);
1938 proto_tree_add_text(tree, tvb, offset, 2,
1939 "%s: Value is %u (0x%08X), type is wrong (i)",
1940 (*items->hf_index == -1) ?
1941 "Doubleword Param" :
1942 proto_registrar_get_name(*items->hf_index),
1947 offset = (*items->func)(tvb, offset, 0, pinfo,
1948 tree, 0, *items->hf_index);
1955 * A 16-bit entry count is returned.
1957 WParam = tvb_get_letohs(tvb, offset);
1958 proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1961 *has_ent_count_p = TRUE;
1962 *ent_count_p = WParam; /* Save this for later retrieval */
1973 dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1974 packet_info *pinfo, proto_tree *tree, const guchar *desc,
1975 const item_t *items, guint16 *aux_count_p)
1985 if (aux_count_p != NULL)
1988 while ((c = *desc++) != '\0') {
1993 * A 16-bit word value.
1994 * XXX - handle the count?
1996 desc = get_count(desc, &count);
1997 if (items->func == NULL) {
1999 * We've run out of items in the table;
2000 * fall back on the default.
2002 offset = add_word_param(tvb, offset, 0, pinfo,
2004 } else if (items->type != PARAM_WORD) {
2006 * Descriptor character is 'W', but this
2007 * isn't a word parameter.
2009 WParam = tvb_get_letohs(tvb, offset);
2010 proto_tree_add_text(tree, tvb, offset, 2,
2011 "%s: Value is %u (0x%04X), type is wrong (W)",
2012 (*items->hf_index == -1) ?
2014 proto_registrar_get_name(*items->hf_index),
2019 offset = (*items->func)(tvb, offset, 0, pinfo,
2020 tree, convert, *items->hf_index);
2027 * A 32-bit doubleword value.
2028 * XXX - handle the count?
2030 desc = get_count(desc, &count);
2031 if (items->func == NULL) {
2033 * We've run out of items in the table;
2034 * fall back on the default.
2036 offset = add_dword_param(tvb, offset, 0, pinfo,
2038 } else if (items->type != PARAM_DWORD) {
2040 * Descriptor character is 'D', but this
2041 * isn't a doubleword parameter.
2043 LParam = tvb_get_letohl(tvb, offset);
2044 proto_tree_add_text(tree, tvb, offset, 2,
2045 "%s: Value is %u (0x%08X), type is wrong (D)",
2046 (*items->hf_index == -1) ?
2047 "Doubleword Param" :
2048 proto_registrar_get_name(*items->hf_index),
2053 offset = (*items->func)(tvb, offset, 0, pinfo,
2054 tree, convert, *items->hf_index);
2061 * A byte or multi-byte value.
2063 desc = get_count(desc, &count);
2064 if (items->func == NULL) {
2066 * We've run out of items in the table;
2067 * fall back on the default.
2069 offset = add_byte_param(tvb, offset, count,
2070 pinfo, tree, convert, -1);
2071 } else if (items->type != PARAM_BYTES) {
2073 * Descriptor character is 'B', but this
2074 * isn't a byte/bytes parameter.
2076 proto_tree_add_text(tree, tvb, offset, count,
2077 "%s: Value is %s, type is wrong (B)",
2078 (*items->hf_index == -1) ?
2080 proto_registrar_get_name(*items->hf_index),
2081 tvb_bytes_to_str(tvb, offset, count));
2085 offset = (*items->func)(tvb, offset, count,
2086 pinfo, tree, convert, *items->hf_index);
2095 if (items->func == NULL) {
2097 * We've run out of items in the table;
2098 * fall back on the default.
2100 add_null_pointer_param(tvb, offset, 0,
2101 pinfo, tree, convert, -1);
2104 * If "*items->hf_index" is -1, this is
2105 * a reserved must-be-null field; don't
2106 * clutter the protocol tree by putting
2109 if (*items->hf_index != -1) {
2110 add_null_pointer_param(tvb,
2111 offset, 0, pinfo, tree, convert,
2120 * A pointer to a null-terminated ASCII string.
2122 if (items->func == NULL) {
2124 * We've run out of items in the table;
2125 * fall back on the default.
2127 offset = add_stringz_pointer_param(tvb, offset,
2128 0, pinfo, tree, convert, -1);
2129 } else if (items->type != PARAM_STRINGZ) {
2131 * Descriptor character is 'z', but this
2132 * isn't a string parameter.
2134 string = get_stringz_pointer_value(tvb, offset,
2135 convert, &cptr, &string_len);
2137 proto_tree_add_text(tree, tvb, cptr, string_len,
2138 "%s: Value is %s, type is wrong (z)",
2139 (*items->hf_index == -1) ?
2141 proto_registrar_get_name(*items->hf_index),
2145 offset = (*items->func)(tvb, offset, 0,
2146 pinfo, tree, convert, *items->hf_index);
2153 * A pointer to a byte or multi-byte value.
2155 desc = get_count(desc, &count);
2156 if (items->func == NULL) {
2158 * We've run out of items in the table;
2159 * fall back on the default.
2161 offset = add_bytes_pointer_param(tvb, offset,
2162 count, pinfo, tree, convert, -1);
2163 } else if (items->type != PARAM_BYTES) {
2165 * Descriptor character is 'b', but this
2166 * isn't a byte/bytes parameter.
2168 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2170 proto_tree_add_text(tree, tvb, offset, count,
2171 "%s: Value is %s, type is wrong (b)",
2172 (*items->hf_index == -1) ?
2174 proto_registrar_get_name(*items->hf_index),
2175 tvb_bytes_to_str(tvb, cptr, count));
2178 offset = (*items->func)(tvb, offset, count,
2179 pinfo, tree, convert, *items->hf_index);
2186 * 16-bit auxiliary data structure count.
2189 WParam = tvb_get_letohs(tvb, offset);
2190 proto_tree_add_text(tree, tvb, offset, 2,
2192 "Auxiliary data structure count",
2195 if (aux_count_p != NULL)
2196 *aux_count_p = WParam; /* Save this for later retrieval */
2206 static const value_string commands[] = {
2207 {API_NetShareEnum, "NetShareEnum"},
2208 {API_NetShareGetInfo, "NetShareGetInfo"},
2209 {API_NetShareSetInfo, "NetShareSetInfo"},
2210 {API_NetShareAdd, "NetShareAdd"},
2211 {API_NetShareDel, "NetShareDel"},
2212 {API_NetShareCheck, "NetShareCheck"},
2213 {API_NetSessionEnum, "NetSessionEnum"},
2214 {API_NetSessionGetInfo, "NetSessionGetInfo"},
2215 {API_NetSessionDel, "NetSessionDel"},
2216 {API_WconnectionEnum, "NetConnectionEnum"},
2217 {API_NetFileEnum, "NetFileEnum"},
2218 {API_NetFileGetInfo, "NetFileGetInfo"},
2219 {API_NetFileClose, "NetFileClose"},
2220 {API_NetServerGetInfo, "NetServerGetInfo"},
2221 {API_NetServerSetInfo, "NetServerSetInfo"},
2222 {API_NetServerDiskEnum, "NetServerDiskEnum"},
2223 {API_NetServerAdminCommand, "NetServerAdminCommand"},
2224 {API_NetAuditOpen, "NetAuditOpen"},
2225 {API_NetAuditClear, "NetAuditClear"},
2226 {API_NetErrorLogOpen, "NetErrorLogOpen"},
2227 {API_NetErrorLogClear, "NetErrorLogClear"},
2228 {API_NetCharDevEnum, "NetCharDevEnum"},
2229 {API_NetCharDevGetInfo, "NetCharDevGetInfo"},
2230 {API_NetCharDevControl, "NetCharDevControl"},
2231 {API_NetCharDevQEnum, "NetCharDevQEnum"},
2232 {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"},
2233 {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"},
2234 {API_NetCharDevQPurge, "NetCharDevQPurge"},
2235 {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"},
2236 {API_NetMessageNameEnum, "NetMessageNameEnum"},
2237 {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"},
2238 {API_NetMessageNameAdd, "NetMessageNameAdd"},
2239 {API_NetMessageNameDel, "NetMessageNameDel"},
2240 {API_NetMessageNameFwd, "NetMessageNameFwd"},
2241 {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"},
2242 {API_NetMessageBufferSend, "NetMessageBufferSend"},
2243 {API_NetMessageFileSend, "NetMessageFileSend"},
2244 {API_NetMessageLogFileSet, "NetMessageLogFileSet"},
2245 {API_NetMessageLogFileGet, "NetMessageLogFileGet"},
2246 {API_NetServiceEnum, "NetServiceEnum"},
2247 {API_NetServiceInstall, "NetServiceInstall"},
2248 {API_NetServiceControl, "NetServiceControl"},
2249 {API_NetAccessEnum, "NetAccessEnum"},
2250 {API_NetAccessGetInfo, "NetAccessGetInfo"},
2251 {API_NetAccessSetInfo, "NetAccessSetInfo"},
2252 {API_NetAccessAdd, "NetAccessAdd"},
2253 {API_NetAccessDel, "NetAccessDel"},
2254 {API_NetGroupEnum, "NetGroupEnum"},
2255 {API_NetGroupAdd, "NetGroupAdd"},
2256 {API_NetGroupDel, "NetGroupDel"},
2257 {API_NetGroupAddUser, "NetGroupAddUser"},
2258 {API_NetGroupDelUser, "NetGroupDelUser"},
2259 {API_NetGroupGetUsers, "NetGroupGetUsers"},
2260 {API_NetUserEnum, "NetUserEnum"},
2261 {API_NetUserAdd, "NetUserAdd"},
2262 {API_NetUserDel, "NetUserDel"},
2263 {API_NetUserGetInfo, "NetUserGetInfo"},
2264 {API_NetUserSetInfo, "NetUserSetInfo"},
2265 {API_NetUserPasswordSet, "NetUserPasswordSet"},
2266 {API_NetUserGetGroups, "NetUserGetGroups"},
2267 {API_NetWkstaSetUID, "NetWkstaSetUID"},
2268 {API_NetWkstaGetInfo, "NetWkstaGetInfo"},
2269 {API_NetWkstaSetInfo, "NetWkstaSetInfo"},
2270 {API_NetUseEnum, "NetUseEnum"},
2271 {API_NetUseAdd, "NetUseAdd"},
2272 {API_NetUseDel, "NetUseDel"},
2273 {API_NetUseGetInfo, "NetUseGetInfo"},
2274 {API_WPrintQEnum, "WPrintQEnum"},
2275 {API_WPrintQGetInfo, "WPrintQGetInfo"},
2276 {API_WPrintQSetInfo, "WPrintQSetInfo"},
2277 {API_WPrintQAdd, "WPrintQAdd"},
2278 {API_WPrintQDel, "WPrintQDel"},
2279 {API_WPrintQPause, "WPrintQPause"},
2280 {API_WPrintQContinue, "WPrintQContinue"},
2281 {API_WPrintJobEnum, "WPrintJobEnum"},
2282 {API_WPrintJobGetInfo, "WPrintJobGetInfo"},
2283 {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"},
2284 {API_WPrintJobDel, "WPrintJobDel"},
2285 {API_WPrintJobPause, "WPrintJobPause"},
2286 {API_WPrintJobContinue, "WPrintJobContinue"},
2287 {API_WPrintDestEnum, "WPrintDestEnum"},
2288 {API_WPrintDestGetInfo, "WPrintDestGetInfo"},
2289 {API_WPrintDestControl, "WPrintDestControl"},
2290 {API_NetProfileSave, "NetProfileSave"},
2291 {API_NetProfileLoad, "NetProfileLoad"},
2292 {API_NetStatisticsGet, "NetStatisticsGet"},
2293 {API_NetStatisticsClear, "NetStatisticsClear"},
2294 {API_NetRemoteTOD, "NetRemoteTOD"},
2295 {API_WNetBiosEnum, "WNetBiosEnum"},
2296 {API_WNetBiosGetInfo, "WNetBiosGetInfo"},
2297 {API_NetServerEnum, "NetServerEnum"},
2298 {API_I_NetServerEnum, "I_NetServerEnum"},
2299 {API_NetServiceGetInfo, "NetServiceGetInfo"},
2300 {API_WPrintQPurge, "WPrintQPurge"},
2301 {API_NetServerEnum2, "NetServerEnum2"},
2302 {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"},
2303 {API_NetGroupGetInfo, "NetGroupGetInfo"},
2304 {API_NetGroupSetInfo, "NetGroupSetInfo"},
2305 {API_NetGroupSetUsers, "NetGroupSetUsers"},
2306 {API_NetUserSetGroups, "NetUserSetGroups"},
2307 {API_NetUserModalsGet, "NetUserModalsGet"},
2308 {API_NetUserModalsSet, "NetUserModalsSet"},
2309 {API_NetFileEnum2, "NetFileEnum2"},
2310 {API_NetUserAdd2, "NetUserAdd2"},
2311 {API_NetUserSetInfo2, "NetUserSetInfo2"},
2312 {API_NetUserPasswordSet2, "SetUserPassword"},
2313 {API_I_NetServerEnum2, "I_NetServerEnum2"},
2314 {API_NetConfigGet2, "NetConfigGet2"},
2315 {API_NetConfigGetAll2, "NetConfigGetAll2"},
2316 {API_NetGetDCName, "NetGetDCName"},
2317 {API_NetHandleGetInfo, "NetHandleGetInfo"},
2318 {API_NetHandleSetInfo, "NetHandleSetInfo"},
2319 {API_NetStatisticsGet2, "NetStatisticsGet2"},
2320 {API_WBuildGetInfo, "WBuildGetInfo"},
2321 {API_NetFileGetInfo2, "NetFileGetInfo2"},
2322 {API_NetFileClose2, "NetFileClose2"},
2323 {API_NetServerReqChallenge, "NetServerReqChallenge"},
2324 {API_NetServerAuthenticate, "NetServerAuthenticate"},
2325 {API_NetServerPasswordSet, "NetServerPasswordSet"},
2326 {API_WNetAccountDeltas, "WNetAccountDeltas"},
2327 {API_WNetAccountSync, "WNetAccountSync"},
2328 {API_NetUserEnum2, "NetUserEnum2"},
2329 {API_NetWkstaUserLogon, "NetWkstaUserLogon"},
2330 {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"},
2331 {API_NetLogonEnum, "NetLogonEnum"},
2332 {API_NetErrorLogRead, "NetErrorLogRead"},
2333 {API_I_NetPathType, "I_NetPathType"},
2334 {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"},
2335 {API_I_NetPathCompare, "I_NetPathCompare"},
2336 {API_I_NetNameValidate, "I_NetNameValidate"},
2337 {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"},
2338 {API_I_NetNameCompare, "I_NetNameCompare"},
2339 {API_NetAuditRead, "NetAuditRead"},
2340 {API_WPrintDestAdd, "WPrintDestAdd"},
2341 {API_WPrintDestSetInfo, "WPrintDestSetInfo"},
2342 {API_WPrintDestDel, "WPrintDestDel"},
2343 {API_NetUserValidate2, "NetUserValidate2"},
2344 {API_WPrintJobSetInfo, "WPrintJobSetInfo"},
2345 {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"},
2346 {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"},
2347 {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"},
2348 {API_TI_FTAbortVerify, "TI_FTAbortVerify"},
2349 {API_TI_FTGetInfo, "TI_FTGetInfo"},
2350 {API_TI_FTSetInfo, "TI_FTSetInfo"},
2351 {API_TI_FTLockDisk, "TI_FTLockDisk"},
2352 {API_TI_FTFixError, "TI_FTFixError"},
2353 {API_TI_FTAbortFix, "TI_FTAbortFix"},
2354 {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"},
2355 {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"},
2356 {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"},
2357 {API_NetAccessCheck, "NetAccessCheck"},
2358 {API_NetAlertRaise, "NetAlertRaise"},
2359 {API_NetAlertStart, "NetAlertStart"},
2360 {API_NetAlertStop, "NetAlertStop"},
2361 {API_NetAuditWrite, "NetAuditWrite"},
2362 {API_NetIRemoteAPI, "NetIRemoteAPI"},
2363 {API_NetServiceStatus, "NetServiceStatus"},
2364 {API_I_NetServerRegister, "I_NetServerRegister"},
2365 {API_I_NetServerDeregister, "I_NetServerDeregister"},
2366 {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"},
2367 {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"},
2368 {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"},
2369 {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"},
2370 {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"},
2371 {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"},
2372 {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2373 {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2374 {API_I_NetFileEntryMake, "I_NetFileEntryMake"},
2375 {API_I_NetFileEntryClear, "I_NetFileEntryClear"},
2376 {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"},
2377 {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"},
2378 {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"},
2379 {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"},
2380 {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"},
2381 {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"},
2382 {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"},
2383 {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"},
2384 {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"},
2385 {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"},
2386 {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"},
2387 {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"},
2388 {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"},
2389 {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"},
2390 {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"},
2391 {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"},
2392 {API_WIServerSetInfo, "WIServerSetInfo"},
2393 {API_WPrintDriverEnum, "WPrintDriverEnum"},
2394 {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"},
2395 {API_WPrintPortEnum, "WPrintPortEnum"},
2396 {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"},
2397 {API_WNetAccountUpdate, "WNetAccountUpdate"},
2398 {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"},
2399 {API_NetConfigSet, "NetConfigSet"},
2400 {API_WAccountsReplicate, "WAccountsReplicate"},
2401 {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"},
2402 {API_NetServerEnum3, "NetServerEnum3"},
2403 {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"},
2404 {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"},
2405 {API_NetAliasAdd, "NetAliasAdd"},
2406 {API_NetAliasDel, "NetAliasDel"},
2407 {API_NetAliasGetInfo, "NetAliasGetInfo"},
2408 {API_NetAliasSetInfo, "NetAliasSetInfo"},
2409 {API_NetAliasEnum, "NetAliasEnum"},
2410 {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"},
2411 {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"},
2412 {API_NetUserGetAppSel, "NetUserGetAppSel"},
2413 {API_NetUserSetAppSel, "NetUserSetAppSel"},
2414 {API_NetAppAdd, "NetAppAdd"},
2415 {API_NetAppDel, "NetAppDel"},
2416 {API_NetAppGetInfo, "NetAppGetInfo"},
2417 {API_NetAppSetInfo, "NetAppSetInfo"},
2418 {API_NetAppEnum, "NetAppEnum"},
2419 {API_NetUserDCDBInit, "NetUserDCDBInit"},
2420 {API_NetDASDAdd, "NetDASDAdd"},
2421 {API_NetDASDDel, "NetDASDDel"},
2422 {API_NetDASDGetInfo, "NetDASDGetInfo"},
2423 {API_NetDASDSetInfo, "NetDASDSetInfo"},
2424 {API_NetDASDEnum, "NetDASDEnum"},
2425 {API_NetDASDCheck, "NetDASDCheck"},
2426 {API_NetDASDCtl, "NetDASDCtl"},
2427 {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"},
2428 {API_NetUserPasswordSet3, "NetUserPasswordSet3"},
2429 {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"},
2430 {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"},
2431 {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"},
2432 {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"},
2433 {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"},
2434 {API_I_ShareAdd, "I_ShareAdd"},
2435 {API_I_AliasEnum, "I_AliasEnum"},
2436 {API_NetAccessApply, "NetAccessApply"},
2437 {API_WPrt16Query, "WPrt16Query"},
2438 {API_WPrt16Set, "WPrt16Set"},
2439 {API_NetUserDel100, "NetUserDel100"},
2440 {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"},
2441 {API_WRemoteTODSet, "WRemoteTODSet"},
2442 {API_WPrintJobMoveAll, "WPrintJobMoveAll"},
2443 {API_W16AppParmAdd, "W16AppParmAdd"},
2444 {API_W16AppParmDel, "W16AppParmDel"},
2445 {API_W16AppParmGet, "W16AppParmGet"},
2446 {API_W16AppParmSet, "W16AppParmSet"},
2447 {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"},
2448 {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"},
2449 {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"},
2450 {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"},
2451 {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"},
2452 {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"},
2453 {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"},
2454 {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"},
2455 {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"},
2456 {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"},
2457 {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"},
2458 {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"},
2459 {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"},
2460 {API_NetServerNameAdd, "NetServerNameAdd"},
2461 {API_NetServerNameDel, "NetServerNameDel"},
2462 {API_NetServerNameEnum, "NetServerNameEnum"},
2463 {API_I_WDASDEnum, "I_WDASDEnum"},
2464 {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"},
2465 {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"},
2470 dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2471 proto_tree *tree, struct smb_info *smb_info,
2472 const struct lanman_desc *lanman, gboolean has_ent_count,
2475 smb_transact_info_t *trp;
2476 const item_list_t *resp_data_list;
2477 int offset, start_offset;
2480 const item_t *resp_data;
2481 proto_item *data_item;
2482 proto_tree *data_tree;
2483 proto_item *entry_item;
2484 proto_tree *entry_tree;
2488 trp = smb_info->sip->extra_info;
2491 * Find the item table for the matching request's detail level.
2493 for (resp_data_list = lanman->resp_data_list;
2494 resp_data_list->level != -1; resp_data_list++) {
2495 if (resp_data_list->level == trp->info_level)
2498 resp_data = resp_data_list->item_list;
2501 if (has_ent_count) {
2503 * The data is a list of entries; create a protocol tree item
2507 label = lanman->resp_data_entry_list_label;
2510 if (lanman->ett_data_entry_list != NULL)
2511 ett = *lanman->ett_data_entry_list;
2513 ett = ett_lanman_unknown_entries;
2514 data_item = proto_tree_add_text(tree, tvb, offset, -1,
2516 data_tree = proto_item_add_subtree(data_item, ett);
2523 * Just leave it at the top level.
2529 if (trp->data_descrip == NULL) {
2531 * This could happen if we only dissected
2532 * part of the request to which this is a
2533 * reply, e.g. if the request was split
2534 * across TCP segments and we weren't doing
2535 * TCP desegmentation, or if we had a snapshot
2536 * length that was too short.
2538 * We can't dissect the data; just show it as raw data or,
2539 * if we've already created a top-level item, note that
2540 * no descriptor is available.
2542 if (has_ent_count) {
2543 if (data_item != NULL) {
2544 proto_item_append_text(data_item,
2545 " (No descriptor available)");
2548 proto_tree_add_text(data_tree, tvb, offset, -1,
2549 "Data (no descriptor available)");
2551 offset += tvb_length_remaining(tvb, offset);
2554 * If we have an entry count, show all the entries,
2555 * with each one having a protocol tree item.
2557 * Otherwise, we just show one returned item, with
2558 * no protocol tree item.
2562 for (i = 0; i < ent_count; i++) {
2563 start_offset = offset;
2564 if (has_ent_count &&
2565 lanman->resp_data_element_item != NULL) {
2567 * Create a protocol tree item for the
2571 (*lanman->resp_data_element_item)
2572 (tvb, data_tree, offset);
2573 entry_tree = proto_item_add_subtree(
2575 *lanman->ett_resp_data_element_item);
2578 * Just leave it at the current
2582 entry_tree = data_tree;
2585 offset = dissect_transact_data(tvb, offset,
2586 convert, pinfo, entry_tree,
2587 trp->data_descrip, resp_data, &aux_count);
2589 /* auxiliary data */
2590 if (trp->aux_data_descrip != NULL) {
2591 for (j = 0; j < aux_count; j++) {
2592 offset = dissect_transact_data(
2593 tvb, offset, convert,
2596 lanman->resp_aux_data, NULL);
2600 if (entry_item != NULL) {
2602 * Set the length of the protocol tree
2603 * item for the entry.
2605 proto_item_set_len(entry_item,
2606 offset - start_offset);
2611 if (data_item != NULL) {
2613 * Set the length of the protocol tree item
2616 proto_item_set_len(data_item, offset);
2621 dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2622 packet_info *pinfo, proto_tree *parent_tree)
2624 smb_info_t *smb_info = pinfo->private_data;
2625 smb_transact_info_t *trp = NULL;
2626 int offset = 0, start_offset;
2630 const struct lanman_desc *lanman;
2631 proto_item *item = NULL;
2632 proto_tree *tree = NULL;
2633 guint descriptor_len;
2634 const gchar *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2636 gboolean has_ent_count;
2637 guint16 ent_count, aux_count;
2639 proto_item *data_item;
2640 proto_tree *data_tree;
2642 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
2643 trp = smb_info->sip->extra_info;
2645 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2647 if (p_tvb == NULL) {
2649 * Requests must have parameters.
2653 pinfo->current_proto = "LANMAN";
2655 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2656 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2660 item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2661 pd_tvb, 0, -1, FALSE);
2662 tree = proto_item_add_subtree(item, ett_lanman);
2665 if (smb_info->request) { /* this is a request */
2667 cmd = tvb_get_letohs(p_tvb, offset);
2668 if (check_col(pinfo->cinfo, COL_INFO)) {
2669 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str(cmd, commands, "Unknown Command (%u)"));
2671 proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2676 return FALSE; /* cant dissect this request */
2680 * If we haven't already done so, save the function code in
2681 * the structure we were handed, so that it's available to
2682 * the code parsing the reply, and initialize the detail
2683 * level to -1, meaning "unknown".
2685 if (!pinfo->fd->flags.visited) {
2686 trp->lanman_cmd = cmd;
2687 trp->info_level = -1;
2688 trp->param_descrip=NULL;
2689 trp->data_descrip=NULL;
2690 trp->aux_data_descrip=NULL;
2693 /* parameter descriptor */
2694 descriptor_len = tvb_strsize(p_tvb, offset);
2695 proto_tree_add_item(tree, hf_param_desc, p_tvb, offset,
2696 descriptor_len, TRUE);
2697 param_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2698 if (!pinfo->fd->flags.visited) {
2700 * Save the parameter descriptor for future use.
2702 DISSECTOR_ASSERT(trp->param_descrip == NULL);
2703 trp->param_descrip = g_strdup(param_descrip);
2705 offset += descriptor_len;
2707 /* return descriptor */
2708 descriptor_len = tvb_strsize(p_tvb, offset);
2709 proto_tree_add_item(tree, hf_return_desc, p_tvb, offset,
2710 descriptor_len, TRUE);
2711 data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2712 if (!pinfo->fd->flags.visited) {
2714 * Save the return descriptor for future use.
2716 DISSECTOR_ASSERT(trp->data_descrip == NULL);
2717 trp->data_descrip = g_strdup(data_descrip);
2719 offset += descriptor_len;
2721 lanman = find_lanman(cmd);
2723 /* request parameters */
2724 start_offset = offset;
2725 offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2726 param_descrip, lanman->req, &has_data);
2728 /* auxiliary data descriptor */
2729 if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2731 * There are more parameters left, so the next
2732 * item is the auxiliary data descriptor.
2734 descriptor_len = tvb_strsize(p_tvb, offset);
2735 proto_tree_add_item(tree, hf_aux_data_desc, p_tvb, offset,
2736 descriptor_len, TRUE);
2737 aux_data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2738 if (!pinfo->fd->flags.visited) {
2740 * Save the auxiliary data descriptor for
2743 DISSECTOR_ASSERT(trp->aux_data_descrip == NULL);
2744 trp->aux_data_descrip =
2745 g_strdup(aux_data_descrip);
2747 offset += descriptor_len;
2750 /* reset offset, we now start dissecting the data area */
2752 if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2754 * There's a send buffer item in the descriptor
2755 * string, and the data count in the transaction
2756 * is non-zero, so there's data to dissect.
2759 if (lanman->req_data_item != NULL) {
2761 * Create a protocol tree item for the data.
2763 data_item = (*lanman->req_data_item)(d_tvb,
2764 pinfo, tree, offset);
2765 data_tree = proto_item_add_subtree(data_item,
2766 *lanman->ett_req_data);
2769 * Just leave it at the top level.
2776 offset = dissect_transact_data(d_tvb, offset, -1,
2777 pinfo, data_tree, data_descrip, lanman->req_data,
2778 &aux_count); /* XXX - what about strings? */
2780 /* auxiliary data */
2781 if (aux_data_descrip != NULL) {
2782 for (i = 0; i < aux_count; i++) {
2783 offset = dissect_transact_data(d_tvb,
2784 offset, -1, pinfo, data_tree,
2786 lanman->req_aux_data, NULL);
2790 if (data_item != NULL) {
2792 * Set the length of the protocol tree item
2795 proto_item_set_len(data_item, offset);
2800 * This is a response.
2801 * Have we seen the request to which it's a response?
2804 return FALSE; /* no - can't dissect it */
2806 /* ok we have seen this one before */
2808 /* if it looks like an interim response, update COL_INFO and return */
2809 if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
2810 && ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
2812 if (check_col(pinfo->cinfo, COL_INFO)) {
2813 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2814 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2816 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2821 if (check_col(pinfo->cinfo, COL_INFO)) {
2822 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2823 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2825 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2828 lanman = find_lanman(trp->lanman_cmd);
2830 /* response parameters */
2833 status = tvb_get_letohs(p_tvb, offset);
2834 proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2838 convert = tvb_get_letohs(p_tvb, offset);
2839 proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2842 if (trp->param_descrip == NULL) {
2844 * This could happen if we only dissected
2845 * part of the request to which this is a
2846 * reply, e.g. if the request was split
2847 * across TCP segments and we weren't doing
2848 * TCP desegmentation, or if we had a snapshot
2849 * length that was too short.
2851 * We can't dissect the parameters; just show them
2854 proto_tree_add_text(tree, p_tvb, offset, -1,
2855 "Parameters (no descriptor available)");
2858 * We don't know whether we have a receive buffer,
2859 * as we don't have the descriptor; just show what
2860 * bytes purport to be data.
2862 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2863 proto_tree_add_text(tree, d_tvb, 0, -1,
2864 "Data (no descriptor available)");
2867 /* rest of the parameters */
2868 offset = dissect_response_parameters(p_tvb, offset,
2869 pinfo, tree, trp->param_descrip, lanman->resp,
2870 &has_data, &has_ent_count, &ent_count);
2872 /* reset offset, we now start dissecting the data area */
2875 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2877 * Well, there are bytes that purport to
2878 * be data, at least.
2882 * There's a receive buffer item
2883 * in the descriptor string, so
2884 * dissect it as response data.
2886 dissect_response_data(d_tvb, pinfo,
2887 convert, tree, smb_info, lanman,
2888 has_ent_count, ent_count);
2891 * There's no receive buffer item,
2892 * but we do have data, so just
2893 * show what bytes are data.
2895 proto_tree_add_text(tree, d_tvb, 0, -1,
2896 "Data (no receive buffer)");
2906 proto_register_pipe_lanman(void)
2908 static hf_register_info hf[] = {
2909 { &hf_function_code,
2910 { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC,
2911 VALS(commands), 0, "LANMAN Function Code/Command", HFILL }},
2914 { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2915 NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2918 { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2919 NULL, 0, "LANMAN Return Descriptor", HFILL }},
2921 { &hf_aux_data_desc,
2922 { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2923 NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2926 { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2927 NULL, 0, "LANMAN Detail Level", HFILL }},
2930 { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2931 NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2934 { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2935 NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2937 { &hf_continuation_from,
2938 { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2939 NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2942 { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2943 VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2946 { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2947 NULL, 0, "LANMAN Convert", HFILL }},
2950 { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2951 NULL, 0, "LANMAN Number of Entries", HFILL }},
2954 { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2955 NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2958 { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2959 NULL, 0, "LANMAN Name of Share", HFILL }},
2962 { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2963 VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2965 { &hf_share_comment,
2966 { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2967 NULL, 0, "LANMAN Share Comment", HFILL }},
2969 { &hf_share_permissions,
2970 { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2971 NULL, 0, "LANMAN Permissions on share", HFILL }},
2973 { &hf_share_max_uses,
2974 { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2975 NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2977 { &hf_share_current_uses,
2978 { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2979 NULL, 0, "LANMAN Current connections to share", HFILL }},
2982 { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2983 NULL, 0, "LANMAN Share Path", HFILL }},
2985 { &hf_share_password,
2986 { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2987 NULL, 0, "LANMAN Share Password", HFILL }},
2990 { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2991 NULL, 0, "LANMAN Name of Server", HFILL }},
2994 { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2995 NULL, 0, "LANMAN Server Major Version", HFILL }},
2998 { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2999 NULL, 0, "LANMAN Server Minor Version", HFILL }},
3001 { &hf_server_comment,
3002 { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
3003 NULL, 0, "LANMAN Server Comment", HFILL }},
3006 { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
3007 NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
3010 { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, BASE_NONE,
3011 NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
3014 { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
3015 NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
3018 { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
3019 NULL, 0, "LANMAN Current hour", HFILL }},
3022 { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
3023 NULL, 0, "LANMAN Current minute", HFILL }},
3026 { "Second", "lanman.second", FT_UINT8, BASE_DEC,
3027 NULL, 0, "LANMAN Current second", HFILL }},
3030 { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
3031 NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
3034 { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
3035 NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
3038 { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
3039 NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
3042 { "Day", "lanman.day", FT_UINT8, BASE_DEC,
3043 NULL, 0, "LANMAN Current day", HFILL }},
3046 { "Month", "lanman.month", FT_UINT8, BASE_DEC,
3047 NULL, 0, "LANMAN Current month", HFILL }},
3050 { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3051 NULL, 0, "LANMAN Current year", HFILL }},
3054 { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3055 VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3057 { &hf_enumeration_domain,
3058 { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3059 NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3062 { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE,
3063 NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }},
3065 { &hf_computer_name,
3066 { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3067 NULL, 0, "LANMAN Computer Name", HFILL }},
3070 { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3071 NULL, 0, "LANMAN User Name", HFILL }},
3074 { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3075 NULL, 0, "LANMAN Group Name", HFILL }},
3077 { &hf_workstation_domain,
3078 { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3079 NULL, 0, "LANMAN Workstation Domain", HFILL }},
3081 { &hf_workstation_major,
3082 { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3083 NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3085 { &hf_workstation_minor,
3086 { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3087 NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3090 { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3091 NULL, 0, "LANMAN Logon Domain", HFILL }},
3093 { &hf_other_domains,
3094 { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3095 NULL, 0, "LANMAN Other Domains", HFILL }},
3098 { "Password", "lanman.password", FT_STRING, BASE_NONE,
3099 NULL, 0, "LANMAN Password", HFILL }},
3101 { &hf_workstation_name,
3102 { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3103 NULL, 0, "LANMAN Workstation Name", HFILL }},
3106 { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3107 NULL, 0, "LANMAN UStruct Length", HFILL }},
3110 { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3111 VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3113 { &hf_privilege_level,
3114 { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3115 VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3117 { &hf_operator_privileges,
3118 { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3119 VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3122 { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3123 NULL, 0, "LANMAN Number of Logons", HFILL }},
3126 { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3127 NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3130 { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, BASE_NONE,
3131 NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3134 { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, BASE_NONE,
3135 NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3138 { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3139 NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3142 { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3143 NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3146 { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3147 NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3149 { &hf_password_can_change,
3150 { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, BASE_NONE,
3151 NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3153 { &hf_password_must_change,
3154 { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, BASE_NONE,
3155 NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3158 { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3159 NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3162 { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3163 VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3166 { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3167 NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3170 { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3171 NULL, 0, "LANMAN Comment", HFILL }},
3174 { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3175 NULL, 0, "LANMAN User Comment", HFILL }},
3178 { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3179 NULL, 0, "LANMAN Full Name", HFILL }},
3182 { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3183 NULL, 0, "LANMAN Home Directory", HFILL }},
3186 { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3187 NULL, 0, "LANMAN Parameters", HFILL }},
3190 { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3191 NULL, 0, "LANMAN Logon Server", HFILL }},
3193 /* XXX - we should have a value_string table for this */
3195 { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC,
3196 VALS(ms_country_codes), 0, "LANMAN Country Code", HFILL }},
3199 { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3200 NULL, 0, "LANMAN Workstations", HFILL }},
3203 { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3204 NULL, 0, "LANMAN Max Storage", HFILL }},
3206 { &hf_units_per_week,
3207 { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3208 NULL, 0, "LANMAN Units Per Week", HFILL }},
3211 { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3212 NULL, 0, "LANMAN Logon Hours", HFILL }},
3214 /* XXX - we should have a value_string table for this */
3216 { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3217 NULL, 0, "LANMAN Code Page", HFILL }},
3220 { "New Password", "lanman.new_password", FT_BYTES, BASE_HEX,
3221 NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3224 { "Old Password", "lanman.old_password", FT_BYTES, BASE_HEX,
3225 NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3228 { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3229 NULL, 0, "LANMAN Reserved", HFILL }},
3232 static gint *ett[] = {
3234 &ett_lanman_unknown_entries,
3235 &ett_lanman_unknown_entry,
3236 &ett_lanman_servers,
3243 proto_smb_lanman = proto_register_protocol(
3244 "Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3245 proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3246 proto_register_subtree_array(ett, array_length(ett));
3249 static heur_dissector_list_t smb_transact_heur_subdissector_list;
3251 static GHashTable *dcerpc_fragment_table = NULL;
3252 static GHashTable *dcerpc_reassembled_table = NULL;
3255 smb_dcerpc_reassembly_init(void)
3257 fragment_table_init(&dcerpc_fragment_table);
3258 reassembled_table_init(&dcerpc_reassembled_table);
3262 dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3263 proto_tree *tree, guint32 fid)
3265 smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
3267 gboolean save_fragmented;
3270 fragment_data *fd_head;
3272 proto_item *frag_tree_item;
3274 pinfo->dcetransportsalt = fid;
3277 * Offer desegmentation service to DCERPC if we have all the
3278 * data. Otherwise, reassembly is (probably) impossible.
3280 pinfo->can_desegment=0;
3281 pinfo->desegment_offset = 0;
3282 pinfo->desegment_len = 0;
3283 reported_len = tvb_reported_length(d_tvb);
3284 if(smb_dcerpc_reassembly && tvb_bytes_exist(d_tvb, 0, reported_len)){
3285 pinfo->can_desegment=2;
3288 save_fragmented = pinfo->fragmented;
3291 /* if we are not offering desegmentation, just try the heuristics
3294 if(!pinfo->can_desegment){
3295 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3296 goto clean_up_and_exit;
3300 /* below this line, we know we are doing reassembly */
3303 * We have to keep track of reassemblies by FID, because
3304 * we could have more than one pipe operation in a frame
3305 * with NetBIOS-over-TCP.
3307 * We also have to keep track of them by direction, as
3308 * we might have reassemblies in progress in both directions.
3310 * We do that by combining the FID and the direction and
3311 * using that as the reassembly ID.
3313 * The direction is indicated by the SMB request/reply flag - data
3314 * from client to server is carried in requests, data from server
3315 * to client is carried in replies.
3317 * We know that the FID is only 16 bits long, so we put the
3318 * direction in bit 17.
3321 if (smb_priv->request)
3322 hash_key |= 0x10000;
3324 /* this is a new packet, see if we are already reassembling this
3325 pdu and if not, check if the dissector wants us
3328 if(!pinfo->fd->flags.visited){
3330 * This is the first pass.
3332 * Check if we are already reassembling this PDU or not;
3333 * we check for an in-progress reassembly for this FID
3334 * in this direction, by searching for its reassembly
3337 fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
3339 /* No reassembly, so this is a new pdu. check if the
3340 dissector wants us to reassemble it or if we
3341 already got the full pdu in this tvb.
3345 * First, just check if it looks like dcerpc or not.
3347 * XXX - this assumes that the dissector is idempotent,
3348 * as it's doing a "trial" dissection building no
3349 * tree; that's not necessarily the case.
3351 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, NULL);
3353 /* no this didnt look like something we know */
3355 goto clean_up_and_exit;
3358 /* did the subdissector want us to reassemble any
3361 if(pinfo->desegment_len){
3362 fragment_add_check(d_tvb, 0, pinfo, fid,
3363 dcerpc_fragment_table,
3364 dcerpc_reassembled_table,
3365 0, reported_len, TRUE);
3366 fragment_set_tot_len(pinfo, fid,
3367 dcerpc_fragment_table,
3368 pinfo->desegment_len+reported_len);
3369 goto clean_up_and_exit;
3372 /* guess we have the full pdu in this tvb then,
3373 just dissect it and continue.
3375 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3376 goto clean_up_and_exit;
3379 /* OK, we're already doing a reassembly for this FID.
3380 skip to last segment in the existing reassembly structure
3381 and add this fragment there
3383 XXX we might add code here to use any offset values
3384 we might pick up from the Read/Write calls instead of
3385 assuming we always get them in the correct order
3387 while(fd_head->next){
3388 fd_head=fd_head->next;
3390 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
3391 dcerpc_fragment_table, dcerpc_reassembled_table,
3392 fd_head->offset+fd_head->len,
3393 reported_len, TRUE);
3395 /* if we completed reassembly */
3397 new_tvb = tvb_new_real_data(fd_head->data,
3398 fd_head->datalen, fd_head->datalen);
3399 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3400 add_new_data_source(pinfo, new_tvb,
3402 pinfo->fragmented=FALSE;
3406 /* list what segments we have */
3407 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3408 tree, pinfo, d_tvb, &frag_tree_item);
3410 /* dissect the full PDU */
3411 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3413 goto clean_up_and_exit;
3417 * This is not the first pass; see if it's in the table of
3418 * reassembled packets.
3420 * XXX - we know that several of the arguments aren't going to
3421 * be used, so we pass bogus variables. Can we clean this
3422 * up so that we don't have to distinguish between the first
3423 * pass and subsequent passes?
3425 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
3426 dcerpc_reassembled_table, 0, 0, TRUE);
3428 /* we didnt find it, try any of the heuristic dissectors
3431 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3432 goto clean_up_and_exit;
3434 if(!fd_head->flags&FD_DEFRAGMENTED){
3435 /* we dont have a fully reassembled frame */
3436 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3437 goto clean_up_and_exit;
3440 /* it is reassembled but it was reassembled in a different frame */
3441 if(pinfo->fd->num!=fd_head->reassembled_in){
3442 proto_tree_add_uint(parent_tree, hf_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3443 goto clean_up_and_exit;
3447 /* display the reassembled pdu */
3448 new_tvb = tvb_new_real_data(fd_head->data,
3449 fd_head->datalen, fd_head->datalen);
3450 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3451 add_new_data_source(pinfo, new_tvb,
3453 pinfo->fragmented=FALSE;
3457 /* list what segments we have */
3458 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3459 tree, pinfo, d_tvb, &frag_tree_item);
3461 /* dissect the full PDU */
3462 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3467 /* clear out the variables */
3468 pinfo->private_data = smb_priv;
3469 pinfo->can_desegment=0;
3470 pinfo->desegment_offset = 0;
3471 pinfo->desegment_len = 0;
3474 call_dissector(data_handle, d_tvb, pinfo, parent_tree);
3476 pinfo->fragmented = save_fragmented;
3481 proto_register_pipe_dcerpc(void)
3483 register_heur_dissector_list("smb_transact", &smb_transact_heur_subdissector_list);
3484 register_init_routine(smb_dcerpc_reassembly_init);
3487 #define CALL_NAMED_PIPE 0x54
3488 #define WAIT_NAMED_PIPE 0x53
3489 #define PEEK_NAMED_PIPE 0x23
3490 #define Q_NM_P_HAND_STATE 0x21
3491 #define SET_NM_P_HAND_STATE 0x01
3492 #define Q_NM_PIPE_INFO 0x22
3493 #define TRANSACT_NM_PIPE 0x26
3494 #define RAW_READ_NM_PIPE 0x11
3495 #define RAW_WRITE_NM_PIPE 0x31
3497 static const value_string functions[] = {
3498 {CALL_NAMED_PIPE, "CallNamedPipe"},
3499 {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3500 {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3501 {Q_NM_P_HAND_STATE, "QNmPHandState"},
3502 {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3503 {Q_NM_PIPE_INFO, "QNmPipeInfo"},
3504 {TRANSACT_NM_PIPE, "TransactNmPipe"},
3505 {RAW_READ_NM_PIPE, "RawReadNmPipe"},
3506 {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3510 static const value_string pipe_status[] = {
3511 {1, "Disconnected by server"},
3513 {3, "Connection to server is OK"},
3514 {4, "Server end of pipe is closed"},
3518 #define PIPE_LANMAN 1
3519 #define PIPE_DCERPC 2
3521 /* decode the SMB pipe protocol
3523 pipe is the name of the pipe, e.g. LANMAN
3524 smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3527 smb_info->trans_subcmd gives us which pipe this response is for
3530 dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3531 tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3532 packet_info *pinfo, proto_tree *tree)
3534 smb_info_t *smb_info;
3535 smb_transact_info_t *tri;
3537 proto_item *pipe_item = NULL;
3538 proto_tree *pipe_tree = NULL;
3545 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3547 pinfo->current_proto = "SMB Pipe";
3549 smb_info = pinfo->private_data;
3554 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
3555 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3557 if (check_col(pinfo->cinfo, COL_INFO)) {
3558 col_set_str(pinfo->cinfo, COL_INFO,
3559 smb_info->request ? "Request" : "Response");
3562 if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI)
3563 tri = smb_info->sip->extra_info;
3568 * Set up a subtree for the pipe protocol. (It might not contain
3572 sp_len = tvb_length(sp_tvb);
3576 pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3577 sp_tvb, 0, sp_len, FALSE);
3578 pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3583 * Do we have any setup words at all?
3585 if (s_tvb != NULL && tvb_length(s_tvb) != 0) {
3587 * Yes. The first of them is the function.
3589 function = tvb_get_letohs(s_tvb, offset);
3590 proto_tree_add_uint(pipe_tree, hf_pipe_function, s_tvb,
3591 offset, 2, function);
3593 if (check_col(pinfo->cinfo, COL_INFO)) {
3594 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3595 val_to_str(function, functions, "Unknown function (0x%04x)"),
3596 smb_info->request ? "Request" : "Response");
3599 tri->function = function;
3602 * The second of them depends on the function.
3606 case CALL_NAMED_PIPE:
3607 case WAIT_NAMED_PIPE:
3611 proto_tree_add_item(pipe_tree, hf_pipe_priority, s_tvb,
3615 case PEEK_NAMED_PIPE:
3616 case Q_NM_P_HAND_STATE:
3617 case SET_NM_P_HAND_STATE:
3618 case Q_NM_PIPE_INFO:
3619 case TRANSACT_NM_PIPE:
3620 case RAW_READ_NM_PIPE:
3621 case RAW_WRITE_NM_PIPE:
3625 fid = tvb_get_letohs(s_tvb, 2);
3626 add_fid(s_tvb, pinfo, pipe_tree, offset, 2, (guint16) fid);
3633 * It's something unknown.
3634 * XXX - put it into the tree?
3641 * This is either a response or a pipe transaction with
3642 * no setup information.
3644 * In the former case, we can get that information from
3645 * the matching request, if we saw it.
3647 * In the latter case, there is no function or FID.
3649 if (tri != NULL && tri->function != -1) {
3650 function = tri->function;
3651 proto_tree_add_uint(pipe_tree, hf_pipe_function, NULL,
3653 if (check_col(pinfo->cinfo, COL_INFO)) {
3654 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3655 val_to_str(function, functions, "Unknown function (0x%04x)"),
3656 smb_info->request ? "Request" : "Response");
3660 add_fid(NULL, pinfo, pipe_tree, 0, 0, (guint16) fid);
3668 * XXX - put the byte count and the pipe name into the tree as well;
3669 * that requires us to fetch a possibly-Unicode string.
3672 if(smb_info->request){
3673 if(strncmp(pipe,"LANMAN",6) == 0){
3674 trans_subcmd=PIPE_LANMAN;
3676 /* assume it is DCERPC */
3677 trans_subcmd=PIPE_DCERPC;
3680 if (!pinfo->fd->flags.visited)
3681 tri->trans_subcmd = trans_subcmd;
3684 trans_subcmd = tri->trans_subcmd;
3692 * We don't know what type of pipe transaction this
3693 * was, so indicate that we didn't dissect it.
3700 case CALL_NAMED_PIPE:
3701 case TRANSACT_NM_PIPE:
3702 switch(trans_subcmd){
3705 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3711 * Only dissect this if we know the FID.
3716 return dissect_pipe_dcerpc(d_tvb, pinfo, tree,
3725 * We don't know the function; we dissect only LANMAN
3726 * pipe messages, not RPC pipe messages, in that case.
3728 switch(trans_subcmd){
3730 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3736 case WAIT_NAMED_PIPE:
3739 case PEEK_NAMED_PIPE:
3741 * Request contains no parameters or data.
3743 if (!smb_info->request) {
3747 proto_tree_add_item(pipe_tree, hf_pipe_peek_available,
3748 p_tvb, offset, 2, TRUE);
3750 proto_tree_add_item(pipe_tree, hf_pipe_peek_remaining,
3751 p_tvb, offset, 2, TRUE);
3753 proto_tree_add_item(pipe_tree, hf_pipe_peek_status,
3754 p_tvb, offset, 2, TRUE);
3759 case Q_NM_P_HAND_STATE:
3761 * Request contains no parameters or data.
3763 if (!smb_info->request) {
3766 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, FALSE);
3770 case SET_NM_P_HAND_STATE:
3772 * Response contains no parameters or data.
3774 if (smb_info->request) {
3777 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, TRUE);
3781 case Q_NM_PIPE_INFO:
3783 if (smb_info->request) {
3788 * Request contains an information level.
3790 info_level = tvb_get_letohs(p_tvb, offset);
3791 proto_tree_add_uint(pipe_tree, hf_pipe_getinfo_info_level,
3792 p_tvb, offset, 2, info_level);
3794 if (!pinfo->fd->flags.visited)
3795 tri->info_level = info_level;
3797 guint8 pipe_namelen;
3802 switch (tri->info_level) {
3805 proto_tree_add_item(pipe_tree,
3806 hf_pipe_getinfo_output_buffer_size,
3807 d_tvb, offset, 2, TRUE);
3809 proto_tree_add_item(pipe_tree,
3810 hf_pipe_getinfo_input_buffer_size,
3811 d_tvb, offset, 2, TRUE);
3813 proto_tree_add_item(pipe_tree,
3814 hf_pipe_getinfo_maximum_instances,
3815 d_tvb, offset, 1, TRUE);
3817 proto_tree_add_item(pipe_tree,
3818 hf_pipe_getinfo_current_instances,
3819 d_tvb, offset, 1, TRUE);
3821 pipe_namelen = tvb_get_guint8(d_tvb, offset);
3822 proto_tree_add_uint(pipe_tree,
3823 hf_pipe_getinfo_pipe_name_length,
3824 d_tvb, offset, 1, pipe_namelen);
3826 /* XXX - can this be Unicode? */
3827 proto_tree_add_item(pipe_tree,
3828 hf_pipe_getinfo_pipe_name,
3829 d_tvb, offset, pipe_namelen, TRUE);
3835 case RAW_READ_NM_PIPE:
3837 * Request contains no parameters or data.
3839 if (!smb_info->request) {
3843 offset = dissect_file_data(d_tvb, pipe_tree, 0,
3844 (guint16) tvb_reported_length(d_tvb),
3845 (guint16) tvb_reported_length(d_tvb));
3849 case RAW_WRITE_NM_PIPE:
3851 if (smb_info->request) {
3855 offset = dissect_file_data(d_tvb, pipe_tree,
3856 offset, (guint16) tvb_reported_length(d_tvb),
3857 (guint16) tvb_reported_length(d_tvb));
3861 proto_tree_add_item(pipe_tree,
3862 hf_pipe_write_raw_bytes_written,
3863 p_tvb, offset, 2, TRUE);
3872 proto_register_smb_pipe(void)
3874 static hf_register_info hf[] = {
3875 { &hf_pipe_function,
3876 { "Function", "pipe.function", FT_UINT16, BASE_HEX,
3877 VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3878 { &hf_pipe_priority,
3879 { "Priority", "pipe.priority", FT_UINT16, BASE_DEC,
3880 NULL, 0, "SMB Pipe Priority", HFILL }},
3881 { &hf_pipe_peek_available,
3882 { "Available Bytes", "pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3883 NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3884 { &hf_pipe_peek_remaining,
3885 { "Bytes Remaining", "pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3886 NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3887 { &hf_pipe_peek_status,
3888 { "Pipe Status", "pipe.peek.status", FT_UINT16, BASE_DEC,
3889 VALS(pipe_status), 0, "Pipe status", HFILL }},
3890 { &hf_pipe_getinfo_info_level,
3891 { "Information Level", "pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3892 NULL, 0, "Information level of information to return", HFILL }},
3893 { &hf_pipe_getinfo_output_buffer_size,
3894 { "Output Buffer Size", "pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3895 NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3896 { &hf_pipe_getinfo_input_buffer_size,
3897 { "Input Buffer Size", "pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3898 NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3899 { &hf_pipe_getinfo_maximum_instances,
3900 { "Maximum Instances", "pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3901 NULL, 0, "Maximum allowed number of instances", HFILL }},
3902 { &hf_pipe_getinfo_current_instances,
3903 { "Current Instances", "pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3904 NULL, 0, "Current number of instances", HFILL }},
3905 { &hf_pipe_getinfo_pipe_name_length,
3906 { "Pipe Name Length", "pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3907 NULL, 0, "Length of pipe name", HFILL }},
3908 { &hf_pipe_getinfo_pipe_name,
3909 { "Pipe Name", "pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3910 NULL, 0, "Name of pipe", HFILL }},
3911 { &hf_pipe_write_raw_bytes_written,
3912 { "Bytes Written", "pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3913 NULL, 0, "Number of bytes written to the pipe", HFILL }},
3914 { &hf_pipe_fragment_overlap,
3915 { "Fragment overlap", "pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3916 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3917 { &hf_pipe_fragment_overlap_conflict,
3918 { "Conflicting data in fragment overlap", "pipe.fragment.overlap.conflict", FT_BOOLEAN,
3919 BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3920 { &hf_pipe_fragment_multiple_tails,
3921 { "Multiple tail fragments found", "pipe.fragment.multipletails", FT_BOOLEAN,
3922 BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3923 { &hf_pipe_fragment_too_long_fragment,
3924 { "Fragment too long", "pipe.fragment.toolongfragment", FT_BOOLEAN,
3925 BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3926 { &hf_pipe_fragment_error,
3927 { "Defragmentation error", "pipe.fragment.error", FT_FRAMENUM,
3928 BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3929 { &hf_pipe_fragment,
3930 { "Fragment", "pipe.fragment", FT_FRAMENUM,
3931 BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3932 { &hf_pipe_fragments,
3933 { "Fragments", "pipe.fragments", FT_NONE,
3934 BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3935 { &hf_pipe_reassembled_in,
3936 { "This PDU is reassembled in", "pipe.reassembled_in", FT_FRAMENUM,
3937 BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3939 static gint *ett[] = {
3941 &ett_smb_pipe_fragment,
3942 &ett_smb_pipe_fragments,
3945 proto_smb_pipe = proto_register_protocol(
3946 "SMB Pipe Protocol", "SMB Pipe", "pipe");
3948 proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3949 proto_register_subtree_array(ett, array_length(ett));
3953 proto_reg_handoff_smb_pipe(void)
3955 data_handle = find_dissector("data");