2 XXX Fixme : shouldn't 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 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * Copied from packet-pop.c
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
42 #include <epan/packet.h>
43 #include <epan/dissectors/packet-smb.h>
44 #include "packet-smb-pipe.h"
45 #include "packet-smb-browse.h"
46 #include "packet-smb-common.h"
47 #include "packet-windows-common.h"
48 #include "packet-dcerpc.h"
49 #include <epan/reassemble.h>
51 static int proto_smb_pipe = -1;
52 static int hf_pipe_function = -1;
53 static int hf_pipe_priority = -1;
54 static int hf_pipe_peek_available = -1;
55 static int hf_pipe_peek_remaining = -1;
56 static int hf_pipe_peek_status = -1;
57 static int hf_pipe_getinfo_info_level = -1;
58 static int hf_pipe_getinfo_output_buffer_size = -1;
59 static int hf_pipe_getinfo_input_buffer_size = -1;
60 static int hf_pipe_getinfo_maximum_instances = -1;
61 static int hf_pipe_getinfo_current_instances = -1;
62 static int hf_pipe_getinfo_pipe_name_length = -1;
63 static int hf_pipe_getinfo_pipe_name = -1;
64 static int hf_pipe_write_raw_bytes_written = -1;
65 static int hf_pipe_fragments = -1;
66 static int hf_pipe_fragment = -1;
67 static int hf_pipe_fragment_overlap = -1;
68 static int hf_pipe_fragment_overlap_conflict = -1;
69 static int hf_pipe_fragment_multiple_tails = -1;
70 static int hf_pipe_fragment_too_long_fragment = -1;
71 static int hf_pipe_fragment_error = -1;
72 static int hf_pipe_fragment_count = -1;
73 static int hf_pipe_reassembled_in = -1;
74 static int hf_pipe_reassembled_length = -1;
76 static gint ett_smb_pipe = -1;
77 static gint ett_smb_pipe_fragment = -1;
78 static gint ett_smb_pipe_fragments = -1;
80 static const fragment_items smb_pipe_frag_items = {
81 &ett_smb_pipe_fragment,
82 &ett_smb_pipe_fragments,
85 &hf_pipe_fragment_overlap,
86 &hf_pipe_fragment_overlap_conflict,
87 &hf_pipe_fragment_multiple_tails,
88 &hf_pipe_fragment_too_long_fragment,
89 &hf_pipe_fragment_error,
90 &hf_pipe_fragment_count,
92 &hf_pipe_reassembled_length,
96 static int proto_smb_lanman = -1;
97 static int hf_function_code = -1;
98 static int hf_param_desc = -1;
99 static int hf_return_desc = -1;
100 static int hf_aux_data_desc = -1;
101 static int hf_detail_level = -1;
102 static int hf_recv_buf_len = -1;
103 static int hf_send_buf_len = -1;
104 static int hf_continuation_from = -1;
105 static int hf_status = -1;
106 static int hf_convert = -1;
107 static int hf_ecount = -1;
108 static int hf_acount = -1;
109 static int hf_share_name = -1;
110 static int hf_share_type = -1;
111 static int hf_share_comment = -1;
112 static int hf_share_permissions = -1;
113 static int hf_share_max_uses = -1;
114 static int hf_share_current_uses = -1;
115 static int hf_share_path = -1;
116 static int hf_share_password = -1;
117 static int hf_server_name = -1;
118 static int hf_server_major = -1;
119 static int hf_server_minor = -1;
120 static int hf_server_comment = -1;
121 static int hf_abytes = -1;
122 static int hf_current_time = -1;
123 static int hf_msecs = -1;
124 static int hf_hour = -1;
125 static int hf_minute = -1;
126 static int hf_second = -1;
127 static int hf_hundredths = -1;
128 static int hf_tzoffset = -1;
129 static int hf_timeinterval = -1;
130 static int hf_day = -1;
131 static int hf_month = -1;
132 static int hf_year = -1;
133 static int hf_weekday = -1;
134 static int hf_enumeration_domain = -1;
135 static int hf_last_entry = -1;
136 static int hf_computer_name = -1;
137 static int hf_user_name = -1;
138 static int hf_group_name = -1;
139 static int hf_workstation_domain = -1;
140 static int hf_workstation_major = -1;
141 static int hf_workstation_minor = -1;
142 static int hf_logon_domain = -1;
143 static int hf_other_domains = -1;
144 static int hf_password = -1;
145 static int hf_workstation_name = -1;
146 static int hf_ustruct_size = -1;
147 static int hf_logon_code = -1;
148 static int hf_privilege_level = -1;
149 static int hf_operator_privileges = -1;
150 static int hf_num_logons = -1;
151 static int hf_bad_pw_count = -1;
152 static int hf_last_logon = -1;
153 static int hf_last_logoff = -1;
154 static int hf_logoff_time = -1;
155 static int hf_kickoff_time = -1;
156 static int hf_password_age = -1;
157 static int hf_password_can_change = -1;
158 static int hf_password_must_change = -1;
159 static int hf_script_path = -1;
160 static int hf_logoff_code = -1;
161 static int hf_duration = -1;
162 static int hf_comment = -1;
163 static int hf_user_comment = -1;
164 static int hf_full_name = -1;
165 static int hf_homedir = -1;
166 static int hf_parameters = -1;
167 static int hf_logon_server = -1;
168 static int hf_country_code = -1;
169 static int hf_workstations = -1;
170 static int hf_max_storage = -1;
171 static int hf_units_per_week = -1;
172 static int hf_logon_hours = -1;
173 static int hf_code_page = -1;
174 static int hf_new_password = -1;
175 static int hf_old_password = -1;
176 static int hf_reserved = -1;
178 static gint ett_lanman = -1;
179 static gint ett_lanman_unknown_entries = -1;
180 static gint ett_lanman_unknown_entry = -1;
181 static gint ett_lanman_shares = -1;
182 static gint ett_lanman_share = -1;
183 static gint ett_lanman_groups = -1;
184 static gint ett_lanman_servers = -1;
185 static gint ett_lanman_server = -1;
187 static dissector_handle_t data_handle;
192 * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
194 * among other documents.
197 static const value_string status_vals[] = {
199 {5, "User has insufficient privilege"},
200 {65, "Network access is denied"},
201 {86, "The specified password is invalid"},
202 {SMBE_moredata, "Additional data is available"},
203 {2114, "Service is not running on the remote computer"},
204 {2123, "Supplied buffer is too small"},
205 {2141, "Server is not configured for transactions (IPC$ not shared)"},
206 {2212, "An error occurred while loading or running the logon script"},
207 {2214, "The logon was not validated by any server"},
208 {2217, "The logon server is running an older software version"},
209 {2221, "The user name was not found"},
210 {2226, "Operation not permitted on Backup Domain Controller"},
211 {2240, "The user is not allowed to logon from this computer"},
212 {2241, "The user is not allowed to logon at this time"},
213 {2242, "The user password has expired"},
214 {2243, "The password cannot be changed"},
215 {2246, "The password is too short"},
219 static const value_string privilege_vals[] = {
222 {2, "Administrator"},
226 static const value_string op_privilege_vals[] = {
227 {0, "Print operator"},
228 {1, "Communications operator"},
229 {2, "Server operator"},
230 {3, "Accounts operator"},
234 static const value_string weekday_vals[] = {
246 add_word_param(tvbuff_t *tvb, int offset, int count _U_,
247 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
252 proto_tree_add_item(tree, hf_index, tvb, offset, 2, TRUE);
254 WParam = tvb_get_letohs(tvb, offset);
255 proto_tree_add_text(tree, tvb, offset, 2,
256 "Word Param: %u (0x%04X)", WParam, WParam);
263 add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
264 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
269 proto_tree_add_item(tree, hf_index, tvb, offset, 4, TRUE);
271 LParam = tvb_get_letohl(tvb, offset);
272 proto_tree_add_text(tree, tvb, offset, 4,
273 "Doubleword Param: %u (0x%08X)", LParam, LParam);
280 add_byte_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
281 proto_tree *tree, int convert _U_, int hf_index)
284 header_field_info *hfinfo;
286 if (hf_index != -1) {
287 hfinfo = proto_registrar_get_nth(hf_index);
288 if (hfinfo && count != 1 &&
289 (hfinfo->type == FT_INT8 || hfinfo->type == FT_UINT8)
291 THROW(ReportedBoundsError);
293 proto_tree_add_item(tree, hf_index, tvb, offset, count, TRUE);
296 BParam = tvb_get_guint8(tvb, offset);
297 proto_tree_add_text(tree, tvb, offset, count,
298 "Byte Param: %u (0x%02X)",
301 proto_tree_add_text(tree, tvb, offset, count,
303 tvb_bytes_to_str(tvb, offset, count));
311 add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
312 proto_tree *tree _U_, int convert _U_, int hf_index _U_)
315 * This is for parameters that have descriptor entries but that
316 * are, in practice, just padding.
323 add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
324 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
326 if (hf_index != -1) {
327 proto_tree_add_text(tree, tvb, offset, 0,
329 proto_registrar_get_name(hf_index));
331 proto_tree_add_text(tree, tvb, offset, 0,
332 "String Param (Null pointer)");
337 add_string_param(tvbuff_t *tvb, int offset, int count _U_,
338 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
342 string_len = tvb_strsize(tvb, offset);
343 if (hf_index != -1) {
344 proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
347 proto_tree_add_text(tree, tvb, offset, string_len,
349 tvb_format_text(tvb, offset, string_len));
351 offset += string_len;
356 get_stringz_pointer_value(tvbuff_t *tvb, int offset, int convert, int *cptrp,
362 /* pointer to string */
363 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
367 if (tvb_offset_exists(tvb, cptr) &&
368 (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
369 string_len++; /* include the terminating '\0' */
371 return tvb_format_text(tvb, cptr, string_len - 1);
377 add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
378 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
384 string = get_stringz_pointer_value(tvb, offset, convert, &cptr,
389 if (string != NULL) {
390 if (hf_index != -1) {
391 proto_tree_add_item(tree, hf_index, tvb, cptr,
394 proto_tree_add_text(tree, tvb, cptr, string_len,
395 "String Param: %s", string);
398 if (hf_index != -1) {
399 proto_tree_add_text(tree, tvb, 0, 0,
400 "%s: <String goes past end of frame>",
401 proto_registrar_get_name(hf_index));
403 proto_tree_add_text(tree, tvb, 0, 0,
404 "String Param: <String goes past end of frame>");
412 add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
413 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
417 /* pointer to byte array */
418 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
422 if (tvb_bytes_exist(tvb, cptr, count)) {
423 if (hf_index != -1) {
424 proto_tree_add_item(tree, hf_index, tvb, cptr,
427 proto_tree_add_text(tree, tvb, cptr, count,
429 tvb_bytes_to_str(tvb, cptr, count));
432 if (hf_index != -1) {
433 proto_tree_add_text(tree, tvb, 0, 0,
434 "%s: <Bytes go past end of frame>",
435 proto_registrar_get_name(hf_index));
437 proto_tree_add_text(tree, tvb, 0, 0,
438 "Byte Param: <Bytes goes past end of frame>");
446 add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
447 proto_tree *tree, int convert _U_, int hf_index)
449 struct smb_info *smb_info = pinfo->private_data;
450 smb_transact_info_t *trp = NULL;
453 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
454 trp = smb_info->sip->extra_info;
456 level = tvb_get_letohs(tvb, offset);
457 if (!pinfo->fd->flags.visited)
459 trp->info_level = level; /* remember this for the response */
461 proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
467 add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
468 proto_tree *tree, int convert _U_, int hf_index)
472 WParam = tvb_get_letohs(tvb, offset);
473 if (WParam == 0xffff) { /* -1 */
474 proto_tree_add_uint_format(tree, hf_index, tvb,
477 proto_registrar_get_name(hf_index));
479 proto_tree_add_uint(tree, hf_index, tvb,
487 add_server_type(tvbuff_t *tvb, int offset, int count _U_,
488 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
490 offset = dissect_smb_server_type_flags(
491 tvb, offset, pinfo, tree, NULL, FALSE);
496 add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
497 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
499 offset = dissect_smb_server_type_flags(
500 tvb, offset, pinfo, tree, NULL, TRUE);
505 add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
506 proto_tree *tree, int convert _U_, int hf_index)
510 nstime.secs = tvb_get_letohl(tvb, offset);
512 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
513 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
514 time_secs_to_str( (gint32) nstime.secs));
520 * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but-
521 * it's-local-time-not-UTC time.
524 add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
525 const char *absent_name)
530 nstime.secs = tvb_get_letohl(tvb, offset);
533 * Sigh. Sometimes it appears that -1 means "unknown", and
534 * sometimes it appears that 0 means "unknown", for the last
537 if (nstime.secs == -1 || nstime.secs == 0) {
538 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
539 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
543 * Run it through "gmtime()" to break it down, and then
544 * run it through "mktime()" to put it back together
547 tmp = gmtime(&nstime.secs);
548 tmp->tm_isdst = -1; /* we don't know if it's DST or not */
549 nstime.secs = mktime(tmp);
550 proto_tree_add_time(tree, hf_index, tvb, offset, 4,
558 add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
559 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
561 return add_abstime_common(tvb, offset, tree, hf_index, "Never");
565 add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
566 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
568 return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
572 add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
573 proto_tree *tree, int convert _U_, int hf_index)
577 nlogons = tvb_get_letohs(tvb, offset);
578 if (nlogons == 0xffff) /* -1 */
579 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 2,
580 nlogons, "%s: Unknown",
581 proto_registrar_get_name(hf_index));
583 proto_tree_add_uint(tree, hf_index, tvb, offset, 2,
590 add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
591 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
595 max_storage = tvb_get_letohl(tvb, offset);
596 if (max_storage == 0xffffffff)
597 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
598 max_storage, "%s: No limit",
599 proto_registrar_get_name(hf_index));
601 proto_tree_add_uint(tree, hf_index, tvb, offset, 4,
608 add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
609 proto_tree *tree, int convert, int hf_index)
613 /* pointer to byte array */
614 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
618 if (tvb_bytes_exist(tvb, cptr, count)) {
621 * The logon hours should be exactly 21 bytes long.
623 * XXX - should actually carve up the bits;
624 * we need the units per week to do that, though.
626 proto_tree_add_item(tree, hf_index, tvb, cptr, count,
629 proto_tree_add_bytes_format(tree, hf_index, tvb,
631 "%s: %s (wrong length, should be 21, is %d",
632 proto_registrar_get_name(hf_index),
633 tvb_bytes_to_str(tvb, cptr, count), count);
636 proto_tree_add_text(tree, tvb, 0, 0,
637 "%s: <Bytes go past end of frame>",
638 proto_registrar_get_name(hf_index));
645 add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
646 proto_tree *tree, int convert _U_, int hf_index)
650 tzoffset = tvb_get_letohs(tvb, offset);
652 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
653 tzoffset, "%s: %s east of UTC",
654 proto_registrar_get_name(hf_index),
655 time_secs_to_str(-tzoffset*60));
656 } else if (tzoffset > 0) {
657 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
658 tzoffset, "%s: %s west of UTC",
659 proto_registrar_get_name(hf_index),
660 time_secs_to_str(tzoffset*60));
662 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
663 tzoffset, "%s: at UTC",
664 proto_registrar_get_name(hf_index));
671 add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
672 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
674 guint16 timeinterval;
676 timeinterval = tvb_get_letohs(tvb, offset);
677 proto_tree_add_uint_format(tree, hf_timeinterval, tvb, offset, 2,
678 timeinterval, "%s: %f seconds", proto_registrar_get_name(hf_index),
685 add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
686 proto_tree *tree, int convert _U_, int hf_index _U_)
689 proto_tree_add_text(tree, tvb, offset, count,
690 "Bogus NetWkstaUserLogon parameters: length is %d, should be 54",
697 proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, TRUE);
704 proto_tree_add_item(tree, hf_password, tvb, offset, 15, TRUE);
710 /* workstation name */
711 proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, TRUE);
717 * The following data structure describes the Remote API requests we
720 * Simply fill in the number and parameter information.
721 * Try to keep them in order.
723 * We will extend this data structure as we try to decode more.
727 * This is a pointer to a function to process an item.
729 typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
733 * Type of an item; determines what parameter strings are valid for
737 PARAM_NONE, /* for the end-of-list stopper */
738 PARAM_WORD, /* 'W' or 'h' - 16-bit word */
739 PARAM_DWORD, /* 'D' or 'i' - 32-bit word */
740 PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
741 PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
745 * This structure describes an item; "hf_index" points to the index
746 * for the field corresponding to that item, "func" points to the
747 * function to use to add that item to the tree, and "type" is the
748 * type that the item is supposed to have.
757 * This structure describes a list of items; each list of items
758 * has a corresponding detail level.
762 const item_t *item_list;
768 proto_item *(*req_data_item)(tvbuff_t *, packet_info *,
771 const item_t *req_data;
772 const item_t *req_aux_data;
774 const gchar *resp_data_entry_list_label;
775 gint *ett_data_entry_list;
776 proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
778 gint *ett_resp_data_element_item;
779 const item_list_t *resp_data_list;
780 const item_t *resp_aux_data;
783 static int no_hf = -1; /* for padding crap */
785 static const item_t lm_params_req_netshareenum[] = {
786 { &hf_detail_level, add_detail_level, PARAM_WORD },
787 { &hf_recv_buf_len, add_word_param, PARAM_WORD },
788 { NULL, NULL, PARAM_NONE }
791 static const item_t lm_params_resp_netshareenum[] = {
792 { &hf_acount, add_word_param, PARAM_WORD },
793 { NULL, NULL, PARAM_NONE }
797 * Create a subtree for a share.
800 netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
803 return proto_tree_add_text(tree, tvb, offset, -1,
804 "Share %.13s", tvb_get_ephemeral_string(tvb, offset, 13));
809 static const item_t lm_null[] = {
810 { NULL, NULL, PARAM_NONE }
813 static const item_list_t lm_null_list[] = {
817 static const item_t lm_data_resp_netshareenum_1[] = {
818 { &hf_share_name, add_byte_param, PARAM_BYTES },
819 { &no_hf, add_pad_param, PARAM_BYTES },
820 { &hf_share_type, add_word_param, PARAM_WORD },
821 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
822 { NULL, NULL, PARAM_NONE }
825 static const item_list_t lm_data_resp_netshareenum[] = {
826 { 1, lm_data_resp_netshareenum_1 },
830 static const item_t lm_params_req_netsharegetinfo[] = {
831 { &hf_share_name, add_string_param, PARAM_STRINGZ },
832 { &hf_detail_level, add_detail_level, PARAM_WORD },
833 { NULL, NULL, PARAM_NONE }
836 static const item_t lm_params_resp_netsharegetinfo[] = {
837 { &hf_abytes, add_word_param, PARAM_WORD },
838 { NULL, NULL, PARAM_NONE }
841 static const item_t lm_data_resp_netsharegetinfo_0[] = {
842 { &hf_share_name, add_byte_param, PARAM_BYTES },
843 { NULL, NULL, PARAM_NONE }
846 static const item_t lm_data_resp_netsharegetinfo_1[] = {
847 { &hf_share_name, add_byte_param, PARAM_BYTES },
848 { &no_hf, add_pad_param, PARAM_BYTES },
849 { &hf_share_type, add_word_param, PARAM_WORD },
850 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
851 { NULL, NULL, PARAM_NONE }
854 static const item_t lm_data_resp_netsharegetinfo_2[] = {
855 { &hf_share_name, add_byte_param, PARAM_BYTES },
856 { &no_hf, add_pad_param, PARAM_BYTES },
857 { &hf_share_type, add_word_param, PARAM_WORD },
858 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
859 { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
860 { &hf_share_max_uses, add_max_uses, PARAM_WORD },
861 { &hf_share_current_uses, add_word_param, PARAM_WORD },
862 { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
863 { &hf_share_password, add_byte_param, PARAM_BYTES },
864 { NULL, NULL, PARAM_NONE }
867 static const item_list_t lm_data_resp_netsharegetinfo[] = {
868 { 0, lm_data_resp_netsharegetinfo_0 },
869 { 1, lm_data_resp_netsharegetinfo_1 },
870 { 2, lm_data_resp_netsharegetinfo_2 },
874 static const item_t lm_params_req_netservergetinfo[] = {
875 { &hf_detail_level, add_detail_level, PARAM_WORD },
876 { NULL, NULL, PARAM_NONE }
879 static const item_t lm_params_resp_netservergetinfo[] = {
880 { &hf_abytes, add_word_param, PARAM_WORD },
881 { NULL, NULL, PARAM_NONE }
884 static const item_t lm_data_serverinfo_0[] = {
885 { &hf_server_name, add_byte_param, PARAM_BYTES },
886 { NULL, NULL, PARAM_NONE }
889 static const item_t lm_data_serverinfo_1[] = {
890 { &hf_server_name, add_byte_param, PARAM_BYTES },
891 { &hf_server_major, add_byte_param, PARAM_BYTES },
892 { &hf_server_minor, add_byte_param, PARAM_BYTES },
893 { &no_hf, add_server_type, PARAM_DWORD },
894 { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
895 { NULL, NULL, PARAM_NONE }
898 static const item_list_t lm_data_serverinfo[] = {
899 { 0, lm_data_serverinfo_0 },
900 { 1, lm_data_serverinfo_1 },
904 static const item_t lm_params_req_netusergetinfo[] = {
905 { &hf_user_name, add_string_param, PARAM_STRINGZ },
906 { &hf_detail_level, add_detail_level, PARAM_WORD },
907 { NULL, NULL, PARAM_NONE }
910 static const item_t lm_params_resp_netusergetinfo[] = {
911 { &hf_abytes, add_word_param, PARAM_WORD },
912 { NULL, NULL, PARAM_NONE }
915 static const item_t lm_data_resp_netusergetinfo_11[] = {
916 { &hf_user_name, add_byte_param, PARAM_BYTES },
917 { &no_hf, add_pad_param, PARAM_BYTES },
918 { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
919 { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
920 { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
921 { &hf_privilege_level, add_word_param, PARAM_WORD },
922 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
923 { &hf_password_age, add_reltime, PARAM_DWORD },
924 { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
925 { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
926 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
927 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
928 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
929 { &hf_num_logons, add_nlogons, PARAM_WORD },
930 { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
931 { &hf_country_code, add_word_param, PARAM_WORD },
932 { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
933 { &hf_max_storage, add_max_storage, PARAM_DWORD },
934 { &hf_units_per_week, add_word_param, PARAM_WORD },
935 { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
936 { &hf_code_page, add_word_param, PARAM_WORD },
937 { NULL, NULL, PARAM_NONE }
940 static const item_list_t lm_data_resp_netusergetinfo[] = {
941 { 11, lm_data_resp_netusergetinfo_11 },
945 static const item_t lm_params_req_netusergetgroups[] = {
946 { &hf_user_name, add_string_param, PARAM_STRINGZ },
947 { &hf_detail_level, add_detail_level, PARAM_WORD },
948 { NULL, NULL, PARAM_NONE }
951 static const item_t lm_params_resp_netusergetgroups[] = {
952 { &hf_abytes, add_word_param, PARAM_WORD },
953 { NULL, NULL, PARAM_NONE }
956 static const item_t lm_data_resp_netusergetgroups_0[] = {
957 { &hf_group_name, add_byte_param, PARAM_BYTES },
958 { NULL, NULL, PARAM_NONE }
961 static const item_list_t lm_data_resp_netusergetgroups[] = {
962 { 0, lm_data_resp_netusergetgroups_0 },
967 * Has no detail level; make it the default.
969 static const item_t lm_data_resp_netremotetod_nolevel[] = {
970 { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
971 { &hf_msecs, add_dword_param, PARAM_DWORD },
972 { &hf_hour, add_byte_param, PARAM_BYTES },
973 { &hf_minute, add_byte_param, PARAM_BYTES },
974 { &hf_second, add_byte_param, PARAM_BYTES },
975 { &hf_hundredths, add_byte_param, PARAM_BYTES },
976 { &hf_tzoffset, add_tzoffset, PARAM_WORD },
977 { &hf_timeinterval, add_timeinterval, PARAM_WORD },
978 { &hf_day, add_byte_param, PARAM_BYTES },
979 { &hf_month, add_byte_param, PARAM_BYTES },
980 { &hf_year, add_word_param, PARAM_WORD },
981 { &hf_weekday, add_byte_param, PARAM_BYTES },
982 { NULL, NULL, PARAM_NONE }
985 static const item_list_t lm_data_resp_netremotetod[] = {
986 { -1, lm_data_resp_netremotetod_nolevel },
989 static const item_t lm_params_req_netserverenum2[] = {
990 { &hf_detail_level, add_detail_level, PARAM_WORD },
991 { &no_hf, add_server_type_info, PARAM_DWORD },
992 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
993 { NULL, NULL, PARAM_NONE }
997 * Create a subtree for a server.
1000 netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
1003 return proto_tree_add_text(tree, tvb, offset, -1,
1004 "Server %.16s", tvb_get_ephemeral_string(tvb, offset, 16));
1009 static const item_t lm_params_resp_netserverenum2[] = {
1010 { &hf_acount, add_word_param, PARAM_WORD },
1011 { NULL, NULL, PARAM_NONE }
1015 static const item_t lm_params_req_netserverenum3[] = {
1016 { &hf_detail_level, add_detail_level, PARAM_WORD },
1017 { &no_hf, add_server_type_info, PARAM_DWORD },
1018 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
1019 { &hf_last_entry, add_string_param, PARAM_STRINGZ },
1020 { NULL, NULL, PARAM_NONE }
1024 static const item_t lm_params_req_netwkstagetinfo[] = {
1025 { &hf_detail_level, add_detail_level, PARAM_WORD },
1026 { NULL, NULL, PARAM_NONE }
1029 static const item_t lm_params_resp_netwkstagetinfo[] = {
1030 { &hf_abytes, add_word_param, PARAM_WORD },
1031 { NULL, NULL, PARAM_NONE }
1034 static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1035 { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1036 { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1037 { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1038 { &hf_workstation_major, add_byte_param, PARAM_BYTES },
1039 { &hf_workstation_minor, add_byte_param, PARAM_BYTES },
1040 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1041 { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1042 { NULL, NULL, PARAM_NONE }
1045 static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1046 { 10, lm_data_resp_netwkstagetinfo_10 },
1050 static const item_t lm_params_req_netwkstauserlogon[] = {
1051 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1052 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1053 { &hf_detail_level, add_detail_level, PARAM_WORD },
1054 { &no_hf, add_logon_args, PARAM_BYTES },
1055 { &hf_ustruct_size, add_word_param, PARAM_WORD },
1056 { NULL, NULL, PARAM_NONE }
1059 static const item_t lm_params_resp_netwkstauserlogon[] = {
1060 { &hf_abytes, add_word_param, PARAM_WORD },
1061 { NULL, NULL, PARAM_NONE }
1064 static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1065 { &hf_logon_code, add_word_param, PARAM_WORD },
1066 { &hf_user_name, add_byte_param, PARAM_BYTES },
1067 { &no_hf, add_pad_param, PARAM_BYTES },
1068 { &hf_privilege_level, add_word_param, PARAM_WORD },
1069 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1070 { &hf_num_logons, add_nlogons, PARAM_WORD },
1071 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1072 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1073 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1074 { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1075 { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1076 { &hf_password_age, add_reltime, PARAM_DWORD },
1077 { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1078 { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1079 { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1080 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1081 { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1082 { &hf_reserved, add_dword_param, PARAM_DWORD },
1083 { NULL, NULL, PARAM_NONE }
1086 static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1087 { 1, lm_data_resp_netwkstauserlogon_1 },
1091 static const item_t lm_params_req_netwkstauserlogoff[] = {
1092 { &hf_user_name, add_byte_param, PARAM_BYTES },
1093 { &no_hf, add_pad_param, PARAM_BYTES },
1094 { &hf_workstation_name, add_byte_param, PARAM_BYTES },
1095 { NULL, NULL, PARAM_NONE }
1098 static const item_t lm_params_resp_netwkstauserlogoff[] = {
1099 { &hf_abytes, add_word_param, PARAM_WORD },
1100 { NULL, NULL, PARAM_NONE }
1103 static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1104 { &hf_logoff_code, add_word_param, PARAM_WORD },
1105 { &hf_duration, add_reltime, PARAM_DWORD },
1106 { &hf_num_logons, add_nlogons, PARAM_WORD },
1107 { NULL, NULL, PARAM_NONE }
1110 static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1111 { 1, lm_data_resp_netwkstauserlogoff_1 },
1115 static const item_t lm_params_req_samoemchangepassword[] = {
1116 { &hf_user_name, add_string_param, PARAM_STRINGZ },
1117 { NULL, NULL, PARAM_NONE }
1120 static const item_t lm_data_req_samoemchangepassword[] = {
1121 { &hf_new_password, add_byte_param, PARAM_BYTES },
1122 { &hf_old_password, add_byte_param, PARAM_BYTES },
1123 { NULL, NULL, PARAM_NONE }
1126 #define API_NetShareEnum 0
1127 #define API_NetShareGetInfo 1
1128 #define API_NetShareSetInfo 2
1129 #define API_NetShareAdd 3
1130 #define API_NetShareDel 4
1131 #define API_NetShareCheck 5
1132 #define API_NetSessionEnum 6
1133 #define API_NetSessionGetInfo 7
1134 #define API_NetSessionDel 8
1135 #define API_WconnectionEnum 9
1136 #define API_NetFileEnum 10
1137 #define API_NetFileGetInfo 11
1138 #define API_NetFileClose 12
1139 #define API_NetServerGetInfo 13
1140 #define API_NetServerSetInfo 14
1141 #define API_NetServerDiskEnum 15
1142 #define API_NetServerAdminCommand 16
1143 #define API_NetAuditOpen 17
1144 #define API_NetAuditClear 18
1145 #define API_NetErrorLogOpen 19
1146 #define API_NetErrorLogClear 20
1147 #define API_NetCharDevEnum 21
1148 #define API_NetCharDevGetInfo 22
1149 #define API_NetCharDevControl 23
1150 #define API_NetCharDevQEnum 24
1151 #define API_NetCharDevQGetInfo 25
1152 #define API_NetCharDevQSetInfo 26
1153 #define API_NetCharDevQPurge 27
1154 #define API_NetCharDevQPurgeSelf 28
1155 #define API_NetMessageNameEnum 29
1156 #define API_NetMessageNameGetInfo 30
1157 #define API_NetMessageNameAdd 31
1158 #define API_NetMessageNameDel 32
1159 #define API_NetMessageNameFwd 33
1160 #define API_NetMessageNameUnFwd 34
1161 #define API_NetMessageBufferSend 35
1162 #define API_NetMessageFileSend 36
1163 #define API_NetMessageLogFileSet 37
1164 #define API_NetMessageLogFileGet 38
1165 #define API_NetServiceEnum 39
1166 #define API_NetServiceInstall 40
1167 #define API_NetServiceControl 41
1168 #define API_NetAccessEnum 42
1169 #define API_NetAccessGetInfo 43
1170 #define API_NetAccessSetInfo 44
1171 #define API_NetAccessAdd 45
1172 #define API_NetAccessDel 46
1173 #define API_NetGroupEnum 47
1174 #define API_NetGroupAdd 48
1175 #define API_NetGroupDel 49
1176 #define API_NetGroupAddUser 50
1177 #define API_NetGroupDelUser 51
1178 #define API_NetGroupGetUsers 52
1179 #define API_NetUserEnum 53
1180 #define API_NetUserAdd 54
1181 #define API_NetUserDel 55
1182 #define API_NetUserGetInfo 56
1183 #define API_NetUserSetInfo 57
1184 #define API_NetUserPasswordSet 58
1185 #define API_NetUserGetGroups 59
1186 /*This line and number replaced a Dead Entry for 60 */
1187 /*This line and number replaced a Dead Entry for 61 */
1188 #define API_NetWkstaSetUID 62
1189 #define API_NetWkstaGetInfo 63
1190 #define API_NetWkstaSetInfo 64
1191 #define API_NetUseEnum 65
1192 #define API_NetUseAdd 66
1193 #define API_NetUseDel 67
1194 #define API_NetUseGetInfo 68
1195 #define API_WPrintQEnum 69
1196 #define API_WPrintQGetInfo 70
1197 #define API_WPrintQSetInfo 71
1198 #define API_WPrintQAdd 72
1199 #define API_WPrintQDel 73
1200 #define API_WPrintQPause 74
1201 #define API_WPrintQContinue 75
1202 #define API_WPrintJobEnum 76
1203 #define API_WPrintJobGetInfo 77
1204 #define API_WPrintJobSetInfo_OLD 78
1205 /* This line and number replaced a Dead Entry for 79 */
1206 /* This line and number replaced a Dead Entry for 80 */
1207 #define API_WPrintJobDel 81
1208 #define API_WPrintJobPause 82
1209 #define API_WPrintJobContinue 83
1210 #define API_WPrintDestEnum 84
1211 #define API_WPrintDestGetInfo 85
1212 #define API_WPrintDestControl 86
1213 #define API_NetProfileSave 87
1214 #define API_NetProfileLoad 88
1215 #define API_NetStatisticsGet 89
1216 #define API_NetStatisticsClear 90
1217 #define API_NetRemoteTOD 91
1218 #define API_WNetBiosEnum 92
1219 #define API_WNetBiosGetInfo 93
1220 #define API_NetServerEnum 94
1221 #define API_I_NetServerEnum 95
1222 #define API_NetServiceGetInfo 96
1223 /* This line and number replaced a Dead Entry for 97 */
1224 /* This line and number replaced a Dead Entry for 98 */
1225 /* This line and number replaced a Dead Entry for 99 */
1226 /* This line and number replaced a Dead Entry for 100 */
1227 /* This line and number replaced a Dead Entry for 101 */
1228 /* This line and number replaced a Dead Entry for 102 */
1229 #define API_WPrintQPurge 103
1230 #define API_NetServerEnum2 104
1231 #define API_NetAccessGetUserPerms 105
1232 #define API_NetGroupGetInfo 106
1233 #define API_NetGroupSetInfo 107
1234 #define API_NetGroupSetUsers 108
1235 #define API_NetUserSetGroups 109
1236 #define API_NetUserModalsGet 110
1237 #define API_NetUserModalsSet 111
1238 #define API_NetFileEnum2 112
1239 #define API_NetUserAdd2 113
1240 #define API_NetUserSetInfo2 114
1241 #define API_NetUserPasswordSet2 115
1242 #define API_I_NetServerEnum2 116
1243 #define API_NetConfigGet2 117
1244 #define API_NetConfigGetAll2 118
1245 #define API_NetGetDCName 119
1246 #define API_NetHandleGetInfo 120
1247 #define API_NetHandleSetInfo 121
1248 #define API_NetStatisticsGet2 122
1249 #define API_WBuildGetInfo 123
1250 #define API_NetFileGetInfo2 124
1251 #define API_NetFileClose2 125
1252 #define API_NetServerReqChallenge 126
1253 #define API_NetServerAuthenticate 127
1254 #define API_NetServerPasswordSet 128
1255 #define API_WNetAccountDeltas 129
1256 #define API_WNetAccountSync 130
1257 #define API_NetUserEnum2 131
1258 #define API_NetWkstaUserLogon 132
1259 #define API_NetWkstaUserLogoff 133
1260 #define API_NetLogonEnum 134
1261 #define API_NetErrorLogRead 135
1262 #define API_I_NetPathType 136
1263 #define API_I_NetPathCanonicalize 137
1264 #define API_I_NetPathCompare 138
1265 #define API_I_NetNameValidate 139
1266 #define API_I_NetNameCanonicalize 140
1267 #define API_I_NetNameCompare 141
1268 #define API_NetAuditRead 142
1269 #define API_WPrintDestAdd 143
1270 #define API_WPrintDestSetInfo 144
1271 #define API_WPrintDestDel 145
1272 #define API_NetUserValidate2 146
1273 #define API_WPrintJobSetInfo 147
1274 #define API_TI_NetServerDiskEnum 148
1275 #define API_TI_NetServerDiskGetInfo 149
1276 #define API_TI_FTVerifyMirror 150
1277 #define API_TI_FTAbortVerify 151
1278 #define API_TI_FTGetInfo 152
1279 #define API_TI_FTSetInfo 153
1280 #define API_TI_FTLockDisk 154
1281 #define API_TI_FTFixError 155
1282 #define API_TI_FTAbortFix 156
1283 #define API_TI_FTDiagnoseError 157
1284 #define API_TI_FTGetDriveStats 158
1285 /* This line and number replaced a Dead Entry for 159 */
1286 #define API_TI_FTErrorGetInfo 160
1287 /* This line and number replaced a Dead Entry for 161 */
1288 /* This line and number replaced a Dead Entry for 162 */
1289 #define API_NetAccessCheck 163
1290 #define API_NetAlertRaise 164
1291 #define API_NetAlertStart 165
1292 #define API_NetAlertStop 166
1293 #define API_NetAuditWrite 167
1294 #define API_NetIRemoteAPI 168
1295 #define API_NetServiceStatus 169
1296 #define API_I_NetServerRegister 170
1297 #define API_I_NetServerDeregister 171
1298 #define API_I_NetSessionEntryMake 172
1299 #define API_I_NetSessionEntryClear 173
1300 #define API_I_NetSessionEntryGetInfo 174
1301 #define API_I_NetSessionEntrySetInfo 175
1302 #define API_I_NetConnectionEntryMake 176
1303 #define API_I_NetConnectionEntryClear 177
1304 #define API_I_NetConnectionEntrySetInfo 178
1305 #define API_I_NetConnectionEntryGetInfo 179
1306 #define API_I_NetFileEntryMake 180
1307 #define API_I_NetFileEntryClear 181
1308 #define API_I_NetFileEntrySetInfo 182
1309 #define API_I_NetFileEntryGetInfo 183
1310 #define API_AltSrvMessageBufferSend 184
1311 #define API_AltSrvMessageFileSend 185
1312 #define API_wI_NetRplWkstaEnum 186
1313 #define API_wI_NetRplWkstaGetInfo 187
1314 #define API_wI_NetRplWkstaSetInfo 188
1315 #define API_wI_NetRplWkstaAdd 189
1316 #define API_wI_NetRplWkstaDel 190
1317 #define API_wI_NetRplProfileEnum 191
1318 #define API_wI_NetRplProfileGetInfo 192
1319 #define API_wI_NetRplProfileSetInfo 193
1320 #define API_wI_NetRplProfileAdd 194
1321 #define API_wI_NetRplProfileDel 195
1322 #define API_wI_NetRplProfileClone 196
1323 #define API_wI_NetRplBaseProfileEnum 197
1324 /* This line and number replaced a Dead Entry for 198 */
1325 /* This line and number replaced a Dead Entry for 199 */
1326 /* This line and number replaced a Dead Entry for 200 */
1327 #define API_WIServerSetInfo 201
1328 /* This line and number replaced a Dead Entry for 202 */
1329 /* This line and number replaced a Dead Entry for 203 */
1330 /* This line and number replaced a Dead Entry for 204 */
1331 #define API_WPrintDriverEnum 205
1332 #define API_WPrintQProcessorEnum 206
1333 #define API_WPrintPortEnum 207
1334 #define API_WNetWriteUpdateLog 208
1335 #define API_WNetAccountUpdate 209
1336 #define API_WNetAccountConfirmUpdate 210
1337 #define API_NetConfigSet 211
1338 #define API_WAccountsReplicate 212
1339 /* 213 is used by WfW */
1340 #define API_SamOEMChgPasswordUser2_P 214
1341 #define API_NetServerEnum3 215
1342 /* XXX - what about 216 through 249? */
1343 #define API_WPrintDriverGetInfo 250
1344 #define API_WPrintDriverSetInfo 251
1345 #define API_NetAliasAdd 252
1346 #define API_NetAliasDel 253
1347 #define API_NetAliasGetInfo 254
1348 #define API_NetAliasSetInfo 255
1349 #define API_NetAliasEnum 256
1350 #define API_NetUserGetLogonAsn 257
1351 #define API_NetUserSetLogonAsn 258
1352 #define API_NetUserGetAppSel 259
1353 #define API_NetUserSetAppSel 260
1354 #define API_NetAppAdd 261
1355 #define API_NetAppDel 262
1356 #define API_NetAppGetInfo 263
1357 #define API_NetAppSetInfo 264
1358 #define API_NetAppEnum 265
1359 #define API_NetUserDCDBInit 266
1360 #define API_NetDASDAdd 267
1361 #define API_NetDASDDel 268
1362 #define API_NetDASDGetInfo 269
1363 #define API_NetDASDSetInfo 270
1364 #define API_NetDASDEnum 271
1365 #define API_NetDASDCheck 272
1366 #define API_NetDASDCtl 273
1367 #define API_NetUserRemoteLogonCheck 274
1368 #define API_NetUserPasswordSet3 275
1369 #define API_NetCreateRIPLMachine 276
1370 #define API_NetDeleteRIPLMachine 277
1371 #define API_NetGetRIPLMachineInfo 278
1372 #define API_NetSetRIPLMachineInfo 279
1373 #define API_NetEnumRIPLMachine 280
1374 #define API_I_ShareAdd 281
1375 #define API_I_AliasEnum 282
1376 #define API_NetAccessApply 283
1377 #define API_WPrt16Query 284
1378 #define API_WPrt16Set 285
1379 #define API_NetUserDel100 286
1380 #define API_NetUserRemoteLogonCheck2 287
1381 #define API_WRemoteTODSet 294
1382 #define API_WPrintJobMoveAll 295
1383 #define API_W16AppParmAdd 296
1384 #define API_W16AppParmDel 297
1385 #define API_W16AppParmGet 298
1386 #define API_W16AppParmSet 299
1387 #define API_W16RIPLMachineCreate 300
1388 #define API_W16RIPLMachineGetInfo 301
1389 #define API_W16RIPLMachineSetInfo 302
1390 #define API_W16RIPLMachineEnum 303
1391 #define API_W16RIPLMachineListParmEnum 304
1392 #define API_W16RIPLMachClassGetInfo 305
1393 #define API_W16RIPLMachClassEnum 306
1394 #define API_W16RIPLMachClassCreate 307
1395 #define API_W16RIPLMachClassSetInfo 308
1396 #define API_W16RIPLMachClassDelete 309
1397 #define API_W16RIPLMachClassLPEnum 310
1398 #define API_W16RIPLMachineDelete 311
1399 #define API_W16WSLevelGetInfo 312
1400 #define API_NetServerNameAdd 313
1401 #define API_NetServerNameDel 314
1402 #define API_NetServerNameEnum 315
1403 #define API_I_WDASDEnum 316
1404 #define API_I_WDASDEnumTerminate 317
1405 #define API_I_WDASDSetInfo2 318
1407 static const struct lanman_desc lmd[] = {
1409 lm_params_req_netshareenum,
1414 lm_params_resp_netshareenum,
1417 netshareenum_share_entry,
1419 lm_data_resp_netshareenum,
1422 { API_NetShareGetInfo,
1423 lm_params_req_netsharegetinfo,
1428 lm_params_resp_netsharegetinfo,
1433 lm_data_resp_netsharegetinfo,
1436 { API_NetServerGetInfo,
1437 lm_params_req_netservergetinfo,
1442 lm_params_resp_netservergetinfo,
1450 { API_NetUserGetInfo,
1451 lm_params_req_netusergetinfo,
1456 lm_params_resp_netusergetinfo,
1461 lm_data_resp_netusergetinfo,
1464 { API_NetUserGetGroups,
1465 lm_params_req_netusergetgroups,
1470 lm_params_resp_netusergetgroups,
1475 lm_data_resp_netusergetgroups,
1489 lm_data_resp_netremotetod,
1492 { API_NetServerEnum2,
1493 lm_params_req_netserverenum2,
1498 lm_params_resp_netserverenum2,
1500 &ett_lanman_servers,
1501 netserverenum2_server_entry,
1506 { API_NetWkstaGetInfo,
1507 lm_params_req_netwkstagetinfo,
1512 lm_params_resp_netwkstagetinfo,
1517 lm_data_resp_netwkstagetinfo,
1520 { API_NetWkstaUserLogon,
1521 lm_params_req_netwkstauserlogon,
1526 lm_params_resp_netwkstauserlogon,
1531 lm_data_resp_netwkstauserlogon,
1534 { API_NetWkstaUserLogoff,
1535 lm_params_req_netwkstauserlogoff,
1540 lm_params_resp_netwkstauserlogoff,
1545 lm_data_resp_netwkstauserlogoff,
1548 { API_SamOEMChgPasswordUser2_P,
1549 lm_params_req_samoemchangepassword,
1552 lm_data_req_samoemchangepassword,
1562 { API_NetServerEnum3,
1563 lm_params_req_netserverenum3,
1568 lm_params_resp_netserverenum2,
1570 &ett_lanman_servers,
1571 netserverenum2_server_entry,
1586 &ett_lanman_unknown_entry,
1591 static const struct lanman_desc *
1592 find_lanman(int lanman_num)
1596 for (i = 0; lmd[i].lanman_num != -1; i++) {
1597 if (lmd[i].lanman_num == lanman_num)
1603 static const guchar *
1604 get_count(const guchar *desc, int *countp)
1609 if (!isdigit(*desc)) {
1610 *countp = 1; /* no count was supplied */
1614 while ((c = *desc) != '\0' && isdigit(c)) {
1615 count = (count * 10) + c - '0';
1619 *countp = count; /* XXX - what if it's 0? */
1624 dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1625 proto_tree *tree, const guchar *desc, const item_t *items,
1626 gboolean *has_data_p)
1634 *has_data_p = FALSE;
1635 while ((c = *desc++) != '\0') {
1640 * A 16-bit word value in the request.
1642 if (items->func == NULL) {
1644 * We've run out of items in the table;
1645 * fall back on the default.
1647 offset = add_word_param(tvb, offset, 0, pinfo,
1649 } else if (items->type != PARAM_WORD) {
1651 * Descriptor character is 'W', but this
1652 * isn't a word parameter.
1654 WParam = tvb_get_letohs(tvb, offset);
1655 proto_tree_add_text(tree, tvb, offset, 2,
1656 "%s: Value is %u (0x%04X), type is wrong (W)",
1657 (*items->hf_index == -1) ?
1659 proto_registrar_get_name(*items->hf_index),
1664 offset = (*items->func)(tvb, offset, 0, pinfo,
1665 tree, 0, *items->hf_index);
1672 * A 32-bit doubleword value in the request.
1674 if (items->func == NULL) {
1676 * We've run out of items in the table;
1677 * fall back on the default.
1679 offset = add_dword_param(tvb, offset, 0, pinfo,
1681 } else if (items->type != PARAM_DWORD) {
1683 * Descriptor character is 'D', but this
1684 * isn't a doubleword parameter.
1686 LParam = tvb_get_letohl(tvb, offset);
1687 proto_tree_add_text(tree, tvb, offset, 2,
1688 "%s: Value is %u (0x%08X), type is wrong (D)",
1689 (*items->hf_index == -1) ?
1690 "Doubleword Param" :
1691 proto_registrar_get_name(*items->hf_index),
1696 offset = (*items->func)(tvb, offset, 0, pinfo,
1697 tree, 0, *items->hf_index);
1704 * A byte or multi-byte value in the request.
1706 desc = get_count(desc, &count);
1707 if (items->func == NULL) {
1709 * We've run out of items in the table;
1710 * fall back on the default.
1712 offset = add_byte_param(tvb, offset, count,
1713 pinfo, tree, 0, -1);
1714 } else if (items->type != PARAM_BYTES) {
1716 * Descriptor character is 'b', but this
1717 * isn't a byte/bytes parameter.
1719 proto_tree_add_text(tree, tvb, offset, count,
1720 "%s: Value is %s, type is wrong (b)",
1721 (*items->hf_index == -1) ?
1723 proto_registrar_get_name(*items->hf_index),
1724 tvb_bytes_to_str(tvb, offset, count));
1728 offset = (*items->func)(tvb, offset, count,
1729 pinfo, tree, 0, *items->hf_index);
1738 if (items->func == NULL) {
1740 * We've run out of items in the table;
1741 * fall back on the default.
1743 add_null_pointer_param(tvb, offset, 0,
1744 pinfo, tree, 0, -1);
1747 * If "*items->hf_index" is -1, this is
1748 * a reserved must-be-null field; don't
1749 * clutter the protocol tree by putting
1752 if (*items->hf_index != -1) {
1753 add_null_pointer_param(tvb,
1754 offset, 0, pinfo, tree, 0,
1763 * A null-terminated ASCII string.
1765 if (items->func == NULL) {
1767 * We've run out of items in the table;
1768 * fall back on the default.
1770 offset = add_string_param(tvb, offset, 0,
1771 pinfo, tree, 0, -1);
1772 } else if (items->type != PARAM_STRINGZ) {
1774 * Descriptor character is 'z', but this
1775 * isn't a string parameter.
1777 string_len = tvb_strsize(tvb, offset);
1778 proto_tree_add_text(tree, tvb, offset, string_len,
1779 "%s: Value is %s, type is wrong (z)",
1780 (*items->hf_index == -1) ?
1782 proto_registrar_get_name(*items->hf_index),
1783 tvb_format_text(tvb, offset, string_len));
1784 offset += string_len;
1787 offset = (*items->func)(tvb, offset, 0,
1788 pinfo, tree, 0, *items->hf_index);
1795 * One or more pad bytes.
1797 desc = get_count(desc, &count);
1798 proto_tree_add_text(tree, tvb, offset, count,
1805 * 16-bit receive buffer length.
1807 proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1814 * 32-bit send buffer offset.
1815 * This appears not to be sent over the wire.
1822 * 16-bit send buffer length.
1824 proto_tree_add_item(tree, hf_send_buf_len, tvb,
1837 dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1838 proto_tree *tree, const guchar *desc, const item_t *items,
1839 gboolean *has_data_p, gboolean *has_ent_count_p, guint16 *ent_count_p)
1846 *has_data_p = FALSE;
1847 *has_ent_count_p = FALSE;
1848 while ((c = *desc++) != '\0') {
1853 * 32-bit receive buffer offset.
1860 * A byte or series of bytes is returned.
1862 desc = get_count(desc, &count);
1863 if (items->func == NULL) {
1865 * We've run out of items in the table;
1866 * fall back on the default.
1868 offset = add_byte_param(tvb, offset, count,
1869 pinfo, tree, 0, -1);
1870 } else if (items->type != PARAM_BYTES) {
1872 * Descriptor character is 'b', but this
1873 * isn't a byte/bytes parameter.
1875 proto_tree_add_text(tree, tvb, offset, count,
1876 "%s: Value is %s, type is wrong (g)",
1877 (*items->hf_index == -1) ?
1879 proto_registrar_get_name(*items->hf_index),
1880 tvb_bytes_to_str(tvb, offset, count));
1884 offset = (*items->func)(tvb, offset, count,
1885 pinfo, tree, 0, *items->hf_index);
1892 * A 16-bit word is received.
1894 if (items->func == NULL) {
1896 * We've run out of items in the table;
1897 * fall back on the default.
1899 offset = add_word_param(tvb, offset, 0, pinfo,
1901 } else if (items->type != PARAM_WORD) {
1903 * Descriptor character is 'h', but this
1904 * isn't a word parameter.
1906 WParam = tvb_get_letohs(tvb, offset);
1907 proto_tree_add_text(tree, tvb, offset, 2,
1908 "%s: Value is %u (0x%04X), type is wrong (W)",
1909 (*items->hf_index == -1) ?
1911 proto_registrar_get_name(*items->hf_index),
1916 offset = (*items->func)(tvb, offset, 0, pinfo,
1917 tree, 0, *items->hf_index);
1924 * A 32-bit doubleword is received.
1926 if (items->func == NULL) {
1928 * We've run out of items in the table;
1929 * fall back on the default.
1931 offset = add_dword_param(tvb, offset, 0, pinfo,
1933 } else if (items->type != PARAM_DWORD) {
1935 * Descriptor character is 'i', but this
1936 * isn't a doubleword parameter.
1938 LParam = tvb_get_letohl(tvb, offset);
1939 proto_tree_add_text(tree, tvb, offset, 2,
1940 "%s: Value is %u (0x%08X), type is wrong (i)",
1941 (*items->hf_index == -1) ?
1942 "Doubleword Param" :
1943 proto_registrar_get_name(*items->hf_index),
1948 offset = (*items->func)(tvb, offset, 0, pinfo,
1949 tree, 0, *items->hf_index);
1956 * A 16-bit entry count is returned.
1958 WParam = tvb_get_letohs(tvb, offset);
1959 proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1962 *has_ent_count_p = TRUE;
1963 *ent_count_p = WParam; /* Save this for later retrieval */
1974 dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1975 packet_info *pinfo, proto_tree *tree, const guchar *desc,
1976 const item_t *items, guint16 *aux_count_p)
1984 gint string_len = 0;
1986 if (aux_count_p != NULL)
1989 while ((c = *desc++) != '\0') {
1994 * A 16-bit word value.
1995 * XXX - handle the count?
1997 desc = get_count(desc, &count);
1998 if (items->func == NULL) {
2000 * We've run out of items in the table;
2001 * fall back on the default.
2003 offset = add_word_param(tvb, offset, 0, pinfo,
2005 } else if (items->type != PARAM_WORD) {
2007 * Descriptor character is 'W', but this
2008 * isn't a word parameter.
2010 WParam = tvb_get_letohs(tvb, offset);
2011 proto_tree_add_text(tree, tvb, offset, 2,
2012 "%s: Value is %u (0x%04X), type is wrong (W)",
2013 (*items->hf_index == -1) ?
2015 proto_registrar_get_name(*items->hf_index),
2020 offset = (*items->func)(tvb, offset, 0, pinfo,
2021 tree, convert, *items->hf_index);
2028 * A 32-bit doubleword value.
2029 * XXX - handle the count?
2031 desc = get_count(desc, &count);
2032 if (items->func == NULL) {
2034 * We've run out of items in the table;
2035 * fall back on the default.
2037 offset = add_dword_param(tvb, offset, 0, pinfo,
2039 } else if (items->type != PARAM_DWORD) {
2041 * Descriptor character is 'D', but this
2042 * isn't a doubleword parameter.
2044 LParam = tvb_get_letohl(tvb, offset);
2045 proto_tree_add_text(tree, tvb, offset, 2,
2046 "%s: Value is %u (0x%08X), type is wrong (D)",
2047 (*items->hf_index == -1) ?
2048 "Doubleword Param" :
2049 proto_registrar_get_name(*items->hf_index),
2054 offset = (*items->func)(tvb, offset, 0, pinfo,
2055 tree, convert, *items->hf_index);
2062 * A byte or multi-byte value.
2064 desc = get_count(desc, &count);
2065 if (items->func == NULL) {
2067 * We've run out of items in the table;
2068 * fall back on the default.
2070 offset = add_byte_param(tvb, offset, count,
2071 pinfo, tree, convert, -1);
2072 } else if (items->type != PARAM_BYTES) {
2074 * Descriptor character is 'B', but this
2075 * isn't a byte/bytes parameter.
2077 proto_tree_add_text(tree, tvb, offset, count,
2078 "%s: Value is %s, type is wrong (B)",
2079 (*items->hf_index == -1) ?
2081 proto_registrar_get_name(*items->hf_index),
2082 tvb_bytes_to_str(tvb, offset, count));
2086 offset = (*items->func)(tvb, offset, count,
2087 pinfo, tree, convert, *items->hf_index);
2096 if (items->func == NULL) {
2098 * We've run out of items in the table;
2099 * fall back on the default.
2101 add_null_pointer_param(tvb, offset, 0,
2102 pinfo, tree, convert, -1);
2105 * If "*items->hf_index" is -1, this is
2106 * a reserved must-be-null field; don't
2107 * clutter the protocol tree by putting
2110 if (*items->hf_index != -1) {
2111 add_null_pointer_param(tvb,
2112 offset, 0, pinfo, tree, convert,
2121 * A pointer to a null-terminated ASCII string.
2123 if (items->func == NULL) {
2125 * We've run out of items in the table;
2126 * fall back on the default.
2128 offset = add_stringz_pointer_param(tvb, offset,
2129 0, pinfo, tree, convert, -1);
2130 } else if (items->type != PARAM_STRINGZ) {
2132 * Descriptor character is 'z', but this
2133 * isn't a string parameter.
2135 string = get_stringz_pointer_value(tvb, offset,
2136 convert, &cptr, &string_len);
2138 proto_tree_add_text(tree, tvb, cptr, string_len,
2139 "%s: Value is %s, type is wrong (z)",
2140 (*items->hf_index == -1) ?
2142 proto_registrar_get_name(*items->hf_index),
2143 string ? string : "(null)");
2146 offset = (*items->func)(tvb, offset, 0,
2147 pinfo, tree, convert, *items->hf_index);
2154 * A pointer to a byte or multi-byte value.
2156 desc = get_count(desc, &count);
2157 if (items->func == NULL) {
2159 * We've run out of items in the table;
2160 * fall back on the default.
2162 offset = add_bytes_pointer_param(tvb, offset,
2163 count, pinfo, tree, convert, -1);
2164 } else if (items->type != PARAM_BYTES) {
2166 * Descriptor character is 'b', but this
2167 * isn't a byte/bytes parameter.
2169 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2171 proto_tree_add_text(tree, tvb, offset, count,
2172 "%s: Value is %s, type is wrong (b)",
2173 (*items->hf_index == -1) ?
2175 proto_registrar_get_name(*items->hf_index),
2176 tvb_bytes_to_str(tvb, cptr, count));
2179 offset = (*items->func)(tvb, offset, count,
2180 pinfo, tree, convert, *items->hf_index);
2187 * 16-bit auxiliary data structure count.
2190 WParam = tvb_get_letohs(tvb, offset);
2191 proto_tree_add_text(tree, tvb, offset, 2,
2193 "Auxiliary data structure count",
2196 if (aux_count_p != NULL)
2197 *aux_count_p = WParam; /* Save this for later retrieval */
2207 static const value_string commands[] = {
2208 {API_NetShareEnum, "NetShareEnum"},
2209 {API_NetShareGetInfo, "NetShareGetInfo"},
2210 {API_NetShareSetInfo, "NetShareSetInfo"},
2211 {API_NetShareAdd, "NetShareAdd"},
2212 {API_NetShareDel, "NetShareDel"},
2213 {API_NetShareCheck, "NetShareCheck"},
2214 {API_NetSessionEnum, "NetSessionEnum"},
2215 {API_NetSessionGetInfo, "NetSessionGetInfo"},
2216 {API_NetSessionDel, "NetSessionDel"},
2217 {API_WconnectionEnum, "NetConnectionEnum"},
2218 {API_NetFileEnum, "NetFileEnum"},
2219 {API_NetFileGetInfo, "NetFileGetInfo"},
2220 {API_NetFileClose, "NetFileClose"},
2221 {API_NetServerGetInfo, "NetServerGetInfo"},
2222 {API_NetServerSetInfo, "NetServerSetInfo"},
2223 {API_NetServerDiskEnum, "NetServerDiskEnum"},
2224 {API_NetServerAdminCommand, "NetServerAdminCommand"},
2225 {API_NetAuditOpen, "NetAuditOpen"},
2226 {API_NetAuditClear, "NetAuditClear"},
2227 {API_NetErrorLogOpen, "NetErrorLogOpen"},
2228 {API_NetErrorLogClear, "NetErrorLogClear"},
2229 {API_NetCharDevEnum, "NetCharDevEnum"},
2230 {API_NetCharDevGetInfo, "NetCharDevGetInfo"},
2231 {API_NetCharDevControl, "NetCharDevControl"},
2232 {API_NetCharDevQEnum, "NetCharDevQEnum"},
2233 {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"},
2234 {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"},
2235 {API_NetCharDevQPurge, "NetCharDevQPurge"},
2236 {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"},
2237 {API_NetMessageNameEnum, "NetMessageNameEnum"},
2238 {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"},
2239 {API_NetMessageNameAdd, "NetMessageNameAdd"},
2240 {API_NetMessageNameDel, "NetMessageNameDel"},
2241 {API_NetMessageNameFwd, "NetMessageNameFwd"},
2242 {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"},
2243 {API_NetMessageBufferSend, "NetMessageBufferSend"},
2244 {API_NetMessageFileSend, "NetMessageFileSend"},
2245 {API_NetMessageLogFileSet, "NetMessageLogFileSet"},
2246 {API_NetMessageLogFileGet, "NetMessageLogFileGet"},
2247 {API_NetServiceEnum, "NetServiceEnum"},
2248 {API_NetServiceInstall, "NetServiceInstall"},
2249 {API_NetServiceControl, "NetServiceControl"},
2250 {API_NetAccessEnum, "NetAccessEnum"},
2251 {API_NetAccessGetInfo, "NetAccessGetInfo"},
2252 {API_NetAccessSetInfo, "NetAccessSetInfo"},
2253 {API_NetAccessAdd, "NetAccessAdd"},
2254 {API_NetAccessDel, "NetAccessDel"},
2255 {API_NetGroupEnum, "NetGroupEnum"},
2256 {API_NetGroupAdd, "NetGroupAdd"},
2257 {API_NetGroupDel, "NetGroupDel"},
2258 {API_NetGroupAddUser, "NetGroupAddUser"},
2259 {API_NetGroupDelUser, "NetGroupDelUser"},
2260 {API_NetGroupGetUsers, "NetGroupGetUsers"},
2261 {API_NetUserEnum, "NetUserEnum"},
2262 {API_NetUserAdd, "NetUserAdd"},
2263 {API_NetUserDel, "NetUserDel"},
2264 {API_NetUserGetInfo, "NetUserGetInfo"},
2265 {API_NetUserSetInfo, "NetUserSetInfo"},
2266 {API_NetUserPasswordSet, "NetUserPasswordSet"},
2267 {API_NetUserGetGroups, "NetUserGetGroups"},
2268 {API_NetWkstaSetUID, "NetWkstaSetUID"},
2269 {API_NetWkstaGetInfo, "NetWkstaGetInfo"},
2270 {API_NetWkstaSetInfo, "NetWkstaSetInfo"},
2271 {API_NetUseEnum, "NetUseEnum"},
2272 {API_NetUseAdd, "NetUseAdd"},
2273 {API_NetUseDel, "NetUseDel"},
2274 {API_NetUseGetInfo, "NetUseGetInfo"},
2275 {API_WPrintQEnum, "WPrintQEnum"},
2276 {API_WPrintQGetInfo, "WPrintQGetInfo"},
2277 {API_WPrintQSetInfo, "WPrintQSetInfo"},
2278 {API_WPrintQAdd, "WPrintQAdd"},
2279 {API_WPrintQDel, "WPrintQDel"},
2280 {API_WPrintQPause, "WPrintQPause"},
2281 {API_WPrintQContinue, "WPrintQContinue"},
2282 {API_WPrintJobEnum, "WPrintJobEnum"},
2283 {API_WPrintJobGetInfo, "WPrintJobGetInfo"},
2284 {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"},
2285 {API_WPrintJobDel, "WPrintJobDel"},
2286 {API_WPrintJobPause, "WPrintJobPause"},
2287 {API_WPrintJobContinue, "WPrintJobContinue"},
2288 {API_WPrintDestEnum, "WPrintDestEnum"},
2289 {API_WPrintDestGetInfo, "WPrintDestGetInfo"},
2290 {API_WPrintDestControl, "WPrintDestControl"},
2291 {API_NetProfileSave, "NetProfileSave"},
2292 {API_NetProfileLoad, "NetProfileLoad"},
2293 {API_NetStatisticsGet, "NetStatisticsGet"},
2294 {API_NetStatisticsClear, "NetStatisticsClear"},
2295 {API_NetRemoteTOD, "NetRemoteTOD"},
2296 {API_WNetBiosEnum, "WNetBiosEnum"},
2297 {API_WNetBiosGetInfo, "WNetBiosGetInfo"},
2298 {API_NetServerEnum, "NetServerEnum"},
2299 {API_I_NetServerEnum, "I_NetServerEnum"},
2300 {API_NetServiceGetInfo, "NetServiceGetInfo"},
2301 {API_WPrintQPurge, "WPrintQPurge"},
2302 {API_NetServerEnum2, "NetServerEnum2"},
2303 {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"},
2304 {API_NetGroupGetInfo, "NetGroupGetInfo"},
2305 {API_NetGroupSetInfo, "NetGroupSetInfo"},
2306 {API_NetGroupSetUsers, "NetGroupSetUsers"},
2307 {API_NetUserSetGroups, "NetUserSetGroups"},
2308 {API_NetUserModalsGet, "NetUserModalsGet"},
2309 {API_NetUserModalsSet, "NetUserModalsSet"},
2310 {API_NetFileEnum2, "NetFileEnum2"},
2311 {API_NetUserAdd2, "NetUserAdd2"},
2312 {API_NetUserSetInfo2, "NetUserSetInfo2"},
2313 {API_NetUserPasswordSet2, "SetUserPassword"},
2314 {API_I_NetServerEnum2, "I_NetServerEnum2"},
2315 {API_NetConfigGet2, "NetConfigGet2"},
2316 {API_NetConfigGetAll2, "NetConfigGetAll2"},
2317 {API_NetGetDCName, "NetGetDCName"},
2318 {API_NetHandleGetInfo, "NetHandleGetInfo"},
2319 {API_NetHandleSetInfo, "NetHandleSetInfo"},
2320 {API_NetStatisticsGet2, "NetStatisticsGet2"},
2321 {API_WBuildGetInfo, "WBuildGetInfo"},
2322 {API_NetFileGetInfo2, "NetFileGetInfo2"},
2323 {API_NetFileClose2, "NetFileClose2"},
2324 {API_NetServerReqChallenge, "NetServerReqChallenge"},
2325 {API_NetServerAuthenticate, "NetServerAuthenticate"},
2326 {API_NetServerPasswordSet, "NetServerPasswordSet"},
2327 {API_WNetAccountDeltas, "WNetAccountDeltas"},
2328 {API_WNetAccountSync, "WNetAccountSync"},
2329 {API_NetUserEnum2, "NetUserEnum2"},
2330 {API_NetWkstaUserLogon, "NetWkstaUserLogon"},
2331 {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"},
2332 {API_NetLogonEnum, "NetLogonEnum"},
2333 {API_NetErrorLogRead, "NetErrorLogRead"},
2334 {API_I_NetPathType, "I_NetPathType"},
2335 {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"},
2336 {API_I_NetPathCompare, "I_NetPathCompare"},
2337 {API_I_NetNameValidate, "I_NetNameValidate"},
2338 {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"},
2339 {API_I_NetNameCompare, "I_NetNameCompare"},
2340 {API_NetAuditRead, "NetAuditRead"},
2341 {API_WPrintDestAdd, "WPrintDestAdd"},
2342 {API_WPrintDestSetInfo, "WPrintDestSetInfo"},
2343 {API_WPrintDestDel, "WPrintDestDel"},
2344 {API_NetUserValidate2, "NetUserValidate2"},
2345 {API_WPrintJobSetInfo, "WPrintJobSetInfo"},
2346 {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"},
2347 {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"},
2348 {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"},
2349 {API_TI_FTAbortVerify, "TI_FTAbortVerify"},
2350 {API_TI_FTGetInfo, "TI_FTGetInfo"},
2351 {API_TI_FTSetInfo, "TI_FTSetInfo"},
2352 {API_TI_FTLockDisk, "TI_FTLockDisk"},
2353 {API_TI_FTFixError, "TI_FTFixError"},
2354 {API_TI_FTAbortFix, "TI_FTAbortFix"},
2355 {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"},
2356 {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"},
2357 {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"},
2358 {API_NetAccessCheck, "NetAccessCheck"},
2359 {API_NetAlertRaise, "NetAlertRaise"},
2360 {API_NetAlertStart, "NetAlertStart"},
2361 {API_NetAlertStop, "NetAlertStop"},
2362 {API_NetAuditWrite, "NetAuditWrite"},
2363 {API_NetIRemoteAPI, "NetIRemoteAPI"},
2364 {API_NetServiceStatus, "NetServiceStatus"},
2365 {API_I_NetServerRegister, "I_NetServerRegister"},
2366 {API_I_NetServerDeregister, "I_NetServerDeregister"},
2367 {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"},
2368 {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"},
2369 {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"},
2370 {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"},
2371 {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"},
2372 {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"},
2373 {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2374 {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2375 {API_I_NetFileEntryMake, "I_NetFileEntryMake"},
2376 {API_I_NetFileEntryClear, "I_NetFileEntryClear"},
2377 {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"},
2378 {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"},
2379 {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"},
2380 {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"},
2381 {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"},
2382 {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"},
2383 {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"},
2384 {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"},
2385 {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"},
2386 {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"},
2387 {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"},
2388 {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"},
2389 {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"},
2390 {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"},
2391 {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"},
2392 {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"},
2393 {API_WIServerSetInfo, "WIServerSetInfo"},
2394 {API_WPrintDriverEnum, "WPrintDriverEnum"},
2395 {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"},
2396 {API_WPrintPortEnum, "WPrintPortEnum"},
2397 {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"},
2398 {API_WNetAccountUpdate, "WNetAccountUpdate"},
2399 {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"},
2400 {API_NetConfigSet, "NetConfigSet"},
2401 {API_WAccountsReplicate, "WAccountsReplicate"},
2402 {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"},
2403 {API_NetServerEnum3, "NetServerEnum3"},
2404 {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"},
2405 {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"},
2406 {API_NetAliasAdd, "NetAliasAdd"},
2407 {API_NetAliasDel, "NetAliasDel"},
2408 {API_NetAliasGetInfo, "NetAliasGetInfo"},
2409 {API_NetAliasSetInfo, "NetAliasSetInfo"},
2410 {API_NetAliasEnum, "NetAliasEnum"},
2411 {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"},
2412 {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"},
2413 {API_NetUserGetAppSel, "NetUserGetAppSel"},
2414 {API_NetUserSetAppSel, "NetUserSetAppSel"},
2415 {API_NetAppAdd, "NetAppAdd"},
2416 {API_NetAppDel, "NetAppDel"},
2417 {API_NetAppGetInfo, "NetAppGetInfo"},
2418 {API_NetAppSetInfo, "NetAppSetInfo"},
2419 {API_NetAppEnum, "NetAppEnum"},
2420 {API_NetUserDCDBInit, "NetUserDCDBInit"},
2421 {API_NetDASDAdd, "NetDASDAdd"},
2422 {API_NetDASDDel, "NetDASDDel"},
2423 {API_NetDASDGetInfo, "NetDASDGetInfo"},
2424 {API_NetDASDSetInfo, "NetDASDSetInfo"},
2425 {API_NetDASDEnum, "NetDASDEnum"},
2426 {API_NetDASDCheck, "NetDASDCheck"},
2427 {API_NetDASDCtl, "NetDASDCtl"},
2428 {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"},
2429 {API_NetUserPasswordSet3, "NetUserPasswordSet3"},
2430 {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"},
2431 {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"},
2432 {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"},
2433 {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"},
2434 {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"},
2435 {API_I_ShareAdd, "I_ShareAdd"},
2436 {API_I_AliasEnum, "I_AliasEnum"},
2437 {API_NetAccessApply, "NetAccessApply"},
2438 {API_WPrt16Query, "WPrt16Query"},
2439 {API_WPrt16Set, "WPrt16Set"},
2440 {API_NetUserDel100, "NetUserDel100"},
2441 {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"},
2442 {API_WRemoteTODSet, "WRemoteTODSet"},
2443 {API_WPrintJobMoveAll, "WPrintJobMoveAll"},
2444 {API_W16AppParmAdd, "W16AppParmAdd"},
2445 {API_W16AppParmDel, "W16AppParmDel"},
2446 {API_W16AppParmGet, "W16AppParmGet"},
2447 {API_W16AppParmSet, "W16AppParmSet"},
2448 {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"},
2449 {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"},
2450 {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"},
2451 {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"},
2452 {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"},
2453 {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"},
2454 {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"},
2455 {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"},
2456 {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"},
2457 {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"},
2458 {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"},
2459 {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"},
2460 {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"},
2461 {API_NetServerNameAdd, "NetServerNameAdd"},
2462 {API_NetServerNameDel, "NetServerNameDel"},
2463 {API_NetServerNameEnum, "NetServerNameEnum"},
2464 {API_I_WDASDEnum, "I_WDASDEnum"},
2465 {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"},
2466 {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"},
2470 static value_string_ext commands_ext = VALUE_STRING_EXT_INIT(commands);
2473 dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2474 proto_tree *tree, struct smb_info *smb_info,
2475 const struct lanman_desc *lanman, gboolean has_ent_count,
2478 smb_transact_info_t *trp;
2479 const item_list_t *resp_data_list;
2480 int offset, start_offset;
2483 const item_t *resp_data;
2484 proto_item *data_item;
2485 proto_tree *data_tree;
2486 proto_item *entry_item;
2487 proto_tree *entry_tree;
2491 trp = smb_info->sip->extra_info;
2494 * Find the item table for the matching request's detail level.
2496 for (resp_data_list = lanman->resp_data_list;
2497 resp_data_list->level != -1; resp_data_list++) {
2498 if (resp_data_list->level == trp->info_level)
2501 resp_data = resp_data_list->item_list;
2504 if (has_ent_count) {
2506 * The data is a list of entries; create a protocol tree item
2510 label = lanman->resp_data_entry_list_label;
2513 if (lanman->ett_data_entry_list != NULL)
2514 ett = *lanman->ett_data_entry_list;
2516 ett = ett_lanman_unknown_entries;
2517 data_item = proto_tree_add_text(tree, tvb, offset, -1, "%s",
2519 data_tree = proto_item_add_subtree(data_item, ett);
2526 * Just leave it at the top level.
2532 if (trp->data_descrip == NULL) {
2534 * This could happen if we only dissected
2535 * part of the request to which this is a
2536 * reply, e.g. if the request was split
2537 * across TCP segments and we weren't doing
2538 * TCP desegmentation, or if we had a snapshot
2539 * length that was too short.
2541 * We can't dissect the data; just show it as raw data or,
2542 * if we've already created a top-level item, note that
2543 * no descriptor is available.
2545 if (has_ent_count) {
2546 if (data_item != NULL) {
2547 proto_item_append_text(data_item,
2548 " (No descriptor available)");
2551 proto_tree_add_text(data_tree, tvb, offset, -1,
2552 "Data (no descriptor available)");
2554 offset += tvb_length_remaining(tvb, offset);
2557 * If we have an entry count, show all the entries,
2558 * with each one having a protocol tree item.
2560 * Otherwise, we just show one returned item, with
2561 * no protocol tree item.
2565 for (i = 0; i < ent_count; i++) {
2566 start_offset = offset;
2567 if (has_ent_count &&
2568 lanman->resp_data_element_item != NULL) {
2570 * Create a protocol tree item for the
2574 (*lanman->resp_data_element_item)
2575 (tvb, data_tree, offset);
2576 entry_tree = proto_item_add_subtree(
2578 *lanman->ett_resp_data_element_item);
2581 * Just leave it at the current
2585 entry_tree = data_tree;
2588 offset = dissect_transact_data(tvb, offset,
2589 convert, pinfo, entry_tree,
2590 trp->data_descrip, resp_data, &aux_count);
2592 /* auxiliary data */
2593 if (trp->aux_data_descrip != NULL) {
2594 for (j = 0; j < aux_count; j++) {
2595 offset = dissect_transact_data(
2596 tvb, offset, convert,
2599 lanman->resp_aux_data, NULL);
2603 if (entry_item != NULL) {
2605 * Set the length of the protocol tree
2606 * item for the entry.
2608 proto_item_set_len(entry_item,
2609 offset - start_offset);
2614 if (data_item != NULL) {
2616 * Set the length of the protocol tree item
2619 proto_item_set_len(data_item, offset);
2624 dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2625 packet_info *pinfo, proto_tree *parent_tree)
2627 smb_info_t *smb_info = pinfo->private_data;
2628 smb_transact_info_t *trp = NULL;
2629 int offset = 0, start_offset;
2633 const struct lanman_desc *lanman;
2634 proto_item *item = NULL;
2635 proto_tree *tree = NULL;
2636 guint descriptor_len;
2637 const gchar *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2639 gboolean has_ent_count;
2640 guint16 ent_count = 0, aux_count;
2642 proto_item *data_item;
2643 proto_tree *data_tree;
2645 if (smb_info->sip->extra_info_type == SMB_EI_TRI)
2646 trp = smb_info->sip->extra_info;
2648 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2650 if (p_tvb == NULL) {
2652 * Requests must have parameters.
2656 pinfo->current_proto = "LANMAN";
2658 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2661 item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2662 pd_tvb, 0, -1, FALSE);
2663 tree = proto_item_add_subtree(item, ett_lanman);
2666 if (smb_info->request) { /* this is a request */
2668 cmd = tvb_get_letohs(p_tvb, offset);
2669 if (check_col(pinfo->cinfo, COL_INFO)) {
2670 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str_ext(cmd, &commands_ext, "Unknown Command (%u)"));
2672 proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2677 return FALSE; /* cant dissect this request */
2681 * If we haven't already done so, save the function code in
2682 * the structure we were handed, so that it's available to
2683 * the code parsing the reply, and initialize the detail
2684 * level to -1, meaning "unknown".
2686 if (!pinfo->fd->flags.visited) {
2687 trp->lanman_cmd = cmd;
2688 trp->info_level = -1;
2689 trp->param_descrip=NULL;
2690 trp->data_descrip=NULL;
2691 trp->aux_data_descrip=NULL;
2694 /* parameter descriptor */
2695 param_descrip = tvb_get_const_stringz(p_tvb, offset, &descriptor_len);
2696 proto_tree_add_item(tree, hf_param_desc, p_tvb, offset,
2697 descriptor_len, TRUE);
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 data_descrip = tvb_get_const_stringz(p_tvb, offset, &descriptor_len);
2709 proto_tree_add_item(tree, hf_return_desc, p_tvb, offset,
2710 descriptor_len, TRUE);
2711 if (!pinfo->fd->flags.visited) {
2713 * Save the return descriptor for future use.
2715 DISSECTOR_ASSERT(trp->data_descrip == NULL);
2716 trp->data_descrip = g_strdup(data_descrip);
2718 offset += descriptor_len;
2720 lanman = find_lanman(cmd);
2722 /* request parameters */
2723 start_offset = offset;
2724 offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2725 param_descrip, lanman->req, &has_data);
2727 /* auxiliary data descriptor */
2728 if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2730 * There are more parameters left, so the next
2731 * item is the auxiliary data descriptor.
2733 aux_data_descrip = tvb_get_const_stringz(p_tvb, offset, &descriptor_len);
2734 proto_tree_add_item(tree, hf_aux_data_desc, p_tvb, offset,
2735 descriptor_len, TRUE);
2736 if (!pinfo->fd->flags.visited) {
2738 * Save the auxiliary data descriptor for
2741 DISSECTOR_ASSERT(trp->aux_data_descrip == NULL);
2742 trp->aux_data_descrip =
2743 g_strdup(aux_data_descrip);
2745 offset += descriptor_len;
2748 /* reset offset, we now start dissecting the data area */
2750 if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2752 * There's a send buffer item in the descriptor
2753 * string, and the data count in the transaction
2754 * is non-zero, so there's data to dissect.
2757 if (lanman->req_data_item != NULL) {
2759 * Create a protocol tree item for the data.
2761 data_item = (*lanman->req_data_item)(d_tvb,
2762 pinfo, tree, offset);
2763 data_tree = proto_item_add_subtree(data_item,
2764 *lanman->ett_req_data);
2767 * Just leave it at the top level.
2774 offset = dissect_transact_data(d_tvb, offset, -1,
2775 pinfo, data_tree, data_descrip, lanman->req_data,
2776 &aux_count); /* XXX - what about strings? */
2778 /* auxiliary data */
2779 if (aux_data_descrip != NULL) {
2780 for (i = 0; i < aux_count; i++) {
2781 offset = dissect_transact_data(d_tvb,
2782 offset, -1, pinfo, data_tree,
2784 lanman->req_aux_data, NULL);
2788 if (data_item != NULL) {
2790 * Set the length of the protocol tree item
2793 proto_item_set_len(data_item, offset);
2798 * This is a response.
2799 * Have we seen the request to which it's a response?
2802 return FALSE; /* no - can't dissect it */
2804 /* ok we have seen this one before */
2806 /* if it looks like an interim response, update COL_INFO and return */
2807 if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
2808 && ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
2810 if (check_col(pinfo->cinfo, COL_INFO)) {
2811 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2812 val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)"));
2814 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2819 if (check_col(pinfo->cinfo, COL_INFO)) {
2820 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2821 val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)"));
2823 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2826 lanman = find_lanman(trp->lanman_cmd);
2828 /* response parameters */
2831 status = tvb_get_letohs(p_tvb, offset);
2832 proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2836 convert = tvb_get_letohs(p_tvb, offset);
2837 proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2840 if (trp->param_descrip == NULL) {
2842 * This could happen if we only dissected
2843 * part of the request to which this is a
2844 * reply, e.g. if the request was split
2845 * across TCP segments and we weren't doing
2846 * TCP desegmentation, or if we had a snapshot
2847 * length that was too short.
2849 * We can't dissect the parameters; just show them
2852 proto_tree_add_text(tree, p_tvb, offset, -1,
2853 "Parameters (no descriptor available)");
2856 * We don't know whether we have a receive buffer,
2857 * as we don't have the descriptor; just show what
2858 * bytes purport to be data.
2860 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2861 proto_tree_add_text(tree, d_tvb, 0, -1,
2862 "Data (no descriptor available)");
2865 /* rest of the parameters */
2866 offset = dissect_response_parameters(p_tvb, offset,
2867 pinfo, tree, trp->param_descrip, lanman->resp,
2868 &has_data, &has_ent_count, &ent_count);
2870 /* reset offset, we now start dissecting the data area */
2873 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2875 * Well, there are bytes that purport to
2876 * be data, at least.
2880 * There's a receive buffer item
2881 * in the descriptor string, so
2882 * dissect it as response data.
2884 dissect_response_data(d_tvb, pinfo,
2885 convert, tree, smb_info, lanman,
2886 has_ent_count, ent_count);
2889 * There's no receive buffer item,
2890 * but we do have data, so just
2891 * show what bytes are data.
2893 proto_tree_add_text(tree, d_tvb, 0, -1,
2894 "Data (no receive buffer)");
2904 proto_register_pipe_lanman(void)
2906 static hf_register_info hf[] = {
2907 { &hf_function_code,
2908 { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
2909 &commands_ext, 0, "LANMAN Function Code/Command", HFILL }},
2912 { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2913 NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2916 { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2917 NULL, 0, "LANMAN Return Descriptor", HFILL }},
2919 { &hf_aux_data_desc,
2920 { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2921 NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2924 { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2925 NULL, 0, "LANMAN Detail Level", HFILL }},
2928 { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2929 NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2932 { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2933 NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2935 { &hf_continuation_from,
2936 { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2937 NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2940 { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2941 VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2944 { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2945 NULL, 0, "LANMAN Convert", HFILL }},
2948 { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2949 NULL, 0, "LANMAN Number of Entries", HFILL }},
2952 { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2953 NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2956 { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2957 NULL, 0, "LANMAN Name of Share", HFILL }},
2960 { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2961 VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2963 { &hf_share_comment,
2964 { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2965 NULL, 0, "LANMAN Share Comment", HFILL }},
2967 { &hf_share_permissions,
2968 { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2969 NULL, 0, "LANMAN Permissions on share", HFILL }},
2971 { &hf_share_max_uses,
2972 { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2973 NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2975 { &hf_share_current_uses,
2976 { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2977 NULL, 0, "LANMAN Current connections to share", HFILL }},
2980 { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2981 NULL, 0, "LANMAN Share Path", HFILL }},
2983 { &hf_share_password,
2984 { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2985 NULL, 0, "LANMAN Share Password", HFILL }},
2988 { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2989 NULL, 0, "LANMAN Name of Server", HFILL }},
2992 { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2993 NULL, 0, "LANMAN Server Major Version", HFILL }},
2996 { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2997 NULL, 0, "LANMAN Server Minor Version", HFILL }},
2999 { &hf_server_comment,
3000 { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
3001 NULL, 0, "LANMAN Server Comment", HFILL }},
3004 { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
3005 NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
3008 { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3009 NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
3012 { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
3013 NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
3016 { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
3017 NULL, 0, "LANMAN Current hour", HFILL }},
3020 { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
3021 NULL, 0, "LANMAN Current minute", HFILL }},
3024 { "Second", "lanman.second", FT_UINT8, BASE_DEC,
3025 NULL, 0, "LANMAN Current second", HFILL }},
3028 { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
3029 NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
3032 { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
3033 NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
3036 { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
3037 NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
3040 { "Day", "lanman.day", FT_UINT8, BASE_DEC,
3041 NULL, 0, "LANMAN Current day", HFILL }},
3044 { "Month", "lanman.month", FT_UINT8, BASE_DEC,
3045 NULL, 0, "LANMAN Current month", HFILL }},
3048 { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3049 NULL, 0, "LANMAN Current year", HFILL }},
3052 { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3053 VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3055 { &hf_enumeration_domain,
3056 { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3057 NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3060 { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE,
3061 NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }},
3063 { &hf_computer_name,
3064 { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3065 NULL, 0, "LANMAN Computer Name", HFILL }},
3068 { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3069 NULL, 0, "LANMAN User Name", HFILL }},
3072 { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3073 NULL, 0, "LANMAN Group Name", HFILL }},
3075 { &hf_workstation_domain,
3076 { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3077 NULL, 0, "LANMAN Workstation Domain", HFILL }},
3079 { &hf_workstation_major,
3080 { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3081 NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3083 { &hf_workstation_minor,
3084 { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3085 NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3088 { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3089 NULL, 0, "LANMAN Logon Domain", HFILL }},
3091 { &hf_other_domains,
3092 { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3093 NULL, 0, "LANMAN Other Domains", HFILL }},
3096 { "Password", "lanman.password", FT_STRING, BASE_NONE,
3097 NULL, 0, "LANMAN Password", HFILL }},
3099 { &hf_workstation_name,
3100 { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3101 NULL, 0, "LANMAN Workstation Name", HFILL }},
3104 { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3105 NULL, 0, "LANMAN UStruct Length", HFILL }},
3108 { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3109 VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3111 { &hf_privilege_level,
3112 { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3113 VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3115 { &hf_operator_privileges,
3116 { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3117 VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3120 { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3121 NULL, 0, "LANMAN Number of Logons", HFILL }},
3124 { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3125 NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3128 { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3129 NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3132 { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3133 NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3136 { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3137 NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3140 { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3141 NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3144 { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3145 NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3147 { &hf_password_can_change,
3148 { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3149 NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3151 { &hf_password_must_change,
3152 { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3153 NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3156 { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3157 NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3160 { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3161 VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3164 { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3165 NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3168 { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3169 NULL, 0, "LANMAN Comment", HFILL }},
3172 { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3173 NULL, 0, "LANMAN User Comment", HFILL }},
3176 { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3177 NULL, 0, "LANMAN Full Name", HFILL }},
3180 { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3181 NULL, 0, "LANMAN Home Directory", HFILL }},
3184 { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3185 NULL, 0, "LANMAN Parameters", HFILL }},
3188 { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3189 NULL, 0, "LANMAN Logon Server", HFILL }},
3191 /* XXX - we should have a value_string table for this */
3193 { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC,
3194 VALS(ms_country_codes), 0, "LANMAN Country Code", HFILL }},
3197 { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3198 NULL, 0, "LANMAN Workstations", HFILL }},
3201 { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3202 NULL, 0, "LANMAN Max Storage", HFILL }},
3204 { &hf_units_per_week,
3205 { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3206 NULL, 0, "LANMAN Units Per Week", HFILL }},
3209 { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3210 NULL, 0, "LANMAN Logon Hours", HFILL }},
3212 /* XXX - we should have a value_string table for this */
3214 { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3215 NULL, 0, "LANMAN Code Page", HFILL }},
3218 { "New Password", "lanman.new_password", FT_BYTES, BASE_NONE,
3219 NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3222 { "Old Password", "lanman.old_password", FT_BYTES, BASE_NONE,
3223 NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3226 { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3227 NULL, 0, "LANMAN Reserved", HFILL }},
3230 static gint *ett[] = {
3232 &ett_lanman_unknown_entries,
3233 &ett_lanman_unknown_entry,
3234 &ett_lanman_servers,
3241 proto_smb_lanman = proto_register_protocol(
3242 "Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3243 proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3244 proto_register_subtree_array(ett, array_length(ett));
3247 static heur_dissector_list_t smb_transact_heur_subdissector_list;
3249 static GHashTable *dcerpc_fragment_table = NULL;
3250 static GHashTable *dcerpc_reassembled_table = NULL;
3253 smb_dcerpc_reassembly_init(void)
3255 fragment_table_init(&dcerpc_fragment_table);
3256 reassembled_table_init(&dcerpc_reassembled_table);
3260 dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3261 proto_tree *tree, guint32 fid)
3263 smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
3265 gboolean save_fragmented;
3268 fragment_data *fd_head;
3270 proto_item *frag_tree_item;
3272 pinfo->dcetransportsalt = fid;
3275 * Offer desegmentation service to DCERPC if we have all the
3276 * data. Otherwise, reassembly is (probably) impossible.
3278 pinfo->can_desegment=0;
3279 pinfo->desegment_offset = 0;
3280 pinfo->desegment_len = 0;
3281 reported_len = tvb_reported_length(d_tvb);
3282 if(smb_dcerpc_reassembly && tvb_length(d_tvb) >= reported_len){
3283 pinfo->can_desegment=2;
3286 save_fragmented = pinfo->fragmented;
3289 /* if we are not offering desegmentation, just try the heuristics
3292 if(!pinfo->can_desegment){
3293 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3294 goto clean_up_and_exit;
3298 /* below this line, we know we are doing reassembly */
3301 * We have to keep track of reassemblies by FID, because
3302 * we could have more than one pipe operation in a frame
3303 * with NetBIOS-over-TCP.
3305 * We also have to keep track of them by direction, as
3306 * we might have reassemblies in progress in both directions.
3308 * We do that by combining the FID and the direction and
3309 * using that as the reassembly ID.
3311 * The direction is indicated by the SMB request/reply flag - data
3312 * from client to server is carried in requests, data from server
3313 * to client is carried in replies.
3315 * We know that the FID is only 16 bits long, so we put the
3316 * direction in bit 17.
3319 if (smb_priv->request)
3320 hash_key |= 0x10000;
3322 /* this is a new packet, see if we are already reassembling this
3323 pdu and if not, check if the dissector wants us
3326 if(!pinfo->fd->flags.visited){
3328 * This is the first pass.
3330 * Check if we are already reassembling this PDU or not;
3331 * we check for an in-progress reassembly for this FID
3332 * in this direction, by searching for its reassembly
3335 fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
3337 /* No reassembly, so this is a new pdu. check if the
3338 dissector wants us to reassemble it or if we
3339 already got the full pdu in this tvb.
3343 * Try the heuristic dissectors and see if we
3344 * find someone that recognizes this payload.
3346 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3348 /* no this didnt look like something we know */
3350 goto clean_up_and_exit;
3353 /* did the subdissector want us to reassemble any
3356 if(pinfo->desegment_len){
3357 fragment_add_check(d_tvb, 0, pinfo, fid,
3358 dcerpc_fragment_table,
3359 dcerpc_reassembled_table,
3360 0, reported_len, TRUE);
3361 fragment_set_tot_len(pinfo, fid,
3362 dcerpc_fragment_table,
3363 pinfo->desegment_len+reported_len);
3365 goto clean_up_and_exit;
3368 /* OK, we're already doing a reassembly for this FID.
3369 skip to last segment in the existing reassembly structure
3370 and add this fragment there
3372 XXX we might add code here to use any offset values
3373 we might pick up from the Read/Write calls instead of
3374 assuming we always get them in the correct order
3376 while(fd_head->next){
3377 fd_head=fd_head->next;
3379 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
3380 dcerpc_fragment_table, dcerpc_reassembled_table,
3381 fd_head->offset+fd_head->len,
3382 reported_len, TRUE);
3384 /* if we completed reassembly */
3386 new_tvb = tvb_new_child_real_data(d_tvb, fd_head->data,
3387 fd_head->datalen, fd_head->datalen);
3388 add_new_data_source(pinfo, new_tvb,
3390 pinfo->fragmented=FALSE;
3394 /* list what segments we have */
3395 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3396 tree, pinfo, d_tvb, &frag_tree_item);
3398 /* dissect the full PDU */
3399 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3401 goto clean_up_and_exit;
3405 * This is not the first pass; see if it's in the table of
3406 * reassembled packets.
3408 * XXX - we know that several of the arguments aren't going to
3409 * be used, so we pass bogus variables. Can we clean this
3410 * up so that we don't have to distinguish between the first
3411 * pass and subsequent passes?
3413 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
3414 dcerpc_reassembled_table, 0, 0, TRUE);
3416 /* we didnt find it, try any of the heuristic dissectors
3419 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3420 goto clean_up_and_exit;
3422 if(!(fd_head->flags&FD_DEFRAGMENTED)){
3423 /* we dont have a fully reassembled frame */
3424 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3425 goto clean_up_and_exit;
3428 /* it is reassembled but it was reassembled in a different frame */
3429 if(pinfo->fd->num!=fd_head->reassembled_in){
3430 proto_tree_add_uint(parent_tree, hf_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3431 goto clean_up_and_exit;
3435 /* display the reassembled pdu */
3436 new_tvb = tvb_new_child_real_data(d_tvb, fd_head->data,
3437 fd_head->datalen, fd_head->datalen);
3438 add_new_data_source(pinfo, new_tvb,
3440 pinfo->fragmented=FALSE;
3444 /* list what segments we have */
3445 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3446 tree, pinfo, d_tvb, &frag_tree_item);
3448 /* dissect the full PDU */
3449 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3454 /* clear out the variables */
3455 pinfo->private_data = smb_priv;
3456 pinfo->can_desegment=0;
3457 pinfo->desegment_offset = 0;
3458 pinfo->desegment_len = 0;
3461 call_dissector(data_handle, d_tvb, pinfo, parent_tree);
3463 pinfo->fragmented = save_fragmented;
3468 proto_register_pipe_dcerpc(void)
3470 register_heur_dissector_list("smb_transact", &smb_transact_heur_subdissector_list);
3471 register_init_routine(smb_dcerpc_reassembly_init);
3474 #define CALL_NAMED_PIPE 0x54
3475 #define WAIT_NAMED_PIPE 0x53
3476 #define PEEK_NAMED_PIPE 0x23
3477 #define Q_NM_P_HAND_STATE 0x21
3478 #define SET_NM_P_HAND_STATE 0x01
3479 #define Q_NM_PIPE_INFO 0x22
3480 #define TRANSACT_NM_PIPE 0x26
3481 #define RAW_READ_NM_PIPE 0x11
3482 #define RAW_WRITE_NM_PIPE 0x31
3484 static const value_string functions[] = {
3485 {CALL_NAMED_PIPE, "CallNamedPipe"},
3486 {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3487 {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3488 {Q_NM_P_HAND_STATE, "QNmPHandState"},
3489 {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3490 {Q_NM_PIPE_INFO, "QNmPipeInfo"},
3491 {TRANSACT_NM_PIPE, "TransactNmPipe"},
3492 {RAW_READ_NM_PIPE, "RawReadNmPipe"},
3493 {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3497 static const value_string pipe_status[] = {
3498 {1, "Disconnected by server"},
3500 {3, "Connection to server is OK"},
3501 {4, "Server end of pipe is closed"},
3505 #define PIPE_LANMAN 1
3506 #define PIPE_DCERPC 2
3508 /* decode the SMB pipe protocol
3510 pipe is the name of the pipe, e.g. LANMAN
3511 smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3514 smb_info->trans_subcmd gives us which pipe this response is for
3517 dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3518 tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3519 packet_info *pinfo, proto_tree *tree)
3521 smb_info_t *smb_info;
3522 smb_transact_info_t *tri;
3524 proto_item *pipe_item = NULL;
3525 proto_tree *pipe_tree = NULL;
3532 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3534 pinfo->current_proto = "SMB Pipe";
3536 smb_info = pinfo->private_data;
3541 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3542 if (check_col(pinfo->cinfo, COL_INFO)) {
3543 col_set_str(pinfo->cinfo, COL_INFO,
3544 smb_info->request ? "Request" : "Response");
3547 if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI)
3548 tri = smb_info->sip->extra_info;
3553 * Set up a subtree for the pipe protocol. (It might not contain
3557 sp_len = tvb_length(sp_tvb);
3561 pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3562 sp_tvb, 0, sp_len, FALSE);
3563 pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3568 * Do we have any setup words at all?
3570 if (s_tvb != NULL && tvb_length(s_tvb) != 0) {
3572 * Yes. The first of them is the function.
3574 function = tvb_get_letohs(s_tvb, offset);
3575 proto_tree_add_uint(pipe_tree, hf_pipe_function, s_tvb,
3576 offset, 2, function);
3578 if (check_col(pinfo->cinfo, COL_INFO)) {
3579 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3580 val_to_str(function, functions, "Unknown function (0x%04x)"),
3581 smb_info->request ? "Request" : "Response");
3584 tri->function = function;
3587 * The second of them depends on the function.
3591 case CALL_NAMED_PIPE:
3592 case WAIT_NAMED_PIPE:
3596 proto_tree_add_item(pipe_tree, hf_pipe_priority, s_tvb,
3600 case PEEK_NAMED_PIPE:
3601 case Q_NM_P_HAND_STATE:
3602 case SET_NM_P_HAND_STATE:
3603 case Q_NM_PIPE_INFO:
3604 case TRANSACT_NM_PIPE:
3605 case RAW_READ_NM_PIPE:
3606 case RAW_WRITE_NM_PIPE:
3610 fid = tvb_get_letohs(s_tvb, 2);
3611 dissect_smb_fid(s_tvb, pinfo, pipe_tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
3618 * It's something unknown.
3619 * XXX - put it into the tree?
3626 * This is either a response or a pipe transaction with
3627 * no setup information.
3629 * In the former case, we can get that information from
3630 * the matching request, if we saw it.
3632 * In the latter case, there is no function or FID.
3634 if (tri != NULL && tri->function != -1) {
3635 function = tri->function;
3636 proto_tree_add_uint(pipe_tree, hf_pipe_function, NULL,
3638 if (check_col(pinfo->cinfo, COL_INFO)) {
3639 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3640 val_to_str(function, functions, "Unknown function (0x%04x)"),
3641 smb_info->request ? "Request" : "Response");
3645 dissect_smb_fid(d_tvb, pinfo, pipe_tree, 0, 0, (guint16) fid, FALSE, FALSE, TRUE);
3653 * XXX - put the byte count and the pipe name into the tree as well;
3654 * that requires us to fetch a possibly-Unicode string.
3657 if(smb_info->request){
3658 if(strncmp(pipe,"LANMAN",6) == 0){
3659 trans_subcmd=PIPE_LANMAN;
3661 /* assume it is DCERPC */
3662 trans_subcmd=PIPE_DCERPC;
3665 if (!pinfo->fd->flags.visited) {
3668 tri->trans_subcmd = trans_subcmd;
3673 trans_subcmd = tri->trans_subcmd;
3678 * We don't know what type of pipe transaction this
3679 * was, so indicate that we didn't dissect it.
3686 case CALL_NAMED_PIPE:
3687 case TRANSACT_NM_PIPE:
3688 switch(trans_subcmd){
3691 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3696 * Only dissect this if we know the FID.
3701 return dissect_pipe_dcerpc(d_tvb, pinfo, tree,
3710 * We don't know the function; we dissect only LANMAN
3711 * pipe messages, not RPC pipe messages, in that case.
3713 switch(trans_subcmd){
3715 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3720 case WAIT_NAMED_PIPE:
3723 case PEEK_NAMED_PIPE:
3725 * Request contains no parameters or data.
3727 if (!smb_info->request) {
3731 proto_tree_add_item(pipe_tree, hf_pipe_peek_available,
3732 p_tvb, offset, 2, TRUE);
3734 proto_tree_add_item(pipe_tree, hf_pipe_peek_remaining,
3735 p_tvb, offset, 2, TRUE);
3737 proto_tree_add_item(pipe_tree, hf_pipe_peek_status,
3738 p_tvb, offset, 2, TRUE);
3743 case Q_NM_P_HAND_STATE:
3745 * Request contains no parameters or data.
3747 if (!smb_info->request) {
3750 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, FALSE);
3754 case SET_NM_P_HAND_STATE:
3756 * Response contains no parameters or data.
3758 if (smb_info->request) {
3761 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, TRUE);
3765 case Q_NM_PIPE_INFO:
3767 if (smb_info->request) {
3772 * Request contains an information level.
3774 info_level = tvb_get_letohs(p_tvb, offset);
3775 proto_tree_add_uint(pipe_tree, hf_pipe_getinfo_info_level,
3776 p_tvb, offset, 2, info_level);
3778 if (!pinfo->fd->flags.visited)
3779 tri->info_level = info_level;
3781 guint8 pipe_namelen;
3786 switch (tri->info_level) {
3789 proto_tree_add_item(pipe_tree,
3790 hf_pipe_getinfo_output_buffer_size,
3791 d_tvb, offset, 2, TRUE);
3793 proto_tree_add_item(pipe_tree,
3794 hf_pipe_getinfo_input_buffer_size,
3795 d_tvb, offset, 2, TRUE);
3797 proto_tree_add_item(pipe_tree,
3798 hf_pipe_getinfo_maximum_instances,
3799 d_tvb, offset, 1, TRUE);
3801 proto_tree_add_item(pipe_tree,
3802 hf_pipe_getinfo_current_instances,
3803 d_tvb, offset, 1, TRUE);
3805 pipe_namelen = tvb_get_guint8(d_tvb, offset);
3806 proto_tree_add_uint(pipe_tree,
3807 hf_pipe_getinfo_pipe_name_length,
3808 d_tvb, offset, 1, pipe_namelen);
3810 /* XXX - can this be Unicode? */
3811 proto_tree_add_item(pipe_tree,
3812 hf_pipe_getinfo_pipe_name,
3813 d_tvb, offset, pipe_namelen, TRUE);
3819 case RAW_READ_NM_PIPE:
3821 * Request contains no parameters or data.
3823 if (!smb_info->request) {
3827 offset = dissect_file_data(d_tvb, pipe_tree, 0,
3828 (guint16) tvb_reported_length(d_tvb),
3829 (guint16) tvb_reported_length(d_tvb));
3833 case RAW_WRITE_NM_PIPE:
3835 if (smb_info->request) {
3839 offset = dissect_file_data(d_tvb, pipe_tree,
3840 offset, (guint16) tvb_reported_length(d_tvb),
3841 (guint16) tvb_reported_length(d_tvb));
3845 proto_tree_add_item(pipe_tree,
3846 hf_pipe_write_raw_bytes_written,
3847 p_tvb, offset, 2, TRUE);
3856 proto_register_smb_pipe(void)
3858 static hf_register_info hf[] = {
3859 { &hf_pipe_function,
3860 { "Function", "pipe.function", FT_UINT16, BASE_HEX,
3861 VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3862 { &hf_pipe_priority,
3863 { "Priority", "pipe.priority", FT_UINT16, BASE_DEC,
3864 NULL, 0, "SMB Pipe Priority", HFILL }},
3865 { &hf_pipe_peek_available,
3866 { "Available Bytes", "pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3867 NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3868 { &hf_pipe_peek_remaining,
3869 { "Bytes Remaining", "pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3870 NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3871 { &hf_pipe_peek_status,
3872 { "Pipe Status", "pipe.peek.status", FT_UINT16, BASE_DEC,
3873 VALS(pipe_status), 0, NULL, HFILL }},
3874 { &hf_pipe_getinfo_info_level,
3875 { "Information Level", "pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3876 NULL, 0, "Information level of information to return", HFILL }},
3877 { &hf_pipe_getinfo_output_buffer_size,
3878 { "Output Buffer Size", "pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3879 NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3880 { &hf_pipe_getinfo_input_buffer_size,
3881 { "Input Buffer Size", "pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3882 NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3883 { &hf_pipe_getinfo_maximum_instances,
3884 { "Maximum Instances", "pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3885 NULL, 0, "Maximum allowed number of instances", HFILL }},
3886 { &hf_pipe_getinfo_current_instances,
3887 { "Current Instances", "pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3888 NULL, 0, "Current number of instances", HFILL }},
3889 { &hf_pipe_getinfo_pipe_name_length,
3890 { "Pipe Name Length", "pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3891 NULL, 0, "Length of pipe name", HFILL }},
3892 { &hf_pipe_getinfo_pipe_name,
3893 { "Pipe Name", "pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3894 NULL, 0, "Name of pipe", HFILL }},
3895 { &hf_pipe_write_raw_bytes_written,
3896 { "Bytes Written", "pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3897 NULL, 0, "Number of bytes written to the pipe", HFILL }},
3898 { &hf_pipe_fragment_overlap,
3899 { "Fragment overlap", "pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3900 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3901 { &hf_pipe_fragment_overlap_conflict,
3902 { "Conflicting data in fragment overlap", "pipe.fragment.overlap.conflict", FT_BOOLEAN,
3903 BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3904 { &hf_pipe_fragment_multiple_tails,
3905 { "Multiple tail fragments found", "pipe.fragment.multipletails", FT_BOOLEAN,
3906 BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3907 { &hf_pipe_fragment_too_long_fragment,
3908 { "Fragment too long", "pipe.fragment.toolongfragment", FT_BOOLEAN,
3909 BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3910 { &hf_pipe_fragment_error,
3911 { "Defragmentation error", "pipe.fragment.error", FT_FRAMENUM,
3912 BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3913 { &hf_pipe_fragment_count,
3914 { "Fragment count", "pipe.fragment.count", FT_UINT32,
3915 BASE_DEC, NULL, 0x0, NULL, HFILL }},
3916 { &hf_pipe_fragment,
3917 { "Fragment", "pipe.fragment", FT_FRAMENUM,
3918 BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3919 { &hf_pipe_fragments,
3920 { "Fragments", "pipe.fragments", FT_NONE,
3921 BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3922 { &hf_pipe_reassembled_in,
3923 { "This PDU is reassembled in", "pipe.reassembled_in", FT_FRAMENUM,
3924 BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3925 { &hf_pipe_reassembled_length,
3926 { "Reassembled SMB Pipe length", "pipe.reassembled.length", FT_UINT32,
3927 BASE_DEC, NULL, 0x0, "The total length of the reassembled payload", HFILL }},
3929 static gint *ett[] = {
3931 &ett_smb_pipe_fragment,
3932 &ett_smb_pipe_fragments,
3935 proto_smb_pipe = proto_register_protocol(
3936 "SMB Pipe Protocol", "SMB Pipe", "pipe");
3938 proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3939 proto_register_subtree_array(ett, array_length(ett));
3943 proto_reg_handoff_smb_pipe(void)
3945 data_handle = find_dissector("data");