2 XXX Fixme : shouldnt show [malformed frame] for long packets
6 * Routines for SMB named pipe packet dissection
7 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
8 * significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
11 * $Id: packet-smb-pipe.c,v 1.101 2004/06/09 09:24:07 sahlberg Exp $
13 * Ethereal - Network traffic analyzer
14 * By Gerald Combs <gerald@ethereal.com>
15 * Copyright 1998 Gerald Combs
17 * Copied from packet-pop.c
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #include <epan/packet.h>
46 #include "packet-smb-pipe.h"
47 #include "packet-smb-browse.h"
48 #include "packet-smb-common.h"
49 #include "packet-dcerpc.h"
50 #include "reassemble.h"
52 static int proto_smb_pipe = -1;
53 static int hf_pipe_function = -1;
54 static int hf_pipe_priority = -1;
55 static int hf_pipe_peek_available = -1;
56 static int hf_pipe_peek_remaining = -1;
57 static int hf_pipe_peek_status = -1;
58 static int hf_pipe_getinfo_info_level = -1;
59 static int hf_pipe_getinfo_output_buffer_size = -1;
60 static int hf_pipe_getinfo_input_buffer_size = -1;
61 static int hf_pipe_getinfo_maximum_instances = -1;
62 static int hf_pipe_getinfo_current_instances = -1;
63 static int hf_pipe_getinfo_pipe_name_length = -1;
64 static int hf_pipe_getinfo_pipe_name = -1;
65 static int hf_pipe_write_raw_bytes_written = -1;
66 static int hf_pipe_fragments = -1;
67 static int hf_pipe_fragment = -1;
68 static int hf_pipe_fragment_overlap = -1;
69 static int hf_pipe_fragment_overlap_conflict = -1;
70 static int hf_pipe_fragment_multiple_tails = -1;
71 static int hf_pipe_fragment_too_long_fragment = -1;
72 static int hf_pipe_fragment_error = -1;
73 static int hf_pipe_reassembled_in = -1;
75 static gint ett_smb_pipe = -1;
76 static gint ett_smb_pipe_fragment = -1;
77 static gint ett_smb_pipe_fragments = -1;
79 static const fragment_items smb_pipe_frag_items = {
80 &ett_smb_pipe_fragment,
81 &ett_smb_pipe_fragments,
84 &hf_pipe_fragment_overlap,
85 &hf_pipe_fragment_overlap_conflict,
86 &hf_pipe_fragment_multiple_tails,
87 &hf_pipe_fragment_too_long_fragment,
88 &hf_pipe_fragment_error,
93 static int proto_smb_lanman = -1;
94 static int hf_function_code = -1;
95 static int hf_param_desc = -1;
96 static int hf_return_desc = -1;
97 static int hf_aux_data_desc = -1;
98 static int hf_detail_level = -1;
99 static int hf_recv_buf_len = -1;
100 static int hf_send_buf_len = -1;
101 static int hf_continuation_from = -1;
102 static int hf_status = -1;
103 static int hf_convert = -1;
104 static int hf_ecount = -1;
105 static int hf_acount = -1;
106 static int hf_share_name = -1;
107 static int hf_share_type = -1;
108 static int hf_share_comment = -1;
109 static int hf_share_permissions = -1;
110 static int hf_share_max_uses = -1;
111 static int hf_share_current_uses = -1;
112 static int hf_share_path = -1;
113 static int hf_share_password = -1;
114 static int hf_server_name = -1;
115 static int hf_server_major = -1;
116 static int hf_server_minor = -1;
117 static int hf_server_comment = -1;
118 static int hf_abytes = -1;
119 static int hf_current_time = -1;
120 static int hf_msecs = -1;
121 static int hf_hour = -1;
122 static int hf_minute = -1;
123 static int hf_second = -1;
124 static int hf_hundredths = -1;
125 static int hf_tzoffset = -1;
126 static int hf_timeinterval = -1;
127 static int hf_day = -1;
128 static int hf_month = -1;
129 static int hf_year = -1;
130 static int hf_weekday = -1;
131 static int hf_enumeration_domain = -1;
132 static int hf_last_entry = -1;
133 static int hf_computer_name = -1;
134 static int hf_user_name = -1;
135 static int hf_group_name = -1;
136 static int hf_workstation_domain = -1;
137 static int hf_workstation_major = -1;
138 static int hf_workstation_minor = -1;
139 static int hf_logon_domain = -1;
140 static int hf_other_domains = -1;
141 static int hf_password = -1;
142 static int hf_workstation_name = -1;
143 static int hf_ustruct_size = -1;
144 static int hf_logon_code = -1;
145 static int hf_privilege_level = -1;
146 static int hf_operator_privileges = -1;
147 static int hf_num_logons = -1;
148 static int hf_bad_pw_count = -1;
149 static int hf_last_logon = -1;
150 static int hf_last_logoff = -1;
151 static int hf_logoff_time = -1;
152 static int hf_kickoff_time = -1;
153 static int hf_password_age = -1;
154 static int hf_password_can_change = -1;
155 static int hf_password_must_change = -1;
156 static int hf_script_path = -1;
157 static int hf_logoff_code = -1;
158 static int hf_duration = -1;
159 static int hf_comment = -1;
160 static int hf_user_comment = -1;
161 static int hf_full_name = -1;
162 static int hf_homedir = -1;
163 static int hf_parameters = -1;
164 static int hf_logon_server = -1;
165 static int hf_country_code = -1;
166 static int hf_workstations = -1;
167 static int hf_max_storage = -1;
168 static int hf_units_per_week = -1;
169 static int hf_logon_hours = -1;
170 static int hf_code_page = -1;
171 static int hf_new_password = -1;
172 static int hf_old_password = -1;
173 static int hf_reserved = -1;
175 static gint ett_lanman = -1;
176 static gint ett_lanman_unknown_entries = -1;
177 static gint ett_lanman_unknown_entry = -1;
178 static gint ett_lanman_shares = -1;
179 static gint ett_lanman_share = -1;
180 static gint ett_lanman_groups = -1;
181 static gint ett_lanman_servers = -1;
182 static gint ett_lanman_server = -1;
184 static dissector_handle_t data_handle;
189 * ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
191 * among other documents.
194 static const value_string status_vals[] = {
196 {5, "User has insufficient privilege"},
197 {65, "Network access is denied"},
198 {86, "The specified password is invalid"},
199 {SMBE_moredata, "Additional data is available"},
200 {2114, "Service is not running on the remote computer"},
201 {2123, "Supplied buffer is too small"},
202 {2141, "Server is not configured for transactions (IPC$ not shared)"},
203 {2212, "An error occurred while loading or running the logon script"},
204 {2214, "The logon was not validated by any server"},
205 {2217, "The logon server is running an older software version"},
206 {2221, "The user name was not found"},
207 {2226, "Operation not permitted on Backup Domain Controller"},
208 {2240, "The user is not allowed to logon from this computer"},
209 {2241, "The user is not allowed to logon at this time"},
210 {2242, "The user password has expired"},
211 {2243, "The password cannot be changed"},
212 {2246, "The password is too short"},
216 static const value_string privilege_vals[] = {
219 {2, "Administrator"},
223 static const value_string op_privilege_vals[] = {
224 {0, "Print operator"},
225 {1, "Communications operator"},
226 {2, "Server operator"},
227 {3, "Accounts operator"},
231 static const value_string weekday_vals[] = {
243 add_word_param(tvbuff_t *tvb, int offset, int count _U_,
244 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
249 proto_tree_add_item(tree, hf_index, tvb, offset, 2, TRUE);
251 WParam = tvb_get_letohs(tvb, offset);
252 proto_tree_add_text(tree, tvb, offset, 2,
253 "Word Param: %u (0x%04X)", WParam, WParam);
260 add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
261 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
266 proto_tree_add_item(tree, hf_index, tvb, offset, 4, TRUE);
268 LParam = tvb_get_letohl(tvb, offset);
269 proto_tree_add_text(tree, tvb, offset, 4,
270 "Doubleword Param: %u (0x%08X)", LParam, LParam);
277 add_byte_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
278 proto_tree *tree, int convert _U_, int hf_index)
283 proto_tree_add_item(tree, hf_index, tvb, offset, count, TRUE);
286 BParam = tvb_get_guint8(tvb, offset);
287 proto_tree_add_text(tree, tvb, offset, count,
288 "Byte Param: %u (0x%02X)",
291 proto_tree_add_text(tree, tvb, offset, count,
293 tvb_bytes_to_str(tvb, offset, count));
301 add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
302 proto_tree *tree _U_, int convert _U_, int hf_index _U_)
305 * This is for parameters that have descriptor entries but that
306 * are, in practice, just padding.
313 add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
314 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
316 if (hf_index != -1) {
317 proto_tree_add_text(tree, tvb, offset, 0,
319 proto_registrar_get_name(hf_index));
321 proto_tree_add_text(tree, tvb, offset, 0,
322 "String Param (Null pointer)");
327 add_string_param(tvbuff_t *tvb, int offset, int count _U_,
328 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
332 string_len = tvb_strsize(tvb, offset);
333 if (hf_index != -1) {
334 proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
337 proto_tree_add_text(tree, tvb, offset, string_len,
339 tvb_format_text(tvb, offset, string_len));
341 offset += string_len;
346 get_stringz_pointer_value(tvbuff_t *tvb, int offset, int convert, int *cptrp,
352 /* pointer to string */
353 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
357 if (tvb_offset_exists(tvb, cptr) &&
358 (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
359 string_len++; /* include the terminating '\0' */
361 return tvb_format_text(tvb, cptr, string_len - 1);
367 add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
368 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
374 string = get_stringz_pointer_value(tvb, offset, convert, &cptr,
379 if (string != NULL) {
380 if (hf_index != -1) {
381 proto_tree_add_item(tree, hf_index, tvb, cptr,
384 proto_tree_add_text(tree, tvb, cptr, string_len,
385 "String Param: %s", string);
388 if (hf_index != -1) {
389 proto_tree_add_text(tree, tvb, 0, 0,
390 "%s: <String goes past end of frame>",
391 proto_registrar_get_name(hf_index));
393 proto_tree_add_text(tree, tvb, 0, 0,
394 "String Param: <String goes past end of frame>");
402 add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
403 packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index)
407 /* pointer to byte array */
408 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
412 if (tvb_bytes_exist(tvb, cptr, count)) {
413 if (hf_index != -1) {
414 proto_tree_add_item(tree, hf_index, tvb, cptr,
417 proto_tree_add_text(tree, tvb, cptr, count,
419 tvb_bytes_to_str(tvb, cptr, count));
422 if (hf_index != -1) {
423 proto_tree_add_text(tree, tvb, 0, 0,
424 "%s: <Bytes go past end of frame>",
425 proto_registrar_get_name(hf_index));
427 proto_tree_add_text(tree, tvb, 0, 0,
428 "Byte Param: <Bytes goes past end of frame>");
436 add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
437 proto_tree *tree, int convert _U_, int hf_index)
439 struct smb_info *smb_info = pinfo->private_data;
440 smb_transact_info_t *trp = smb_info->sip->extra_info;
443 level = tvb_get_letohs(tvb, offset);
444 if (!pinfo->fd->flags.visited)
445 trp->info_level = level; /* remember this for the response */
446 proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
452 add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
453 proto_tree *tree, int convert _U_, int hf_index)
457 WParam = tvb_get_letohs(tvb, offset);
458 if (WParam == 0xffff) { /* -1 */
459 proto_tree_add_uint_format(tree, hf_index, tvb,
462 proto_registrar_get_name(hf_index));
464 proto_tree_add_uint(tree, hf_index, tvb,
472 add_server_type(tvbuff_t *tvb, int offset, int count _U_,
473 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
475 offset = dissect_smb_server_type_flags(
476 tvb, offset, pinfo, tree, NULL, FALSE);
481 add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
482 packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_)
484 offset = dissect_smb_server_type_flags(
485 tvb, offset, pinfo, tree, NULL, TRUE);
490 add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
491 proto_tree *tree, int convert _U_, int hf_index)
495 nstime.secs = tvb_get_letohl(tvb, offset);
497 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
498 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
499 time_secs_to_str(nstime.secs));
505 * Sigh. These are for handling Microsoft's annoying almost-UNIX-time-but-
506 * it's-local-time-not-UTC time.
509 add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
510 const char *absent_name)
515 nstime.secs = tvb_get_letohl(tvb, offset);
518 * Sigh. Sometimes it appears that -1 means "unknown", and
519 * sometimes it appears that 0 means "unknown", for the last
522 if (nstime.secs == -1 || nstime.secs == 0) {
523 proto_tree_add_time_format(tree, hf_index, tvb, offset, 4,
524 &nstime, "%s: %s", proto_registrar_get_name(hf_index),
528 * Run it through "gmtime()" to break it down, and then
529 * run it through "mktime()" to put it back together
532 tmp = gmtime(&nstime.secs);
533 tmp->tm_isdst = -1; /* we don't know if it's DST or not */
534 nstime.secs = mktime(tmp);
535 proto_tree_add_time(tree, hf_index, tvb, offset, 4,
543 add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
544 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
546 return add_abstime_common(tvb, offset, tree, hf_index, "Never");
550 add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
551 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
553 return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
557 add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
558 proto_tree *tree, int convert _U_, int hf_index)
562 nlogons = tvb_get_letohs(tvb, offset);
563 if (nlogons == 0xffff) /* -1 */
564 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 2,
565 nlogons, "%s: Unknown",
566 proto_registrar_get_name(hf_index));
568 proto_tree_add_uint(tree, hf_index, tvb, offset, 2,
575 add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
576 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
580 max_storage = tvb_get_letohl(tvb, offset);
581 if (max_storage == 0xffffffff)
582 proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
583 max_storage, "%s: No limit",
584 proto_registrar_get_name(hf_index));
586 proto_tree_add_uint(tree, hf_index, tvb, offset, 4,
593 add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
594 proto_tree *tree, int convert, int hf_index)
598 /* pointer to byte array */
599 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
603 if (tvb_bytes_exist(tvb, cptr, count)) {
606 * The logon hours should be exactly 21 bytes long.
608 * XXX - should actually carve up the bits;
609 * we need the units per week to do that, though.
611 proto_tree_add_item(tree, hf_index, tvb, cptr, count,
614 proto_tree_add_bytes_format(tree, hf_index, tvb,
615 cptr, count, tvb_get_ptr(tvb, cptr, count),
616 "%s: %s (wrong length, should be 21, is %d",
617 proto_registrar_get_name(hf_index),
618 tvb_bytes_to_str(tvb, cptr, count), count);
621 proto_tree_add_text(tree, tvb, 0, 0,
622 "%s: <Bytes go past end of frame>",
623 proto_registrar_get_name(hf_index));
630 add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
631 proto_tree *tree, int convert _U_, int hf_index)
635 tzoffset = tvb_get_letohs(tvb, offset);
637 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
638 tzoffset, "%s: %s east of UTC",
639 proto_registrar_get_name(hf_index),
640 time_secs_to_str(-tzoffset*60));
641 } else if (tzoffset > 0) {
642 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
643 tzoffset, "%s: %s west of UTC",
644 proto_registrar_get_name(hf_index),
645 time_secs_to_str(tzoffset*60));
647 proto_tree_add_int_format(tree, hf_tzoffset, tvb, offset, 2,
648 tzoffset, "%s: at UTC",
649 proto_registrar_get_name(hf_index));
656 add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
657 packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index)
659 guint16 timeinterval;
661 timeinterval = tvb_get_letohs(tvb, offset);
662 proto_tree_add_uint_format(tree, hf_timeinterval, tvb, offset, 2,
663 timeinterval, "%s: %f seconds", proto_registrar_get_name(hf_index),
670 add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
671 proto_tree *tree, int convert _U_, int hf_index _U_)
674 proto_tree_add_text(tree, tvb, offset, count,
675 "Bogus NetWkstaUserLogon parameters: length is %d, should be 54",
682 proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, TRUE);
689 proto_tree_add_item(tree, hf_password, tvb, offset, 15, TRUE);
695 /* workstation name */
696 proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, TRUE);
702 * The following data structure describes the Remote API requests we
705 * Simply fill in the number and parameter information.
706 * Try to keep them in order.
708 * We will extend this data structure as we try to decode more.
712 * This is a pointer to a function to process an item.
714 typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
718 * Type of an item; determines what parameter strings are valid for
722 PARAM_NONE, /* for the end-of-list stopper */
723 PARAM_WORD, /* 'W' or 'h' - 16-bit word */
724 PARAM_DWORD, /* 'D' or 'i' - 32-bit word */
725 PARAM_BYTES, /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
726 PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
730 * This structure describes an item; "hf_index" points to the index
731 * for the field corresponding to that item, "func" points to the
732 * function to use to add that item to the tree, and "type" is the
733 * type that the item is supposed to have.
742 * This structure describes a list of items; each list of items
743 * has a corresponding detail level.
747 const item_t *item_list;
753 proto_item *(*req_data_item)(tvbuff_t *, packet_info *,
756 const item_t *req_data;
757 const item_t *req_aux_data;
759 const gchar *resp_data_entry_list_label;
760 gint *ett_data_entry_list;
761 proto_item *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
763 gint *ett_resp_data_element_item;
764 const item_list_t *resp_data_list;
765 const item_t *resp_aux_data;
768 static int no_hf = -1; /* for padding crap */
770 static const item_t lm_params_req_netshareenum[] = {
771 { &hf_detail_level, add_detail_level, PARAM_WORD },
772 { &hf_recv_buf_len, add_word_param, PARAM_WORD },
773 { NULL, NULL, PARAM_NONE }
776 static const item_t lm_params_resp_netshareenum[] = {
777 { &hf_acount, add_word_param, PARAM_WORD },
778 { NULL, NULL, PARAM_NONE }
782 * Create a subtree for a share.
785 netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
788 return proto_tree_add_text(tree, tvb, offset, -1,
789 "Share %.13s", tvb_get_ptr(tvb, offset, 13));
794 static const item_t lm_null[] = {
795 { NULL, NULL, PARAM_NONE }
798 static const item_list_t lm_null_list[] = {
802 static const item_t lm_data_resp_netshareenum_1[] = {
803 { &hf_share_name, add_byte_param, PARAM_BYTES },
804 { &no_hf, add_pad_param, PARAM_BYTES },
805 { &hf_share_type, add_word_param, PARAM_WORD },
806 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
807 { NULL, NULL, PARAM_NONE }
810 static const item_list_t lm_data_resp_netshareenum[] = {
811 { 1, lm_data_resp_netshareenum_1 },
815 static const item_t lm_params_req_netsharegetinfo[] = {
816 { &hf_share_name, add_string_param, PARAM_STRINGZ },
817 { &hf_detail_level, add_detail_level, PARAM_WORD },
818 { NULL, NULL, PARAM_NONE }
821 static const item_t lm_params_resp_netsharegetinfo[] = {
822 { &hf_abytes, add_word_param, PARAM_WORD },
823 { NULL, NULL, PARAM_NONE }
826 static const item_t lm_data_resp_netsharegetinfo_0[] = {
827 { &hf_share_name, add_byte_param, PARAM_BYTES },
828 { NULL, NULL, PARAM_NONE }
831 static const item_t lm_data_resp_netsharegetinfo_1[] = {
832 { &hf_share_name, add_byte_param, PARAM_BYTES },
833 { &no_hf, add_pad_param, PARAM_BYTES },
834 { &hf_share_type, add_word_param, PARAM_WORD },
835 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
836 { NULL, NULL, PARAM_NONE }
839 static const item_t lm_data_resp_netsharegetinfo_2[] = {
840 { &hf_share_name, add_byte_param, PARAM_BYTES },
841 { &no_hf, add_pad_param, PARAM_BYTES },
842 { &hf_share_type, add_word_param, PARAM_WORD },
843 { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
844 { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
845 { &hf_share_max_uses, add_max_uses, PARAM_WORD },
846 { &hf_share_current_uses, add_word_param, PARAM_WORD },
847 { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
848 { &hf_share_password, add_byte_param, PARAM_BYTES },
849 { NULL, NULL, PARAM_NONE }
852 static const item_list_t lm_data_resp_netsharegetinfo[] = {
853 { 0, lm_data_resp_netsharegetinfo_0 },
854 { 1, lm_data_resp_netsharegetinfo_1 },
855 { 2, lm_data_resp_netsharegetinfo_2 },
859 static const item_t lm_params_req_netservergetinfo[] = {
860 { &hf_detail_level, add_detail_level, PARAM_WORD },
861 { NULL, NULL, PARAM_NONE }
864 static const item_t lm_params_resp_netservergetinfo[] = {
865 { &hf_abytes, add_word_param, PARAM_WORD },
866 { NULL, NULL, PARAM_NONE }
869 static const item_t lm_data_serverinfo_0[] = {
870 { &hf_server_name, add_byte_param, PARAM_BYTES },
871 { NULL, NULL, PARAM_NONE }
874 static const item_t lm_data_serverinfo_1[] = {
875 { &hf_server_name, add_byte_param, PARAM_BYTES },
876 { &hf_server_major, add_byte_param, PARAM_BYTES },
877 { &hf_server_minor, add_byte_param, PARAM_BYTES },
878 { &no_hf, add_server_type, PARAM_DWORD },
879 { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
880 { NULL, NULL, PARAM_NONE }
883 static const item_list_t lm_data_serverinfo[] = {
884 { 0, lm_data_serverinfo_0 },
885 { 1, lm_data_serverinfo_1 },
889 static const item_t lm_params_req_netusergetinfo[] = {
890 { &hf_user_name, add_string_param, PARAM_STRINGZ },
891 { &hf_detail_level, add_detail_level, PARAM_WORD },
892 { NULL, NULL, PARAM_NONE }
895 static const item_t lm_params_resp_netusergetinfo[] = {
896 { &hf_abytes, add_word_param, PARAM_WORD },
897 { NULL, NULL, PARAM_NONE }
900 static const item_t lm_data_resp_netusergetinfo_11[] = {
901 { &hf_user_name, add_byte_param, PARAM_BYTES },
902 { &no_hf, add_pad_param, PARAM_BYTES },
903 { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
904 { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
905 { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
906 { &hf_privilege_level, add_word_param, PARAM_WORD },
907 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
908 { &hf_password_age, add_reltime, PARAM_DWORD },
909 { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
910 { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
911 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
912 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
913 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
914 { &hf_num_logons, add_nlogons, PARAM_WORD },
915 { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
916 { &hf_country_code, add_word_param, PARAM_WORD },
917 { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
918 { &hf_max_storage, add_max_storage, PARAM_DWORD },
919 { &hf_units_per_week, add_word_param, PARAM_WORD },
920 { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
921 { &hf_code_page, add_word_param, PARAM_WORD },
922 { NULL, NULL, PARAM_NONE }
925 static const item_list_t lm_data_resp_netusergetinfo[] = {
926 { 11, lm_data_resp_netusergetinfo_11 },
930 static const item_t lm_params_req_netusergetgroups[] = {
931 { &hf_user_name, add_string_param, PARAM_STRINGZ },
932 { &hf_detail_level, add_detail_level, PARAM_WORD },
933 { NULL, NULL, PARAM_NONE }
936 static const item_t lm_params_resp_netusergetgroups[] = {
937 { &hf_abytes, add_word_param, PARAM_WORD },
938 { NULL, NULL, PARAM_NONE }
941 static const item_t lm_data_resp_netusergetgroups_0[] = {
942 { &hf_group_name, add_byte_param, PARAM_BYTES },
943 { NULL, NULL, PARAM_NONE }
946 static const item_list_t lm_data_resp_netusergetgroups[] = {
947 { 0, lm_data_resp_netusergetgroups_0 },
952 * Has no detail level; make it the default.
954 static const item_t lm_data_resp_netremotetod_nolevel[] = {
955 { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
956 { &hf_msecs, add_dword_param, PARAM_DWORD },
957 { &hf_hour, add_byte_param, PARAM_BYTES },
958 { &hf_minute, add_byte_param, PARAM_BYTES },
959 { &hf_second, add_byte_param, PARAM_BYTES },
960 { &hf_hundredths, add_byte_param, PARAM_BYTES },
961 { &hf_tzoffset, add_tzoffset, PARAM_WORD },
962 { &hf_timeinterval, add_timeinterval, PARAM_WORD },
963 { &hf_day, add_byte_param, PARAM_BYTES },
964 { &hf_month, add_byte_param, PARAM_BYTES },
965 { &hf_year, add_word_param, PARAM_WORD },
966 { &hf_weekday, add_byte_param, PARAM_BYTES },
967 { NULL, NULL, PARAM_NONE }
970 static const item_list_t lm_data_resp_netremotetod[] = {
971 { -1, lm_data_resp_netremotetod_nolevel },
974 static const item_t lm_params_req_netserverenum2[] = {
975 { &hf_detail_level, add_detail_level, PARAM_WORD },
976 { &no_hf, add_server_type_info, PARAM_DWORD },
977 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
978 { NULL, NULL, PARAM_NONE }
982 * Create a subtree for a server.
985 netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
988 return proto_tree_add_text(tree, tvb, offset, -1,
989 "Server %.16s", tvb_get_ptr(tvb, offset, 16));
994 static const item_t lm_params_resp_netserverenum2[] = {
995 { &hf_acount, add_word_param, PARAM_WORD },
996 { NULL, NULL, PARAM_NONE }
1000 static const item_t lm_params_req_netserverenum3[] = {
1001 { &hf_detail_level, add_detail_level, PARAM_WORD },
1002 { &no_hf, add_server_type_info, PARAM_DWORD },
1003 { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
1004 { &hf_last_entry, add_string_param, PARAM_STRINGZ },
1005 { NULL, NULL, PARAM_NONE }
1009 static const item_t lm_params_req_netwkstagetinfo[] = {
1010 { &hf_detail_level, add_detail_level, PARAM_WORD },
1011 { NULL, NULL, PARAM_NONE }
1014 static const item_t lm_params_resp_netwkstagetinfo[] = {
1015 { &hf_abytes, add_word_param, PARAM_WORD },
1016 { NULL, NULL, PARAM_NONE }
1019 static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1020 { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1021 { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1022 { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1023 { &hf_workstation_major, add_byte_param, PARAM_BYTES },
1024 { &hf_workstation_minor, add_byte_param, PARAM_BYTES },
1025 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1026 { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1027 { NULL, NULL, PARAM_NONE }
1030 static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1031 { 10, lm_data_resp_netwkstagetinfo_10 },
1035 static const item_t lm_params_req_netwkstauserlogon[] = {
1036 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1037 { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1038 { &hf_detail_level, add_detail_level, PARAM_WORD },
1039 { &no_hf, add_logon_args, PARAM_BYTES },
1040 { &hf_ustruct_size, add_word_param, PARAM_WORD },
1041 { NULL, NULL, PARAM_NONE }
1044 static const item_t lm_params_resp_netwkstauserlogon[] = {
1045 { &hf_abytes, add_word_param, PARAM_WORD },
1046 { NULL, NULL, PARAM_NONE }
1049 static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1050 { &hf_logon_code, add_word_param, PARAM_WORD },
1051 { &hf_user_name, add_byte_param, PARAM_BYTES },
1052 { &no_hf, add_pad_param, PARAM_BYTES },
1053 { &hf_privilege_level, add_word_param, PARAM_WORD },
1054 { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1055 { &hf_num_logons, add_nlogons, PARAM_WORD },
1056 { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1057 { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1058 { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1059 { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1060 { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1061 { &hf_password_age, add_reltime, PARAM_DWORD },
1062 { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1063 { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1064 { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1065 { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1066 { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1067 { &hf_reserved, add_dword_param, PARAM_DWORD },
1068 { NULL, NULL, PARAM_NONE }
1071 static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1072 { 1, lm_data_resp_netwkstauserlogon_1 },
1076 static const item_t lm_params_req_netwkstauserlogoff[] = {
1077 { &hf_user_name, add_byte_param, PARAM_BYTES },
1078 { &no_hf, add_pad_param, PARAM_BYTES },
1079 { &hf_workstation_name, add_byte_param, PARAM_BYTES },
1080 { NULL, NULL, PARAM_NONE }
1083 static const item_t lm_params_resp_netwkstauserlogoff[] = {
1084 { &hf_abytes, add_word_param, PARAM_WORD },
1085 { NULL, NULL, PARAM_NONE }
1088 static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1089 { &hf_logoff_code, add_word_param, PARAM_WORD },
1090 { &hf_duration, add_reltime, PARAM_DWORD },
1091 { &hf_num_logons, add_nlogons, PARAM_WORD },
1092 { NULL, NULL, PARAM_NONE }
1095 static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1096 { 1, lm_data_resp_netwkstauserlogoff_1 },
1100 static const item_t lm_params_req_samoemchangepassword[] = {
1101 { &hf_user_name, add_string_param, PARAM_STRINGZ },
1102 { NULL, NULL, PARAM_NONE }
1105 static const item_t lm_data_req_samoemchangepassword[] = {
1106 { &hf_new_password, add_byte_param, PARAM_BYTES },
1107 { &hf_old_password, add_byte_param, PARAM_BYTES },
1108 { NULL, NULL, PARAM_NONE }
1111 #define API_NetShareEnum 0
1112 #define API_NetShareGetInfo 1
1113 #define API_NetShareSetInfo 2
1114 #define API_NetShareAdd 3
1115 #define API_NetShareDel 4
1116 #define API_NetShareCheck 5
1117 #define API_NetSessionEnum 6
1118 #define API_NetSessionGetInfo 7
1119 #define API_NetSessionDel 8
1120 #define API_WconnectionEnum 9
1121 #define API_NetFileEnum 10
1122 #define API_NetFileGetInfo 11
1123 #define API_NetFileClose 12
1124 #define API_NetServerGetInfo 13
1125 #define API_NetServerSetInfo 14
1126 #define API_NetServerDiskEnum 15
1127 #define API_NetServerAdminCommand 16
1128 #define API_NetAuditOpen 17
1129 #define API_NetAuditClear 18
1130 #define API_NetErrorLogOpen 19
1131 #define API_NetErrorLogClear 20
1132 #define API_NetCharDevEnum 21
1133 #define API_NetCharDevGetInfo 22
1134 #define API_NetCharDevControl 23
1135 #define API_NetCharDevQEnum 24
1136 #define API_NetCharDevQGetInfo 25
1137 #define API_NetCharDevQSetInfo 26
1138 #define API_NetCharDevQPurge 27
1139 #define API_NetCharDevQPurgeSelf 28
1140 #define API_NetMessageNameEnum 29
1141 #define API_NetMessageNameGetInfo 30
1142 #define API_NetMessageNameAdd 31
1143 #define API_NetMessageNameDel 32
1144 #define API_NetMessageNameFwd 33
1145 #define API_NetMessageNameUnFwd 34
1146 #define API_NetMessageBufferSend 35
1147 #define API_NetMessageFileSend 36
1148 #define API_NetMessageLogFileSet 37
1149 #define API_NetMessageLogFileGet 38
1150 #define API_NetServiceEnum 39
1151 #define API_NetServiceInstall 40
1152 #define API_NetServiceControl 41
1153 #define API_NetAccessEnum 42
1154 #define API_NetAccessGetInfo 43
1155 #define API_NetAccessSetInfo 44
1156 #define API_NetAccessAdd 45
1157 #define API_NetAccessDel 46
1158 #define API_NetGroupEnum 47
1159 #define API_NetGroupAdd 48
1160 #define API_NetGroupDel 49
1161 #define API_NetGroupAddUser 50
1162 #define API_NetGroupDelUser 51
1163 #define API_NetGroupGetUsers 52
1164 #define API_NetUserEnum 53
1165 #define API_NetUserAdd 54
1166 #define API_NetUserDel 55
1167 #define API_NetUserGetInfo 56
1168 #define API_NetUserSetInfo 57
1169 #define API_NetUserPasswordSet 58
1170 #define API_NetUserGetGroups 59
1171 /*This line and number replaced a Dead Entry for 60 */
1172 /*This line and number replaced a Dead Entry for 61 */
1173 #define API_NetWkstaSetUID 62
1174 #define API_NetWkstaGetInfo 63
1175 #define API_NetWkstaSetInfo 64
1176 #define API_NetUseEnum 65
1177 #define API_NetUseAdd 66
1178 #define API_NetUseDel 67
1179 #define API_NetUseGetInfo 68
1180 #define API_WPrintQEnum 69
1181 #define API_WPrintQGetInfo 70
1182 #define API_WPrintQSetInfo 71
1183 #define API_WPrintQAdd 72
1184 #define API_WPrintQDel 73
1185 #define API_WPrintQPause 74
1186 #define API_WPrintQContinue 75
1187 #define API_WPrintJobEnum 76
1188 #define API_WPrintJobGetInfo 77
1189 #define API_WPrintJobSetInfo_OLD 78
1190 /* This line and number replaced a Dead Entry for 79 */
1191 /* This line and number replaced a Dead Entry for 80 */
1192 #define API_WPrintJobDel 81
1193 #define API_WPrintJobPause 82
1194 #define API_WPrintJobContinue 83
1195 #define API_WPrintDestEnum 84
1196 #define API_WPrintDestGetInfo 85
1197 #define API_WPrintDestControl 86
1198 #define API_NetProfileSave 87
1199 #define API_NetProfileLoad 88
1200 #define API_NetStatisticsGet 89
1201 #define API_NetStatisticsClear 90
1202 #define API_NetRemoteTOD 91
1203 #define API_WNetBiosEnum 92
1204 #define API_WNetBiosGetInfo 93
1205 #define API_NetServerEnum 94
1206 #define API_I_NetServerEnum 95
1207 #define API_NetServiceGetInfo 96
1208 /* This line and number replaced a Dead Entry for 97 */
1209 /* This line and number replaced a Dead Entry for 98 */
1210 /* This line and number replaced a Dead Entry for 99 */
1211 /* This line and number replaced a Dead Entry for 100 */
1212 /* This line and number replaced a Dead Entry for 101 */
1213 /* This line and number replaced a Dead Entry for 102 */
1214 #define API_WPrintQPurge 103
1215 #define API_NetServerEnum2 104
1216 #define API_NetAccessGetUserPerms 105
1217 #define API_NetGroupGetInfo 106
1218 #define API_NetGroupSetInfo 107
1219 #define API_NetGroupSetUsers 108
1220 #define API_NetUserSetGroups 109
1221 #define API_NetUserModalsGet 110
1222 #define API_NetUserModalsSet 111
1223 #define API_NetFileEnum2 112
1224 #define API_NetUserAdd2 113
1225 #define API_NetUserSetInfo2 114
1226 #define API_NetUserPasswordSet2 115
1227 #define API_I_NetServerEnum2 116
1228 #define API_NetConfigGet2 117
1229 #define API_NetConfigGetAll2 118
1230 #define API_NetGetDCName 119
1231 #define API_NetHandleGetInfo 120
1232 #define API_NetHandleSetInfo 121
1233 #define API_NetStatisticsGet2 122
1234 #define API_WBuildGetInfo 123
1235 #define API_NetFileGetInfo2 124
1236 #define API_NetFileClose2 125
1237 #define API_NetServerReqChallenge 126
1238 #define API_NetServerAuthenticate 127
1239 #define API_NetServerPasswordSet 128
1240 #define API_WNetAccountDeltas 129
1241 #define API_WNetAccountSync 130
1242 #define API_NetUserEnum2 131
1243 #define API_NetWkstaUserLogon 132
1244 #define API_NetWkstaUserLogoff 133
1245 #define API_NetLogonEnum 134
1246 #define API_NetErrorLogRead 135
1247 #define API_I_NetPathType 136
1248 #define API_I_NetPathCanonicalize 137
1249 #define API_I_NetPathCompare 138
1250 #define API_I_NetNameValidate 139
1251 #define API_I_NetNameCanonicalize 140
1252 #define API_I_NetNameCompare 141
1253 #define API_NetAuditRead 142
1254 #define API_WPrintDestAdd 143
1255 #define API_WPrintDestSetInfo 144
1256 #define API_WPrintDestDel 145
1257 #define API_NetUserValidate2 146
1258 #define API_WPrintJobSetInfo 147
1259 #define API_TI_NetServerDiskEnum 148
1260 #define API_TI_NetServerDiskGetInfo 149
1261 #define API_TI_FTVerifyMirror 150
1262 #define API_TI_FTAbortVerify 151
1263 #define API_TI_FTGetInfo 152
1264 #define API_TI_FTSetInfo 153
1265 #define API_TI_FTLockDisk 154
1266 #define API_TI_FTFixError 155
1267 #define API_TI_FTAbortFix 156
1268 #define API_TI_FTDiagnoseError 157
1269 #define API_TI_FTGetDriveStats 158
1270 /* This line and number replaced a Dead Entry for 159 */
1271 #define API_TI_FTErrorGetInfo 160
1272 /* This line and number replaced a Dead Entry for 161 */
1273 /* This line and number replaced a Dead Entry for 162 */
1274 #define API_NetAccessCheck 163
1275 #define API_NetAlertRaise 164
1276 #define API_NetAlertStart 165
1277 #define API_NetAlertStop 166
1278 #define API_NetAuditWrite 167
1279 #define API_NetIRemoteAPI 168
1280 #define API_NetServiceStatus 169
1281 #define API_I_NetServerRegister 170
1282 #define API_I_NetServerDeregister 171
1283 #define API_I_NetSessionEntryMake 172
1284 #define API_I_NetSessionEntryClear 173
1285 #define API_I_NetSessionEntryGetInfo 174
1286 #define API_I_NetSessionEntrySetInfo 175
1287 #define API_I_NetConnectionEntryMake 176
1288 #define API_I_NetConnectionEntryClear 177
1289 #define API_I_NetConnectionEntrySetInfo 178
1290 #define API_I_NetConnectionEntryGetInfo 179
1291 #define API_I_NetFileEntryMake 180
1292 #define API_I_NetFileEntryClear 181
1293 #define API_I_NetFileEntrySetInfo 182
1294 #define API_I_NetFileEntryGetInfo 183
1295 #define API_AltSrvMessageBufferSend 184
1296 #define API_AltSrvMessageFileSend 185
1297 #define API_wI_NetRplWkstaEnum 186
1298 #define API_wI_NetRplWkstaGetInfo 187
1299 #define API_wI_NetRplWkstaSetInfo 188
1300 #define API_wI_NetRplWkstaAdd 189
1301 #define API_wI_NetRplWkstaDel 190
1302 #define API_wI_NetRplProfileEnum 191
1303 #define API_wI_NetRplProfileGetInfo 192
1304 #define API_wI_NetRplProfileSetInfo 193
1305 #define API_wI_NetRplProfileAdd 194
1306 #define API_wI_NetRplProfileDel 195
1307 #define API_wI_NetRplProfileClone 196
1308 #define API_wI_NetRplBaseProfileEnum 197
1309 /* This line and number replaced a Dead Entry for 198 */
1310 /* This line and number replaced a Dead Entry for 199 */
1311 /* This line and number replaced a Dead Entry for 200 */
1312 #define API_WIServerSetInfo 201
1313 /* This line and number replaced a Dead Entry for 202 */
1314 /* This line and number replaced a Dead Entry for 203 */
1315 /* This line and number replaced a Dead Entry for 204 */
1316 #define API_WPrintDriverEnum 205
1317 #define API_WPrintQProcessorEnum 206
1318 #define API_WPrintPortEnum 207
1319 #define API_WNetWriteUpdateLog 208
1320 #define API_WNetAccountUpdate 209
1321 #define API_WNetAccountConfirmUpdate 210
1322 #define API_NetConfigSet 211
1323 #define API_WAccountsReplicate 212
1324 /* 213 is used by WfW */
1325 #define API_SamOEMChgPasswordUser2_P 214
1326 #define API_NetServerEnum3 215
1327 /* XXX - what about 216 through 249? */
1328 #define API_WPrintDriverGetInfo 250
1329 #define API_WPrintDriverSetInfo 251
1330 #define API_NetAliasAdd 252
1331 #define API_NetAliasDel 253
1332 #define API_NetAliasGetInfo 254
1333 #define API_NetAliasSetInfo 255
1334 #define API_NetAliasEnum 256
1335 #define API_NetUserGetLogonAsn 257
1336 #define API_NetUserSetLogonAsn 258
1337 #define API_NetUserGetAppSel 259
1338 #define API_NetUserSetAppSel 260
1339 #define API_NetAppAdd 261
1340 #define API_NetAppDel 262
1341 #define API_NetAppGetInfo 263
1342 #define API_NetAppSetInfo 264
1343 #define API_NetAppEnum 265
1344 #define API_NetUserDCDBInit 266
1345 #define API_NetDASDAdd 267
1346 #define API_NetDASDDel 268
1347 #define API_NetDASDGetInfo 269
1348 #define API_NetDASDSetInfo 270
1349 #define API_NetDASDEnum 271
1350 #define API_NetDASDCheck 272
1351 #define API_NetDASDCtl 273
1352 #define API_NetUserRemoteLogonCheck 274
1353 #define API_NetUserPasswordSet3 275
1354 #define API_NetCreateRIPLMachine 276
1355 #define API_NetDeleteRIPLMachine 277
1356 #define API_NetGetRIPLMachineInfo 278
1357 #define API_NetSetRIPLMachineInfo 279
1358 #define API_NetEnumRIPLMachine 280
1359 #define API_I_ShareAdd 281
1360 #define API_I_AliasEnum 282
1361 #define API_NetAccessApply 283
1362 #define API_WPrt16Query 284
1363 #define API_WPrt16Set 285
1364 #define API_NetUserDel100 286
1365 #define API_NetUserRemoteLogonCheck2 287
1366 #define API_WRemoteTODSet 294
1367 #define API_WPrintJobMoveAll 295
1368 #define API_W16AppParmAdd 296
1369 #define API_W16AppParmDel 297
1370 #define API_W16AppParmGet 298
1371 #define API_W16AppParmSet 299
1372 #define API_W16RIPLMachineCreate 300
1373 #define API_W16RIPLMachineGetInfo 301
1374 #define API_W16RIPLMachineSetInfo 302
1375 #define API_W16RIPLMachineEnum 303
1376 #define API_W16RIPLMachineListParmEnum 304
1377 #define API_W16RIPLMachClassGetInfo 305
1378 #define API_W16RIPLMachClassEnum 306
1379 #define API_W16RIPLMachClassCreate 307
1380 #define API_W16RIPLMachClassSetInfo 308
1381 #define API_W16RIPLMachClassDelete 309
1382 #define API_W16RIPLMachClassLPEnum 310
1383 #define API_W16RIPLMachineDelete 311
1384 #define API_W16WSLevelGetInfo 312
1385 #define API_NetServerNameAdd 313
1386 #define API_NetServerNameDel 314
1387 #define API_NetServerNameEnum 315
1388 #define API_I_WDASDEnum 316
1389 #define API_I_WDASDEnumTerminate 317
1390 #define API_I_WDASDSetInfo2 318
1392 static const struct lanman_desc lmd[] = {
1394 lm_params_req_netshareenum,
1399 lm_params_resp_netshareenum,
1402 netshareenum_share_entry,
1404 lm_data_resp_netshareenum,
1407 { API_NetShareGetInfo,
1408 lm_params_req_netsharegetinfo,
1413 lm_params_resp_netsharegetinfo,
1418 lm_data_resp_netsharegetinfo,
1421 { API_NetServerGetInfo,
1422 lm_params_req_netservergetinfo,
1427 lm_params_resp_netservergetinfo,
1435 { API_NetUserGetInfo,
1436 lm_params_req_netusergetinfo,
1441 lm_params_resp_netusergetinfo,
1446 lm_data_resp_netusergetinfo,
1449 { API_NetUserGetGroups,
1450 lm_params_req_netusergetgroups,
1455 lm_params_resp_netusergetgroups,
1460 lm_data_resp_netusergetgroups,
1474 lm_data_resp_netremotetod,
1477 { API_NetServerEnum2,
1478 lm_params_req_netserverenum2,
1483 lm_params_resp_netserverenum2,
1485 &ett_lanman_servers,
1486 netserverenum2_server_entry,
1491 { API_NetWkstaGetInfo,
1492 lm_params_req_netwkstagetinfo,
1497 lm_params_resp_netwkstagetinfo,
1502 lm_data_resp_netwkstagetinfo,
1505 { API_NetWkstaUserLogon,
1506 lm_params_req_netwkstauserlogon,
1511 lm_params_resp_netwkstauserlogon,
1516 lm_data_resp_netwkstauserlogon,
1519 { API_NetWkstaUserLogoff,
1520 lm_params_req_netwkstauserlogoff,
1525 lm_params_resp_netwkstauserlogoff,
1530 lm_data_resp_netwkstauserlogoff,
1533 { API_SamOEMChgPasswordUser2_P,
1534 lm_params_req_samoemchangepassword,
1537 lm_data_req_samoemchangepassword,
1547 { API_NetServerEnum3,
1548 lm_params_req_netserverenum3,
1553 lm_params_resp_netserverenum2,
1555 &ett_lanman_servers,
1556 netserverenum2_server_entry,
1571 &ett_lanman_unknown_entry,
1576 static const struct lanman_desc *
1577 find_lanman(int lanman_num)
1581 for (i = 0; lmd[i].lanman_num != -1; i++) {
1582 if (lmd[i].lanman_num == lanman_num)
1588 static const guchar *
1589 get_count(const guchar *desc, int *countp)
1594 if (!isdigit(*desc)) {
1595 *countp = 1; /* no count was supplied */
1599 while ((c = *desc) != '\0' && isdigit(c)) {
1600 count = (count * 10) + c - '0';
1604 *countp = count; /* XXX - what if it's 0? */
1609 dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1610 proto_tree *tree, const guchar *desc, const item_t *items,
1611 gboolean *has_data_p)
1619 *has_data_p = FALSE;
1620 while ((c = *desc++) != '\0') {
1625 * A 16-bit word value in the request.
1627 if (items->func == NULL) {
1629 * We've run out of items in the table;
1630 * fall back on the default.
1632 offset = add_word_param(tvb, offset, 0, pinfo,
1634 } else if (items->type != PARAM_WORD) {
1636 * Descriptor character is 'W', but this
1637 * isn't a word parameter.
1639 WParam = tvb_get_letohs(tvb, offset);
1640 proto_tree_add_text(tree, tvb, offset, 2,
1641 "%s: Value is %u (0x%04X), type is wrong (W)",
1642 (*items->hf_index == -1) ?
1644 proto_registrar_get_name(*items->hf_index),
1649 offset = (*items->func)(tvb, offset, 0, pinfo,
1650 tree, 0, *items->hf_index);
1657 * A 32-bit doubleword value in the request.
1659 if (items->func == NULL) {
1661 * We've run out of items in the table;
1662 * fall back on the default.
1664 offset = add_dword_param(tvb, offset, 0, pinfo,
1666 } else if (items->type != PARAM_DWORD) {
1668 * Descriptor character is 'D', but this
1669 * isn't a doubleword parameter.
1671 LParam = tvb_get_letohl(tvb, offset);
1672 proto_tree_add_text(tree, tvb, offset, 2,
1673 "%s: Value is %u (0x%08X), type is wrong (D)",
1674 (*items->hf_index == -1) ?
1675 "Doubleword Param" :
1676 proto_registrar_get_name(*items->hf_index),
1681 offset = (*items->func)(tvb, offset, 0, pinfo,
1682 tree, 0, *items->hf_index);
1689 * A byte or multi-byte value in the request.
1691 desc = get_count(desc, &count);
1692 if (items->func == NULL) {
1694 * We've run out of items in the table;
1695 * fall back on the default.
1697 offset = add_byte_param(tvb, offset, count,
1698 pinfo, tree, 0, -1);
1699 } else if (items->type != PARAM_BYTES) {
1701 * Descriptor character is 'b', but this
1702 * isn't a byte/bytes parameter.
1704 proto_tree_add_text(tree, tvb, offset, count,
1705 "%s: Value is %s, type is wrong (b)",
1706 (*items->hf_index == -1) ?
1708 proto_registrar_get_name(*items->hf_index),
1709 tvb_bytes_to_str(tvb, offset, count));
1713 offset = (*items->func)(tvb, offset, count,
1714 pinfo, tree, 0, *items->hf_index);
1723 if (items->func == NULL) {
1725 * We've run out of items in the table;
1726 * fall back on the default.
1728 add_null_pointer_param(tvb, offset, 0,
1729 pinfo, tree, 0, -1);
1732 * If "*items->hf_index" is -1, this is
1733 * a reserved must-be-null field; don't
1734 * clutter the protocol tree by putting
1737 if (*items->hf_index != -1) {
1738 add_null_pointer_param(tvb,
1739 offset, 0, pinfo, tree, 0,
1748 * A null-terminated ASCII string.
1750 if (items->func == NULL) {
1752 * We've run out of items in the table;
1753 * fall back on the default.
1755 offset = add_string_param(tvb, offset, 0,
1756 pinfo, tree, 0, -1);
1757 } else if (items->type != PARAM_STRINGZ) {
1759 * Descriptor character is 'z', but this
1760 * isn't a string parameter.
1762 string_len = tvb_strsize(tvb, offset);
1763 proto_tree_add_text(tree, tvb, offset, string_len,
1764 "%s: Value is %s, type is wrong (z)",
1765 (*items->hf_index == -1) ?
1767 proto_registrar_get_name(*items->hf_index),
1768 tvb_format_text(tvb, offset, string_len));
1769 offset += string_len;
1772 offset = (*items->func)(tvb, offset, 0,
1773 pinfo, tree, 0, *items->hf_index);
1780 * One or more pad bytes.
1782 desc = get_count(desc, &count);
1783 proto_tree_add_text(tree, tvb, offset, count,
1790 * 16-bit receive buffer length.
1792 proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1799 * 32-bit send buffer offset.
1800 * This appears not to be sent over the wire.
1807 * 16-bit send buffer length.
1809 proto_tree_add_item(tree, hf_send_buf_len, tvb,
1822 dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1823 proto_tree *tree, const guchar *desc, const item_t *items,
1824 gboolean *has_data_p, gboolean *has_ent_count_p, guint16 *ent_count_p)
1831 *has_data_p = FALSE;
1832 *has_ent_count_p = FALSE;
1833 while ((c = *desc++) != '\0') {
1838 * 32-bit receive buffer offset.
1845 * A byte or series of bytes is returned.
1847 desc = get_count(desc, &count);
1848 if (items->func == NULL) {
1850 * We've run out of items in the table;
1851 * fall back on the default.
1853 offset = add_byte_param(tvb, offset, count,
1854 pinfo, tree, 0, -1);
1855 } else if (items->type != PARAM_BYTES) {
1857 * Descriptor character is 'b', but this
1858 * isn't a byte/bytes parameter.
1860 proto_tree_add_text(tree, tvb, offset, count,
1861 "%s: Value is %s, type is wrong (g)",
1862 (*items->hf_index == -1) ?
1864 proto_registrar_get_name(*items->hf_index),
1865 tvb_bytes_to_str(tvb, offset, count));
1869 offset = (*items->func)(tvb, offset, count,
1870 pinfo, tree, 0, *items->hf_index);
1877 * A 16-bit word is received.
1879 if (items->func == NULL) {
1881 * We've run out of items in the table;
1882 * fall back on the default.
1884 offset = add_word_param(tvb, offset, 0, pinfo,
1886 } else if (items->type != PARAM_WORD) {
1888 * Descriptor character is 'h', but this
1889 * isn't a word parameter.
1891 WParam = tvb_get_letohs(tvb, offset);
1892 proto_tree_add_text(tree, tvb, offset, 2,
1893 "%s: Value is %u (0x%04X), type is wrong (W)",
1894 (*items->hf_index == -1) ?
1896 proto_registrar_get_name(*items->hf_index),
1901 offset = (*items->func)(tvb, offset, 0, pinfo,
1902 tree, 0, *items->hf_index);
1909 * A 32-bit doubleword is received.
1911 if (items->func == NULL) {
1913 * We've run out of items in the table;
1914 * fall back on the default.
1916 offset = add_dword_param(tvb, offset, 0, pinfo,
1918 } else if (items->type != PARAM_DWORD) {
1920 * Descriptor character is 'i', but this
1921 * isn't a doubleword parameter.
1923 LParam = tvb_get_letohl(tvb, offset);
1924 proto_tree_add_text(tree, tvb, offset, 2,
1925 "%s: Value is %u (0x%08X), type is wrong (i)",
1926 (*items->hf_index == -1) ?
1927 "Doubleword Param" :
1928 proto_registrar_get_name(*items->hf_index),
1933 offset = (*items->func)(tvb, offset, 0, pinfo,
1934 tree, 0, *items->hf_index);
1941 * A 16-bit entry count is returned.
1943 WParam = tvb_get_letohs(tvb, offset);
1944 proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1947 *has_ent_count_p = TRUE;
1948 *ent_count_p = WParam; /* Save this for later retrieval */
1959 dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1960 packet_info *pinfo, proto_tree *tree, const guchar *desc,
1961 const item_t *items, guint16 *aux_count_p)
1971 if (aux_count_p != NULL)
1974 while ((c = *desc++) != '\0') {
1979 * A 16-bit word value.
1980 * XXX - handle the count?
1982 desc = get_count(desc, &count);
1983 if (items->func == NULL) {
1985 * We've run out of items in the table;
1986 * fall back on the default.
1988 offset = add_word_param(tvb, offset, 0, pinfo,
1990 } else if (items->type != PARAM_WORD) {
1992 * Descriptor character is 'W', but this
1993 * isn't a word parameter.
1995 WParam = tvb_get_letohs(tvb, offset);
1996 proto_tree_add_text(tree, tvb, offset, 2,
1997 "%s: Value is %u (0x%04X), type is wrong (W)",
1998 (*items->hf_index == -1) ?
2000 proto_registrar_get_name(*items->hf_index),
2005 offset = (*items->func)(tvb, offset, 0, pinfo,
2006 tree, convert, *items->hf_index);
2013 * A 32-bit doubleword value.
2014 * XXX - handle the count?
2016 desc = get_count(desc, &count);
2017 if (items->func == NULL) {
2019 * We've run out of items in the table;
2020 * fall back on the default.
2022 offset = add_dword_param(tvb, offset, 0, pinfo,
2024 } else if (items->type != PARAM_DWORD) {
2026 * Descriptor character is 'D', but this
2027 * isn't a doubleword parameter.
2029 LParam = tvb_get_letohl(tvb, offset);
2030 proto_tree_add_text(tree, tvb, offset, 2,
2031 "%s: Value is %u (0x%08X), type is wrong (D)",
2032 (*items->hf_index == -1) ?
2033 "Doubleword Param" :
2034 proto_registrar_get_name(*items->hf_index),
2039 offset = (*items->func)(tvb, offset, 0, pinfo,
2040 tree, convert, *items->hf_index);
2047 * A byte or multi-byte value.
2049 desc = get_count(desc, &count);
2050 if (items->func == NULL) {
2052 * We've run out of items in the table;
2053 * fall back on the default.
2055 offset = add_byte_param(tvb, offset, count,
2056 pinfo, tree, convert, -1);
2057 } else if (items->type != PARAM_BYTES) {
2059 * Descriptor character is 'B', but this
2060 * isn't a byte/bytes parameter.
2062 proto_tree_add_text(tree, tvb, offset, count,
2063 "%s: Value is %s, type is wrong (B)",
2064 (*items->hf_index == -1) ?
2066 proto_registrar_get_name(*items->hf_index),
2067 tvb_bytes_to_str(tvb, offset, count));
2071 offset = (*items->func)(tvb, offset, count,
2072 pinfo, tree, convert, *items->hf_index);
2081 if (items->func == NULL) {
2083 * We've run out of items in the table;
2084 * fall back on the default.
2086 add_null_pointer_param(tvb, offset, 0,
2087 pinfo, tree, convert, -1);
2090 * If "*items->hf_index" is -1, this is
2091 * a reserved must-be-null field; don't
2092 * clutter the protocol tree by putting
2095 if (*items->hf_index != -1) {
2096 add_null_pointer_param(tvb,
2097 offset, 0, pinfo, tree, convert,
2106 * A pointer to a null-terminated ASCII string.
2108 if (items->func == NULL) {
2110 * We've run out of items in the table;
2111 * fall back on the default.
2113 offset = add_stringz_pointer_param(tvb, offset,
2114 0, pinfo, tree, convert, -1);
2115 } else if (items->type != PARAM_STRINGZ) {
2117 * Descriptor character is 'z', but this
2118 * isn't a string parameter.
2120 string = get_stringz_pointer_value(tvb, offset,
2121 convert, &cptr, &string_len);
2123 proto_tree_add_text(tree, tvb, cptr, string_len,
2124 "%s: Value is %s, type is wrong (z)",
2125 (*items->hf_index == -1) ?
2127 proto_registrar_get_name(*items->hf_index),
2131 offset = (*items->func)(tvb, offset, 0,
2132 pinfo, tree, convert, *items->hf_index);
2139 * A pointer to a byte or multi-byte value.
2141 desc = get_count(desc, &count);
2142 if (items->func == NULL) {
2144 * We've run out of items in the table;
2145 * fall back on the default.
2147 offset = add_bytes_pointer_param(tvb, offset,
2148 count, pinfo, tree, convert, -1);
2149 } else if (items->type != PARAM_BYTES) {
2151 * Descriptor character is 'b', but this
2152 * isn't a byte/bytes parameter.
2154 cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2156 proto_tree_add_text(tree, tvb, offset, count,
2157 "%s: Value is %s, type is wrong (b)",
2158 (*items->hf_index == -1) ?
2160 proto_registrar_get_name(*items->hf_index),
2161 tvb_bytes_to_str(tvb, cptr, count));
2164 offset = (*items->func)(tvb, offset, count,
2165 pinfo, tree, convert, *items->hf_index);
2172 * 16-bit auxiliary data structure count.
2175 WParam = tvb_get_letohs(tvb, offset);
2176 proto_tree_add_text(tree, tvb, offset, 2,
2178 "Auxiliary data structure count",
2181 if (aux_count_p != NULL)
2182 *aux_count_p = WParam; /* Save this for later retrieval */
2192 static const value_string commands[] = {
2193 {API_NetShareEnum, "NetShareEnum"},
2194 {API_NetShareGetInfo, "NetShareGetInfo"},
2195 {API_NetShareSetInfo, "NetShareSetInfo"},
2196 {API_NetShareAdd, "NetShareAdd"},
2197 {API_NetShareDel, "NetShareDel"},
2198 {API_NetShareCheck, "NetShareCheck"},
2199 {API_NetSessionEnum, "NetSessionEnum"},
2200 {API_NetSessionGetInfo, "NetSessionGetInfo"},
2201 {API_NetSessionDel, "NetSessionDel"},
2202 {API_WconnectionEnum, "NetConnectionEnum"},
2203 {API_NetFileEnum, "NetFileEnum"},
2204 {API_NetFileGetInfo, "NetFileGetInfo"},
2205 {API_NetFileClose, "NetFileClose"},
2206 {API_NetServerGetInfo, "NetServerGetInfo"},
2207 {API_NetServerSetInfo, "NetServerSetInfo"},
2208 {API_NetServerDiskEnum, "NetServerDiskEnum"},
2209 {API_NetServerAdminCommand, "NetServerAdminCommand"},
2210 {API_NetAuditOpen, "NetAuditOpen"},
2211 {API_NetAuditClear, "NetAuditClear"},
2212 {API_NetErrorLogOpen, "NetErrorLogOpen"},
2213 {API_NetErrorLogClear, "NetErrorLogClear"},
2214 {API_NetCharDevEnum, "NetCharDevEnum"},
2215 {API_NetCharDevGetInfo, "NetCharDevGetInfo"},
2216 {API_NetCharDevControl, "NetCharDevControl"},
2217 {API_NetCharDevQEnum, "NetCharDevQEnum"},
2218 {API_NetCharDevQGetInfo, "NetCharDevQGetInfo"},
2219 {API_NetCharDevQSetInfo, "NetCharDevQSetInfo"},
2220 {API_NetCharDevQPurge, "NetCharDevQPurge"},
2221 {API_NetCharDevQPurgeSelf, "NetCharDevQPurgeSelf"},
2222 {API_NetMessageNameEnum, "NetMessageNameEnum"},
2223 {API_NetMessageNameGetInfo, "NetMessageNameGetInfo"},
2224 {API_NetMessageNameAdd, "NetMessageNameAdd"},
2225 {API_NetMessageNameDel, "NetMessageNameDel"},
2226 {API_NetMessageNameFwd, "NetMessageNameFwd"},
2227 {API_NetMessageNameUnFwd, "NetMessageNameUnFwd"},
2228 {API_NetMessageBufferSend, "NetMessageBufferSend"},
2229 {API_NetMessageFileSend, "NetMessageFileSend"},
2230 {API_NetMessageLogFileSet, "NetMessageLogFileSet"},
2231 {API_NetMessageLogFileGet, "NetMessageLogFileGet"},
2232 {API_NetServiceEnum, "NetServiceEnum"},
2233 {API_NetServiceInstall, "NetServiceInstall"},
2234 {API_NetServiceControl, "NetServiceControl"},
2235 {API_NetAccessEnum, "NetAccessEnum"},
2236 {API_NetAccessGetInfo, "NetAccessGetInfo"},
2237 {API_NetAccessSetInfo, "NetAccessSetInfo"},
2238 {API_NetAccessAdd, "NetAccessAdd"},
2239 {API_NetAccessDel, "NetAccessDel"},
2240 {API_NetGroupEnum, "NetGroupEnum"},
2241 {API_NetGroupAdd, "NetGroupAdd"},
2242 {API_NetGroupDel, "NetGroupDel"},
2243 {API_NetGroupAddUser, "NetGroupAddUser"},
2244 {API_NetGroupDelUser, "NetGroupDelUser"},
2245 {API_NetGroupGetUsers, "NetGroupGetUsers"},
2246 {API_NetUserEnum, "NetUserEnum"},
2247 {API_NetUserAdd, "NetUserAdd"},
2248 {API_NetUserDel, "NetUserDel"},
2249 {API_NetUserGetInfo, "NetUserGetInfo"},
2250 {API_NetUserSetInfo, "NetUserSetInfo"},
2251 {API_NetUserPasswordSet, "NetUserPasswordSet"},
2252 {API_NetUserGetGroups, "NetUserGetGroups"},
2253 {API_NetWkstaSetUID, "NetWkstaSetUID"},
2254 {API_NetWkstaGetInfo, "NetWkstaGetInfo"},
2255 {API_NetWkstaSetInfo, "NetWkstaSetInfo"},
2256 {API_NetUseEnum, "NetUseEnum"},
2257 {API_NetUseAdd, "NetUseAdd"},
2258 {API_NetUseDel, "NetUseDel"},
2259 {API_NetUseGetInfo, "NetUseGetInfo"},
2260 {API_WPrintQEnum, "WPrintQEnum"},
2261 {API_WPrintQGetInfo, "WPrintQGetInfo"},
2262 {API_WPrintQSetInfo, "WPrintQSetInfo"},
2263 {API_WPrintQAdd, "WPrintQAdd"},
2264 {API_WPrintQDel, "WPrintQDel"},
2265 {API_WPrintQPause, "WPrintQPause"},
2266 {API_WPrintQContinue, "WPrintQContinue"},
2267 {API_WPrintJobEnum, "WPrintJobEnum"},
2268 {API_WPrintJobGetInfo, "WPrintJobGetInfo"},
2269 {API_WPrintJobSetInfo_OLD, "WPrintJobSetInfo_OLD"},
2270 {API_WPrintJobDel, "WPrintJobDel"},
2271 {API_WPrintJobPause, "WPrintJobPause"},
2272 {API_WPrintJobContinue, "WPrintJobContinue"},
2273 {API_WPrintDestEnum, "WPrintDestEnum"},
2274 {API_WPrintDestGetInfo, "WPrintDestGetInfo"},
2275 {API_WPrintDestControl, "WPrintDestControl"},
2276 {API_NetProfileSave, "NetProfileSave"},
2277 {API_NetProfileLoad, "NetProfileLoad"},
2278 {API_NetStatisticsGet, "NetStatisticsGet"},
2279 {API_NetStatisticsClear, "NetStatisticsClear"},
2280 {API_NetRemoteTOD, "NetRemoteTOD"},
2281 {API_WNetBiosEnum, "WNetBiosEnum"},
2282 {API_WNetBiosGetInfo, "WNetBiosGetInfo"},
2283 {API_NetServerEnum, "NetServerEnum"},
2284 {API_I_NetServerEnum, "I_NetServerEnum"},
2285 {API_NetServiceGetInfo, "NetServiceGetInfo"},
2286 {API_WPrintQPurge, "WPrintQPurge"},
2287 {API_NetServerEnum2, "NetServerEnum2"},
2288 {API_NetAccessGetUserPerms, "NetAccessGetUserPerms"},
2289 {API_NetGroupGetInfo, "NetGroupGetInfo"},
2290 {API_NetGroupSetInfo, "NetGroupSetInfo"},
2291 {API_NetGroupSetUsers, "NetGroupSetUsers"},
2292 {API_NetUserSetGroups, "NetUserSetGroups"},
2293 {API_NetUserModalsGet, "NetUserModalsGet"},
2294 {API_NetUserModalsSet, "NetUserModalsSet"},
2295 {API_NetFileEnum2, "NetFileEnum2"},
2296 {API_NetUserAdd2, "NetUserAdd2"},
2297 {API_NetUserSetInfo2, "NetUserSetInfo2"},
2298 {API_NetUserPasswordSet2, "SetUserPassword"},
2299 {API_I_NetServerEnum2, "I_NetServerEnum2"},
2300 {API_NetConfigGet2, "NetConfigGet2"},
2301 {API_NetConfigGetAll2, "NetConfigGetAll2"},
2302 {API_NetGetDCName, "NetGetDCName"},
2303 {API_NetHandleGetInfo, "NetHandleGetInfo"},
2304 {API_NetHandleSetInfo, "NetHandleSetInfo"},
2305 {API_NetStatisticsGet2, "NetStatisticsGet2"},
2306 {API_WBuildGetInfo, "WBuildGetInfo"},
2307 {API_NetFileGetInfo2, "NetFileGetInfo2"},
2308 {API_NetFileClose2, "NetFileClose2"},
2309 {API_NetServerReqChallenge, "NetServerReqChallenge"},
2310 {API_NetServerAuthenticate, "NetServerAuthenticate"},
2311 {API_NetServerPasswordSet, "NetServerPasswordSet"},
2312 {API_WNetAccountDeltas, "WNetAccountDeltas"},
2313 {API_WNetAccountSync, "WNetAccountSync"},
2314 {API_NetUserEnum2, "NetUserEnum2"},
2315 {API_NetWkstaUserLogon, "NetWkstaUserLogon"},
2316 {API_NetWkstaUserLogoff, "NetWkstaUserLogoff"},
2317 {API_NetLogonEnum, "NetLogonEnum"},
2318 {API_NetErrorLogRead, "NetErrorLogRead"},
2319 {API_I_NetPathType, "I_NetPathType"},
2320 {API_I_NetPathCanonicalize, "I_NetPathCanonicalize"},
2321 {API_I_NetPathCompare, "I_NetPathCompare"},
2322 {API_I_NetNameValidate, "I_NetNameValidate"},
2323 {API_I_NetNameCanonicalize, "I_NetNameCanonicalize"},
2324 {API_I_NetNameCompare, "I_NetNameCompare"},
2325 {API_NetAuditRead, "NetAuditRead"},
2326 {API_WPrintDestAdd, "WPrintDestAdd"},
2327 {API_WPrintDestSetInfo, "WPrintDestSetInfo"},
2328 {API_WPrintDestDel, "WPrintDestDel"},
2329 {API_NetUserValidate2, "NetUserValidate2"},
2330 {API_WPrintJobSetInfo, "WPrintJobSetInfo"},
2331 {API_TI_NetServerDiskEnum, "TI_NetServerDiskEnum"},
2332 {API_TI_NetServerDiskGetInfo, "TI_NetServerDiskGetInfo"},
2333 {API_TI_FTVerifyMirror, "TI_FTVerifyMirror"},
2334 {API_TI_FTAbortVerify, "TI_FTAbortVerify"},
2335 {API_TI_FTGetInfo, "TI_FTGetInfo"},
2336 {API_TI_FTSetInfo, "TI_FTSetInfo"},
2337 {API_TI_FTLockDisk, "TI_FTLockDisk"},
2338 {API_TI_FTFixError, "TI_FTFixError"},
2339 {API_TI_FTAbortFix, "TI_FTAbortFix"},
2340 {API_TI_FTDiagnoseError, "TI_FTDiagnoseError"},
2341 {API_TI_FTGetDriveStats, "TI_FTGetDriveStats"},
2342 {API_TI_FTErrorGetInfo, "TI_FTErrorGetInfo"},
2343 {API_NetAccessCheck, "NetAccessCheck"},
2344 {API_NetAlertRaise, "NetAlertRaise"},
2345 {API_NetAlertStart, "NetAlertStart"},
2346 {API_NetAlertStop, "NetAlertStop"},
2347 {API_NetAuditWrite, "NetAuditWrite"},
2348 {API_NetIRemoteAPI, "NetIRemoteAPI"},
2349 {API_NetServiceStatus, "NetServiceStatus"},
2350 {API_I_NetServerRegister, "I_NetServerRegister"},
2351 {API_I_NetServerDeregister, "I_NetServerDeregister"},
2352 {API_I_NetSessionEntryMake, "I_NetSessionEntryMake"},
2353 {API_I_NetSessionEntryClear, "I_NetSessionEntryClear"},
2354 {API_I_NetSessionEntryGetInfo, "I_NetSessionEntryGetInfo"},
2355 {API_I_NetSessionEntrySetInfo, "I_NetSessionEntrySetInfo"},
2356 {API_I_NetConnectionEntryMake, "I_NetConnectionEntryMake"},
2357 {API_I_NetConnectionEntryClear, "I_NetConnectionEntryClear"},
2358 {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2359 {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2360 {API_I_NetFileEntryMake, "I_NetFileEntryMake"},
2361 {API_I_NetFileEntryClear, "I_NetFileEntryClear"},
2362 {API_I_NetFileEntrySetInfo, "I_NetFileEntrySetInfo"},
2363 {API_I_NetFileEntryGetInfo, "I_NetFileEntryGetInfo"},
2364 {API_AltSrvMessageBufferSend, "AltSrvMessageBufferSend"},
2365 {API_AltSrvMessageFileSend, "AltSrvMessageFileSend"},
2366 {API_wI_NetRplWkstaEnum, "wI_NetRplWkstaEnum"},
2367 {API_wI_NetRplWkstaGetInfo, "wI_NetRplWkstaGetInfo"},
2368 {API_wI_NetRplWkstaSetInfo, "wI_NetRplWkstaSetInfo"},
2369 {API_wI_NetRplWkstaAdd, "wI_NetRplWkstaAdd"},
2370 {API_wI_NetRplWkstaDel, "wI_NetRplWkstaDel"},
2371 {API_wI_NetRplProfileEnum, "wI_NetRplProfileEnum"},
2372 {API_wI_NetRplProfileGetInfo, "wI_NetRplProfileGetInfo"},
2373 {API_wI_NetRplProfileSetInfo, "wI_NetRplProfileSetInfo"},
2374 {API_wI_NetRplProfileAdd, "wI_NetRplProfileAdd"},
2375 {API_wI_NetRplProfileDel, "wI_NetRplProfileDel"},
2376 {API_wI_NetRplProfileClone, "wI_NetRplProfileClone"},
2377 {API_wI_NetRplBaseProfileEnum, "wI_NetRplBaseProfileEnum"},
2378 {API_WIServerSetInfo, "WIServerSetInfo"},
2379 {API_WPrintDriverEnum, "WPrintDriverEnum"},
2380 {API_WPrintQProcessorEnum, "WPrintQProcessorEnum"},
2381 {API_WPrintPortEnum, "WPrintPortEnum"},
2382 {API_WNetWriteUpdateLog, "WNetWriteUpdateLog"},
2383 {API_WNetAccountUpdate, "WNetAccountUpdate"},
2384 {API_WNetAccountConfirmUpdate, "WNetAccountConfirmUpdate"},
2385 {API_NetConfigSet, "NetConfigSet"},
2386 {API_WAccountsReplicate, "WAccountsReplicate"},
2387 {API_SamOEMChgPasswordUser2_P, "SamOEMChangePassword"},
2388 {API_NetServerEnum3, "NetServerEnum3"},
2389 {API_WPrintDriverGetInfo, "WPrintDriverGetInfo"},
2390 {API_WPrintDriverSetInfo, "WPrintDriverSetInfo"},
2391 {API_NetAliasAdd, "NetAliasAdd"},
2392 {API_NetAliasDel, "NetAliasDel"},
2393 {API_NetAliasGetInfo, "NetAliasGetInfo"},
2394 {API_NetAliasSetInfo, "NetAliasSetInfo"},
2395 {API_NetAliasEnum, "NetAliasEnum"},
2396 {API_NetUserGetLogonAsn, "NetUserGetLogonAsn"},
2397 {API_NetUserSetLogonAsn, "NetUserSetLogonAsn"},
2398 {API_NetUserGetAppSel, "NetUserGetAppSel"},
2399 {API_NetUserSetAppSel, "NetUserSetAppSel"},
2400 {API_NetAppAdd, "NetAppAdd"},
2401 {API_NetAppDel, "NetAppDel"},
2402 {API_NetAppGetInfo, "NetAppGetInfo"},
2403 {API_NetAppSetInfo, "NetAppSetInfo"},
2404 {API_NetAppEnum, "NetAppEnum"},
2405 {API_NetUserDCDBInit, "NetUserDCDBInit"},
2406 {API_NetDASDAdd, "NetDASDAdd"},
2407 {API_NetDASDDel, "NetDASDDel"},
2408 {API_NetDASDGetInfo, "NetDASDGetInfo"},
2409 {API_NetDASDSetInfo, "NetDASDSetInfo"},
2410 {API_NetDASDEnum, "NetDASDEnum"},
2411 {API_NetDASDCheck, "NetDASDCheck"},
2412 {API_NetDASDCtl, "NetDASDCtl"},
2413 {API_NetUserRemoteLogonCheck, "NetUserRemoteLogonCheck"},
2414 {API_NetUserPasswordSet3, "NetUserPasswordSet3"},
2415 {API_NetCreateRIPLMachine, "NetCreateRIPLMachine"},
2416 {API_NetDeleteRIPLMachine, "NetDeleteRIPLMachine"},
2417 {API_NetGetRIPLMachineInfo, "NetGetRIPLMachineInfo"},
2418 {API_NetSetRIPLMachineInfo, "NetSetRIPLMachineInfo"},
2419 {API_NetEnumRIPLMachine, "NetEnumRIPLMachine"},
2420 {API_I_ShareAdd, "I_ShareAdd"},
2421 {API_I_AliasEnum, "I_AliasEnum"},
2422 {API_NetAccessApply, "NetAccessApply"},
2423 {API_WPrt16Query, "WPrt16Query"},
2424 {API_WPrt16Set, "WPrt16Set"},
2425 {API_NetUserDel100, "NetUserDel100"},
2426 {API_NetUserRemoteLogonCheck2, "NetUserRemoteLogonCheck2"},
2427 {API_WRemoteTODSet, "WRemoteTODSet"},
2428 {API_WPrintJobMoveAll, "WPrintJobMoveAll"},
2429 {API_W16AppParmAdd, "W16AppParmAdd"},
2430 {API_W16AppParmDel, "W16AppParmDel"},
2431 {API_W16AppParmGet, "W16AppParmGet"},
2432 {API_W16AppParmSet, "W16AppParmSet"},
2433 {API_W16RIPLMachineCreate, "W16RIPLMachineCreate"},
2434 {API_W16RIPLMachineGetInfo, "W16RIPLMachineGetInfo"},
2435 {API_W16RIPLMachineSetInfo, "W16RIPLMachineSetInfo"},
2436 {API_W16RIPLMachineEnum, "W16RIPLMachineEnum"},
2437 {API_W16RIPLMachineListParmEnum, "W16RIPLMachineListParmEnum"},
2438 {API_W16RIPLMachClassGetInfo, "W16RIPLMachClassGetInfo"},
2439 {API_W16RIPLMachClassEnum, "W16RIPLMachClassEnum"},
2440 {API_W16RIPLMachClassCreate, "W16RIPLMachClassCreate"},
2441 {API_W16RIPLMachClassSetInfo, "W16RIPLMachClassSetInfo"},
2442 {API_W16RIPLMachClassDelete, "W16RIPLMachClassDelete"},
2443 {API_W16RIPLMachClassLPEnum, "W16RIPLMachClassLPEnum"},
2444 {API_W16RIPLMachineDelete, "W16RIPLMachineDelete"},
2445 {API_W16WSLevelGetInfo, "W16WSLevelGetInfo"},
2446 {API_NetServerNameAdd, "NetServerNameAdd"},
2447 {API_NetServerNameDel, "NetServerNameDel"},
2448 {API_NetServerNameEnum, "NetServerNameEnum"},
2449 {API_I_WDASDEnum, "I_WDASDEnum"},
2450 {API_I_WDASDEnumTerminate, "I_WDASDEnumTerminate"},
2451 {API_I_WDASDSetInfo2, "I_WDASDSetInfo2"},
2456 dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2457 proto_tree *tree, struct smb_info *smb_info,
2458 const struct lanman_desc *lanman, gboolean has_ent_count,
2461 smb_transact_info_t *trp = smb_info->sip->extra_info;
2462 const item_list_t *resp_data_list;
2463 int offset, start_offset;
2466 const item_t *resp_data;
2467 proto_item *data_item;
2468 proto_tree *data_tree;
2469 proto_item *entry_item;
2470 proto_tree *entry_tree;
2475 * Find the item table for the matching request's detail level.
2477 for (resp_data_list = lanman->resp_data_list;
2478 resp_data_list->level != -1; resp_data_list++) {
2479 if (resp_data_list->level == trp->info_level)
2482 resp_data = resp_data_list->item_list;
2485 if (has_ent_count) {
2487 * The data is a list of entries; create a protocol tree item
2491 label = lanman->resp_data_entry_list_label;
2494 if (lanman->ett_data_entry_list != NULL)
2495 ett = *lanman->ett_data_entry_list;
2497 ett = ett_lanman_unknown_entries;
2498 data_item = proto_tree_add_text(tree, tvb, offset, -1,
2500 data_tree = proto_item_add_subtree(data_item, ett);
2507 * Just leave it at the top level.
2513 if (trp->data_descrip == NULL) {
2515 * This could happen if we only dissected
2516 * part of the request to which this is a
2517 * reply, e.g. if the request was split
2518 * across TCP segments and we weren't doing
2519 * TCP desegmentation, or if we had a snapshot
2520 * length that was too short.
2522 * We can't dissect the data; just show it as raw data or,
2523 * if we've already created a top-level item, note that
2524 * no descriptor is available.
2526 if (has_ent_count) {
2527 if (data_item != NULL) {
2528 proto_item_append_text(data_item,
2529 " (No descriptor available)");
2532 proto_tree_add_text(data_tree, tvb, offset, -1,
2533 "Data (no descriptor available)");
2535 offset += tvb_length_remaining(tvb, offset);
2538 * If we have an entry count, show all the entries,
2539 * with each one having a protocol tree item.
2541 * Otherwise, we just show one returned item, with
2542 * no protocol tree item.
2546 for (i = 0; i < ent_count; i++) {
2547 start_offset = offset;
2548 if (has_ent_count &&
2549 lanman->resp_data_element_item != NULL) {
2551 * Create a protocol tree item for the
2555 (*lanman->resp_data_element_item)
2556 (tvb, data_tree, offset);
2557 entry_tree = proto_item_add_subtree(
2559 *lanman->ett_resp_data_element_item);
2562 * Just leave it at the current
2566 entry_tree = data_tree;
2569 offset = dissect_transact_data(tvb, offset,
2570 convert, pinfo, entry_tree,
2571 trp->data_descrip, resp_data, &aux_count);
2573 /* auxiliary data */
2574 if (trp->aux_data_descrip != NULL) {
2575 for (j = 0; j < aux_count; j++) {
2576 offset = dissect_transact_data(
2577 tvb, offset, convert,
2580 lanman->resp_aux_data, NULL);
2584 if (entry_item != NULL) {
2586 * Set the length of the protocol tree
2587 * item for the entry.
2589 proto_item_set_len(entry_item,
2590 offset - start_offset);
2595 if (data_item != NULL) {
2597 * Set the length of the protocol tree item
2600 proto_item_set_len(data_item, offset);
2605 dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2606 packet_info *pinfo, proto_tree *parent_tree)
2608 smb_info_t *smb_info = pinfo->private_data;
2609 smb_transact_info_t *trp = smb_info->sip->extra_info;
2610 int offset = 0, start_offset;
2614 const struct lanman_desc *lanman;
2615 proto_item *item = NULL;
2616 proto_tree *tree = NULL;
2617 guint descriptor_len;
2618 const gchar *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2620 gboolean has_ent_count;
2621 guint16 ent_count, aux_count;
2623 proto_item *data_item;
2624 proto_tree *data_tree;
2626 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2628 if (smb_info->request && p_tvb == NULL) {
2630 * Requests must have parameters.
2634 pinfo->current_proto = "LANMAN";
2636 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
2637 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2641 item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2642 pd_tvb, 0, -1, FALSE);
2643 tree = proto_item_add_subtree(item, ett_lanman);
2646 if (smb_info->request) { /* this is a request */
2648 cmd = tvb_get_letohs(p_tvb, offset);
2649 if (check_col(pinfo->cinfo, COL_INFO)) {
2650 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str(cmd, commands, "Unknown Command (%u)"));
2652 proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2657 * If we haven't already done so, save the function code in
2658 * the structure we were handed, so that it's available to
2659 * the code parsing the reply, and initialize the detail
2660 * level to -1, meaning "unknown".
2662 if (!pinfo->fd->flags.visited) {
2663 trp->lanman_cmd = cmd;
2664 trp->info_level = -1;
2665 trp->param_descrip=NULL;
2666 trp->data_descrip=NULL;
2667 trp->aux_data_descrip=NULL;
2670 /* parameter descriptor */
2671 descriptor_len = tvb_strsize(p_tvb, offset);
2672 proto_tree_add_item(tree, hf_param_desc, p_tvb, offset,
2673 descriptor_len, TRUE);
2674 param_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2675 if (!pinfo->fd->flags.visited) {
2677 * Save the parameter descriptor for future use.
2679 g_assert(trp->param_descrip == NULL);
2680 trp->param_descrip = g_strdup(param_descrip);
2682 offset += descriptor_len;
2684 /* return descriptor */
2685 descriptor_len = tvb_strsize(p_tvb, offset);
2686 proto_tree_add_item(tree, hf_return_desc, p_tvb, offset,
2687 descriptor_len, TRUE);
2688 data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2689 if (!pinfo->fd->flags.visited) {
2691 * Save the return descriptor for future use.
2693 g_assert(trp->data_descrip == NULL);
2694 trp->data_descrip = g_strdup(data_descrip);
2696 offset += descriptor_len;
2698 lanman = find_lanman(cmd);
2700 /* request parameters */
2701 start_offset = offset;
2702 offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2703 param_descrip, lanman->req, &has_data);
2705 /* auxiliary data descriptor */
2706 if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2708 * There are more parameters left, so the next
2709 * item is the auxiliary data descriptor.
2711 descriptor_len = tvb_strsize(p_tvb, offset);
2712 proto_tree_add_item(tree, hf_aux_data_desc, p_tvb, offset,
2713 descriptor_len, TRUE);
2714 aux_data_descrip = tvb_get_ptr(p_tvb, offset, descriptor_len);
2715 if (!pinfo->fd->flags.visited) {
2717 * Save the auxiliary data descriptor for
2720 g_assert(trp->aux_data_descrip == NULL);
2721 trp->aux_data_descrip =
2722 g_strdup(aux_data_descrip);
2724 offset += descriptor_len;
2727 /* reset offset, we now start dissecting the data area */
2729 if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2731 * There's a send buffer item in the descriptor
2732 * string, and the data count in the transaction
2733 * is non-zero, so there's data to dissect.
2736 if (lanman->req_data_item != NULL) {
2738 * Create a protocol tree item for the data.
2740 data_item = (*lanman->req_data_item)(d_tvb,
2741 pinfo, tree, offset);
2742 data_tree = proto_item_add_subtree(data_item,
2743 *lanman->ett_req_data);
2746 * Just leave it at the top level.
2753 offset = dissect_transact_data(d_tvb, offset, -1,
2754 pinfo, data_tree, data_descrip, lanman->req_data,
2755 &aux_count); /* XXX - what about strings? */
2757 /* auxiliary data */
2758 if (aux_data_descrip != NULL) {
2759 for (i = 0; i < aux_count; i++) {
2760 offset = dissect_transact_data(d_tvb,
2761 offset, -1, pinfo, data_tree,
2763 lanman->req_aux_data, NULL);
2767 if (data_item != NULL) {
2769 * Set the length of the protocol tree item
2772 proto_item_set_len(data_item, offset);
2777 * This is a response.
2778 * Have we seen the request to which it's a response?
2781 return FALSE; /* no - can't dissect it */
2783 /* ok we have seen this one before */
2785 /* if it looks like an interim response, update COL_INFO and return */
2786 if( ( (p_tvb==NULL) || (tvb_reported_length(p_tvb)==0) )
2787 && ( (d_tvb==NULL) || (tvb_reported_length(d_tvb)==0) ) ){
2789 if (check_col(pinfo->cinfo, COL_INFO)) {
2790 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2791 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2793 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2798 if (check_col(pinfo->cinfo, COL_INFO)) {
2799 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2800 val_to_str(trp->lanman_cmd, commands, "Unknown Command (%u)"));
2802 proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2805 lanman = find_lanman(trp->lanman_cmd);
2807 /* response parameters */
2810 status = tvb_get_letohs(p_tvb, offset);
2811 proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2815 convert = tvb_get_letohs(p_tvb, offset);
2816 proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2819 if (trp->param_descrip == NULL) {
2821 * This could happen if we only dissected
2822 * part of the request to which this is a
2823 * reply, e.g. if the request was split
2824 * across TCP segments and we weren't doing
2825 * TCP desegmentation, or if we had a snapshot
2826 * length that was too short.
2828 * We can't dissect the parameters; just show them
2831 proto_tree_add_text(tree, p_tvb, offset, -1,
2832 "Parameters (no descriptor available)");
2835 * We don't know whether we have a receive buffer,
2836 * as we don't have the descriptor; just show what
2837 * bytes purport to be data.
2839 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2840 proto_tree_add_text(tree, d_tvb, 0, -1,
2841 "Data (no descriptor available)");
2844 /* rest of the parameters */
2845 offset = dissect_response_parameters(p_tvb, offset,
2846 pinfo, tree, trp->param_descrip, lanman->resp,
2847 &has_data, &has_ent_count, &ent_count);
2849 /* reset offset, we now start dissecting the data area */
2852 if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2854 * Well, there are bytes that purport to
2855 * be data, at least.
2859 * There's a receive buffer item
2860 * in the descriptor string, so
2861 * dissect it as response data.
2863 dissect_response_data(d_tvb, pinfo,
2864 convert, tree, smb_info, lanman,
2865 has_ent_count, ent_count);
2868 * There's no receive buffer item,
2869 * but we do have data, so just
2870 * show what bytes are data.
2872 proto_tree_add_text(tree, d_tvb, 0, -1,
2873 "Data (no receive buffer)");
2883 proto_register_pipe_lanman(void)
2885 static hf_register_info hf[] = {
2886 { &hf_function_code,
2887 { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC,
2888 VALS(commands), 0, "LANMAN Function Code/Command", HFILL }},
2891 { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2892 NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2895 { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2896 NULL, 0, "LANMAN Return Descriptor", HFILL }},
2898 { &hf_aux_data_desc,
2899 { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2900 NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2903 { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2904 NULL, 0, "LANMAN Detail Level", HFILL }},
2907 { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2908 NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2911 { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2912 NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2914 { &hf_continuation_from,
2915 { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2916 NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2919 { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2920 VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2923 { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2924 NULL, 0, "LANMAN Convert", HFILL }},
2927 { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2928 NULL, 0, "LANMAN Number of Entries", HFILL }},
2931 { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2932 NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2935 { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2936 NULL, 0, "LANMAN Name of Share", HFILL }},
2939 { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2940 VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2942 { &hf_share_comment,
2943 { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2944 NULL, 0, "LANMAN Share Comment", HFILL }},
2946 { &hf_share_permissions,
2947 { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2948 NULL, 0, "LANMAN Permissions on share", HFILL }},
2950 { &hf_share_max_uses,
2951 { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2952 NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2954 { &hf_share_current_uses,
2955 { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2956 NULL, 0, "LANMAN Current connections to share", HFILL }},
2959 { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2960 NULL, 0, "LANMAN Share Path", HFILL }},
2962 { &hf_share_password,
2963 { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2964 NULL, 0, "LANMAN Share Password", HFILL }},
2967 { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2968 NULL, 0, "LANMAN Name of Server", HFILL }},
2971 { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2972 NULL, 0, "LANMAN Server Major Version", HFILL }},
2975 { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2976 NULL, 0, "LANMAN Server Minor Version", HFILL }},
2978 { &hf_server_comment,
2979 { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
2980 NULL, 0, "LANMAN Server Comment", HFILL }},
2983 { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
2984 NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
2987 { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, BASE_NONE,
2988 NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
2991 { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
2992 NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
2995 { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
2996 NULL, 0, "LANMAN Current hour", HFILL }},
2999 { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
3000 NULL, 0, "LANMAN Current minute", HFILL }},
3003 { "Second", "lanman.second", FT_UINT8, BASE_DEC,
3004 NULL, 0, "LANMAN Current second", HFILL }},
3007 { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
3008 NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
3011 { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
3012 NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
3015 { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
3016 NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
3019 { "Day", "lanman.day", FT_UINT8, BASE_DEC,
3020 NULL, 0, "LANMAN Current day", HFILL }},
3023 { "Month", "lanman.month", FT_UINT8, BASE_DEC,
3024 NULL, 0, "LANMAN Current month", HFILL }},
3027 { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3028 NULL, 0, "LANMAN Current year", HFILL }},
3031 { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3032 VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3034 { &hf_enumeration_domain,
3035 { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3036 NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3039 { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE,
3040 NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }},
3042 { &hf_computer_name,
3043 { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3044 NULL, 0, "LANMAN Computer Name", HFILL }},
3047 { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3048 NULL, 0, "LANMAN User Name", HFILL }},
3051 { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3052 NULL, 0, "LANMAN Group Name", HFILL }},
3054 { &hf_workstation_domain,
3055 { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3056 NULL, 0, "LANMAN Workstation Domain", HFILL }},
3058 { &hf_workstation_major,
3059 { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3060 NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3062 { &hf_workstation_minor,
3063 { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3064 NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3067 { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3068 NULL, 0, "LANMAN Logon Domain", HFILL }},
3070 { &hf_other_domains,
3071 { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3072 NULL, 0, "LANMAN Other Domains", HFILL }},
3075 { "Password", "lanman.password", FT_STRING, BASE_NONE,
3076 NULL, 0, "LANMAN Password", HFILL }},
3078 { &hf_workstation_name,
3079 { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3080 NULL, 0, "LANMAN Workstation Name", HFILL }},
3083 { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3084 NULL, 0, "LANMAN UStruct Length", HFILL }},
3087 { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3088 VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3090 { &hf_privilege_level,
3091 { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3092 VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3094 { &hf_operator_privileges,
3095 { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3096 VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3099 { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3100 NULL, 0, "LANMAN Number of Logons", HFILL }},
3103 { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3104 NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3107 { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, BASE_NONE,
3108 NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3111 { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, BASE_NONE,
3112 NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3115 { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3116 NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3119 { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, BASE_NONE,
3120 NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3123 { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3124 NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3126 { &hf_password_can_change,
3127 { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, BASE_NONE,
3128 NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3130 { &hf_password_must_change,
3131 { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, BASE_NONE,
3132 NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3135 { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3136 NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3139 { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3140 VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3143 { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3144 NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3147 { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3148 NULL, 0, "LANMAN Comment", HFILL }},
3151 { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3152 NULL, 0, "LANMAN User Comment", HFILL }},
3155 { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3156 NULL, 0, "LANMAN Full Name", HFILL }},
3159 { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3160 NULL, 0, "LANMAN Home Directory", HFILL }},
3163 { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3164 NULL, 0, "LANMAN Parameters", HFILL }},
3167 { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3168 NULL, 0, "LANMAN Logon Server", HFILL }},
3170 /* XXX - we should have a value_string table for this */
3172 { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC,
3173 VALS(ms_country_codes), 0, "LANMAN Country Code", HFILL }},
3176 { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3177 NULL, 0, "LANMAN Workstations", HFILL }},
3180 { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3181 NULL, 0, "LANMAN Max Storage", HFILL }},
3183 { &hf_units_per_week,
3184 { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3185 NULL, 0, "LANMAN Units Per Week", HFILL }},
3188 { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3189 NULL, 0, "LANMAN Logon Hours", HFILL }},
3191 /* XXX - we should have a value_string table for this */
3193 { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3194 NULL, 0, "LANMAN Code Page", HFILL }},
3197 { "New Password", "lanman.new_password", FT_BYTES, BASE_HEX,
3198 NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3201 { "Old Password", "lanman.old_password", FT_BYTES, BASE_HEX,
3202 NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3205 { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3206 NULL, 0, "LANMAN Reserved", HFILL }},
3209 static gint *ett[] = {
3211 &ett_lanman_unknown_entries,
3212 &ett_lanman_unknown_entry,
3213 &ett_lanman_servers,
3220 proto_smb_lanman = proto_register_protocol(
3221 "Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3222 proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3223 proto_register_subtree_array(ett, array_length(ett));
3226 static heur_dissector_list_t smb_transact_heur_subdissector_list;
3228 static GHashTable *dcerpc_fragment_table = NULL;
3229 static GHashTable *dcerpc_reassembled_table = NULL;
3232 smb_dcerpc_reassembly_init(void)
3234 fragment_table_init(&dcerpc_fragment_table);
3235 reassembled_table_init(&dcerpc_reassembled_table);
3239 dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3240 proto_tree *tree, guint32 fid)
3242 dcerpc_private_info dcerpc_priv;
3243 smb_info_t *smb_priv = (smb_info_t *)pinfo->private_data;
3245 gboolean save_fragmented;
3248 fragment_data *fd_head;
3251 dcerpc_priv.fid = fid;
3253 pinfo->private_data = &dcerpc_priv;
3257 * Offer desegmentation service to DCERPC if we have all the
3258 * data. Otherwise, reassembly is (probably) impossible.
3260 pinfo->can_desegment=0;
3261 pinfo->desegment_offset = 0;
3262 pinfo->desegment_len = 0;
3263 reported_len = tvb_reported_length(d_tvb);
3264 if(smb_dcerpc_reassembly && tvb_bytes_exist(d_tvb, 0, reported_len)){
3265 pinfo->can_desegment=2;
3268 save_fragmented = pinfo->fragmented;
3271 /* if we are not offering desegmentation, just try the heuristics
3274 if(!pinfo->can_desegment){
3275 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3276 goto clean_up_and_exit;
3280 /* below this line, we know we are doing reassembly */
3283 * We have to keep track of reassemblies by FID, because
3284 * we could have more than one pipe operation in a frame
3285 * with NetBIOS-over-TCP.
3287 * We also have to keep track of them by direction, as
3288 * we might have reassemblies in progress in both directions.
3290 * We do that by combining the FID and the direction and
3291 * using that as the reassembly ID.
3293 * The direction is indicated by the SMB request/reply flag - data
3294 * from client to server is carried in requests, data from server
3295 * to client is carried in replies.
3297 * We know that the FID is only 16 bits long, so we put the
3298 * direction in bit 17.
3301 if (smb_priv->request)
3302 hash_key |= 0x10000;
3304 /* this is a new packet, see if we are already reassembling this
3305 pdu and if not, check if the dissector wants us
3308 if(!pinfo->fd->flags.visited){
3310 * This is the first pass.
3312 * Check if we are already reassembling this PDU or not;
3313 * we check for an in-progress reassembly for this FID
3314 * in this direction, by searching for its reassembly
3317 fd_head=fragment_get(pinfo, fid, dcerpc_fragment_table);
3319 /* No reassembly, so this is a new pdu. check if the
3320 dissector wants us to reassemble it or if we
3321 already got the full pdu in this tvb.
3325 * First, just check if it looks like dcerpc or not.
3327 * XXX - this assumes that the dissector is idempotent,
3328 * as it's doing a "trial" dissection building no
3329 * tree; that's not necessarily the case.
3331 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, NULL);
3333 /* no this didnt look like something we know */
3335 goto clean_up_and_exit;
3338 /* did the subdissector want us to reassemble any
3341 if(pinfo->desegment_len){
3342 fragment_add_check(d_tvb, 0, pinfo, fid,
3343 dcerpc_fragment_table,
3344 dcerpc_reassembled_table,
3345 0, reported_len, TRUE);
3346 fragment_set_tot_len(pinfo, fid,
3347 dcerpc_fragment_table,
3348 pinfo->desegment_len+reported_len);
3349 goto clean_up_and_exit;
3352 /* guess we have the full pdu in this tvb then,
3353 just dissect it and continue.
3355 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3356 goto clean_up_and_exit;
3359 /* OK, we're already doing a reassembly for this FID.
3360 skip to last segment in the existing reassembly structure
3361 and add this fragment there
3363 XXX we might add code here to use any offset values
3364 we might pick up from the Read/Write calls instead of
3365 assuming we always get them in the correct order
3367 while(fd_head->next){
3368 fd_head=fd_head->next;
3370 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid,
3371 dcerpc_fragment_table, dcerpc_reassembled_table,
3372 fd_head->offset+fd_head->len,
3373 reported_len, TRUE);
3375 /* if we completed reassembly */
3377 new_tvb = tvb_new_real_data(fd_head->data,
3378 fd_head->datalen, fd_head->datalen);
3379 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3380 add_new_data_source(pinfo, new_tvb,
3382 pinfo->fragmented=FALSE;
3386 /* list what segments we have */
3387 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3388 tree, pinfo, d_tvb);
3390 /* dissect the full PDU */
3391 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3393 goto clean_up_and_exit;
3397 * This is not the first pass; see if it's in the table of
3398 * reassembled packets.
3400 * XXX - we know that several of the arguments aren't going to
3401 * be used, so we pass bogus variables. Can we clean this
3402 * up so that we don't have to distinguish between the first
3403 * pass and subsequent passes?
3405 fd_head=fragment_add_check(d_tvb, 0, pinfo, fid, dcerpc_fragment_table,
3406 dcerpc_reassembled_table, 0, 0, TRUE);
3408 /* we didnt find it, try any of the heuristic dissectors
3411 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3412 goto clean_up_and_exit;
3414 if(!fd_head->flags&FD_DEFRAGMENTED){
3415 /* we dont have a fully reassembled frame */
3416 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3417 goto clean_up_and_exit;
3420 /* it is reassembled but it was reassembled in a different frame */
3421 if(pinfo->fd->num!=fd_head->reassembled_in){
3422 proto_tree_add_uint(parent_tree, hf_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3423 goto clean_up_and_exit;
3427 /* display the reassembled pdu */
3428 new_tvb = tvb_new_real_data(fd_head->data,
3429 fd_head->datalen, fd_head->datalen);
3430 tvb_set_child_real_data_tvbuff(d_tvb, new_tvb);
3431 add_new_data_source(pinfo, new_tvb,
3433 pinfo->fragmented=FALSE;
3437 /* list what segments we have */
3438 show_fragment_tree(fd_head, &smb_pipe_frag_items,
3439 tree, pinfo, d_tvb);
3441 /* dissect the full PDU */
3442 result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree);
3447 /* clear out the variables */
3448 pinfo->private_data = smb_priv;
3449 pinfo->can_desegment=0;
3450 pinfo->desegment_offset = 0;
3451 pinfo->desegment_len = 0;
3454 call_dissector(data_handle, d_tvb, pinfo, parent_tree);
3456 pinfo->fragmented = save_fragmented;
3461 proto_register_pipe_dcerpc(void)
3463 register_heur_dissector_list("smb_transact", &smb_transact_heur_subdissector_list);
3464 register_init_routine(smb_dcerpc_reassembly_init);
3467 #define CALL_NAMED_PIPE 0x54
3468 #define WAIT_NAMED_PIPE 0x53
3469 #define PEEK_NAMED_PIPE 0x23
3470 #define Q_NM_P_HAND_STATE 0x21
3471 #define SET_NM_P_HAND_STATE 0x01
3472 #define Q_NM_PIPE_INFO 0x22
3473 #define TRANSACT_NM_PIPE 0x26
3474 #define RAW_READ_NM_PIPE 0x11
3475 #define RAW_WRITE_NM_PIPE 0x31
3477 static const value_string functions[] = {
3478 {CALL_NAMED_PIPE, "CallNamedPipe"},
3479 {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3480 {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3481 {Q_NM_P_HAND_STATE, "QNmPHandState"},
3482 {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3483 {Q_NM_PIPE_INFO, "QNmPipeInfo"},
3484 {TRANSACT_NM_PIPE, "TransactNmPipe"},
3485 {RAW_READ_NM_PIPE, "RawReadNmPipe"},
3486 {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3490 static const value_string pipe_status[] = {
3491 {1, "Disconnected by server"},
3493 {3, "Connection to server is OK"},
3494 {4, "Server end of pipe is closed"},
3498 #define PIPE_LANMAN 1
3499 #define PIPE_DCERPC 2
3501 /* decode the SMB pipe protocol
3503 pipe is the name of the pipe, e.g. LANMAN
3504 smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3507 smb_info->trans_subcmd gives us which pipe this response is for
3510 dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3511 tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3512 packet_info *pinfo, proto_tree *tree)
3514 smb_info_t *smb_info;
3515 smb_transact_info_t *tri;
3517 proto_item *pipe_item = NULL;
3518 proto_tree *pipe_tree = NULL;
3525 if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3527 pinfo->current_proto = "SMB Pipe";
3529 smb_info = pinfo->private_data;
3534 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
3535 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3537 if (check_col(pinfo->cinfo, COL_INFO)) {
3538 col_set_str(pinfo->cinfo, COL_INFO,
3539 smb_info->request ? "Request" : "Response");
3542 if (smb_info->sip != NULL)
3543 tri = smb_info->sip->extra_info;
3548 * Set up a subtree for the pipe protocol. (It might not contain
3552 sp_len = tvb_length(sp_tvb);
3556 pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3557 sp_tvb, 0, sp_len, FALSE);
3558 pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3563 * Do we have any setup words at all?
3565 if (s_tvb != NULL && tvb_length(s_tvb) != 0) {
3567 * Yes. The first of them is the function.
3569 function = tvb_get_letohs(s_tvb, offset);
3570 proto_tree_add_uint(pipe_tree, hf_pipe_function, s_tvb,
3571 offset, 2, function);
3573 if (check_col(pinfo->cinfo, COL_INFO)) {
3574 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3575 val_to_str(function, functions, "Unknown function (0x%04x)"),
3576 smb_info->request ? "Request" : "Response");
3579 tri->function = function;
3582 * The second of them depends on the function.
3586 case CALL_NAMED_PIPE:
3587 case WAIT_NAMED_PIPE:
3591 proto_tree_add_item(pipe_tree, hf_pipe_priority, s_tvb,
3595 case PEEK_NAMED_PIPE:
3596 case Q_NM_P_HAND_STATE:
3597 case SET_NM_P_HAND_STATE:
3598 case Q_NM_PIPE_INFO:
3599 case TRANSACT_NM_PIPE:
3600 case RAW_READ_NM_PIPE:
3601 case RAW_WRITE_NM_PIPE:
3605 fid = tvb_get_letohs(s_tvb, 2);
3606 add_fid(s_tvb, pinfo, pipe_tree, offset, 2, (guint16) fid);
3613 * It's something unknown.
3614 * XXX - put it into the tree?
3621 * This is either a response or a pipe transaction with
3622 * no setup information.
3624 * In the former case, we can get that information from
3625 * the matching request, if we saw it.
3627 * In the latter case, there is no function or FID.
3629 if (tri != NULL && tri->function != -1) {
3630 function = tri->function;
3631 proto_tree_add_uint(pipe_tree, hf_pipe_function, NULL,
3633 if (check_col(pinfo->cinfo, COL_INFO)) {
3634 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3635 val_to_str(function, functions, "Unknown function (0x%04x)"),
3636 smb_info->request ? "Request" : "Response");
3640 add_fid(NULL, pinfo, pipe_tree, 0, 0, (guint16) fid);
3648 * XXX - put the byte count and the pipe name into the tree as well;
3649 * that requires us to fetch a possibly-Unicode string.
3652 if(smb_info->request){
3653 if(strncmp(pipe,"LANMAN",6) == 0){
3654 trans_subcmd=PIPE_LANMAN;
3656 /* assume it is DCERPC */
3657 trans_subcmd=PIPE_DCERPC;
3660 if (!pinfo->fd->flags.visited)
3661 tri->trans_subcmd = trans_subcmd;
3663 trans_subcmd = tri->trans_subcmd;
3667 * We don't know what type of pipe transaction this
3668 * was, so indicate that we didn't dissect it.
3675 case CALL_NAMED_PIPE:
3676 case TRANSACT_NM_PIPE:
3677 switch(trans_subcmd){
3680 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3686 * Only dissect this if we know the FID.
3691 return dissect_pipe_dcerpc(d_tvb, pinfo, tree,
3700 * We don't know the function; we dissect only LANMAN
3701 * pipe messages, not RPC pipe messages, in that case.
3703 switch(trans_subcmd){
3705 return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo,
3711 case WAIT_NAMED_PIPE:
3714 case PEEK_NAMED_PIPE:
3716 * Request contains no parameters or data.
3718 if (!smb_info->request) {
3722 proto_tree_add_item(pipe_tree, hf_pipe_peek_available,
3723 p_tvb, offset, 2, TRUE);
3725 proto_tree_add_item(pipe_tree, hf_pipe_peek_remaining,
3726 p_tvb, offset, 2, TRUE);
3728 proto_tree_add_item(pipe_tree, hf_pipe_peek_status,
3729 p_tvb, offset, 2, TRUE);
3734 case Q_NM_P_HAND_STATE:
3736 * Request contains no parameters or data.
3738 if (!smb_info->request) {
3741 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, FALSE);
3745 case SET_NM_P_HAND_STATE:
3747 * Response contains no parameters or data.
3749 if (smb_info->request) {
3752 offset = dissect_ipc_state(p_tvb, pipe_tree, 0, TRUE);
3756 case Q_NM_PIPE_INFO:
3758 if (smb_info->request) {
3763 * Request contains an information level.
3765 info_level = tvb_get_letohs(p_tvb, offset);
3766 proto_tree_add_uint(pipe_tree, hf_pipe_getinfo_info_level,
3767 p_tvb, offset, 2, info_level);
3769 if (!pinfo->fd->flags.visited)
3770 tri->info_level = info_level;
3772 guint8 pipe_namelen;
3777 switch (tri->info_level) {
3780 proto_tree_add_item(pipe_tree,
3781 hf_pipe_getinfo_output_buffer_size,
3782 d_tvb, offset, 2, TRUE);
3784 proto_tree_add_item(pipe_tree,
3785 hf_pipe_getinfo_input_buffer_size,
3786 d_tvb, offset, 2, TRUE);
3788 proto_tree_add_item(pipe_tree,
3789 hf_pipe_getinfo_maximum_instances,
3790 d_tvb, offset, 1, TRUE);
3792 proto_tree_add_item(pipe_tree,
3793 hf_pipe_getinfo_current_instances,
3794 d_tvb, offset, 1, TRUE);
3796 pipe_namelen = tvb_get_guint8(d_tvb, offset);
3797 proto_tree_add_uint(pipe_tree,
3798 hf_pipe_getinfo_pipe_name_length,
3799 d_tvb, offset, 1, pipe_namelen);
3801 /* XXX - can this be Unicode? */
3802 proto_tree_add_item(pipe_tree,
3803 hf_pipe_getinfo_pipe_name,
3804 d_tvb, offset, pipe_namelen, TRUE);
3810 case RAW_READ_NM_PIPE:
3812 * Request contains no parameters or data.
3814 if (!smb_info->request) {
3818 offset = dissect_file_data(d_tvb, pipe_tree, 0,
3819 (guint16) tvb_reported_length(d_tvb),
3820 (guint16) tvb_reported_length(d_tvb));
3824 case RAW_WRITE_NM_PIPE:
3826 if (smb_info->request) {
3830 offset = dissect_file_data(d_tvb, pipe_tree,
3831 offset, (guint16) tvb_reported_length(d_tvb),
3832 (guint16) tvb_reported_length(d_tvb));
3836 proto_tree_add_item(pipe_tree,
3837 hf_pipe_write_raw_bytes_written,
3838 p_tvb, offset, 2, TRUE);
3847 proto_register_smb_pipe(void)
3849 static hf_register_info hf[] = {
3850 { &hf_pipe_function,
3851 { "Function", "pipe.function", FT_UINT16, BASE_HEX,
3852 VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3853 { &hf_pipe_priority,
3854 { "Priority", "pipe.priority", FT_UINT16, BASE_DEC,
3855 NULL, 0, "SMB Pipe Priority", HFILL }},
3856 { &hf_pipe_peek_available,
3857 { "Available Bytes", "pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3858 NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3859 { &hf_pipe_peek_remaining,
3860 { "Bytes Remaining", "pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3861 NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3862 { &hf_pipe_peek_status,
3863 { "Pipe Status", "pipe.peek.status", FT_UINT16, BASE_DEC,
3864 VALS(pipe_status), 0, "Pipe status", HFILL }},
3865 { &hf_pipe_getinfo_info_level,
3866 { "Information Level", "pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3867 NULL, 0, "Information level of information to return", HFILL }},
3868 { &hf_pipe_getinfo_output_buffer_size,
3869 { "Output Buffer Size", "pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3870 NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3871 { &hf_pipe_getinfo_input_buffer_size,
3872 { "Input Buffer Size", "pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3873 NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3874 { &hf_pipe_getinfo_maximum_instances,
3875 { "Maximum Instances", "pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3876 NULL, 0, "Maximum allowed number of instances", HFILL }},
3877 { &hf_pipe_getinfo_current_instances,
3878 { "Current Instances", "pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3879 NULL, 0, "Current number of instances", HFILL }},
3880 { &hf_pipe_getinfo_pipe_name_length,
3881 { "Pipe Name Length", "pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3882 NULL, 0, "Length of pipe name", HFILL }},
3883 { &hf_pipe_getinfo_pipe_name,
3884 { "Pipe Name", "pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3885 NULL, 0, "Name of pipe", HFILL }},
3886 { &hf_pipe_write_raw_bytes_written,
3887 { "Bytes Written", "pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3888 NULL, 0, "Number of bytes written to the pipe", HFILL }},
3889 { &hf_pipe_fragment_overlap,
3890 { "Fragment overlap", "pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3891 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3892 { &hf_pipe_fragment_overlap_conflict,
3893 { "Conflicting data in fragment overlap", "pipe.fragment.overlap.conflict", FT_BOOLEAN,
3894 BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3895 { &hf_pipe_fragment_multiple_tails,
3896 { "Multiple tail fragments found", "pipe.fragment.multipletails", FT_BOOLEAN,
3897 BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3898 { &hf_pipe_fragment_too_long_fragment,
3899 { "Fragment too long", "pipe.fragment.toolongfragment", FT_BOOLEAN,
3900 BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3901 { &hf_pipe_fragment_error,
3902 { "Defragmentation error", "pipe.fragment.error", FT_FRAMENUM,
3903 BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3904 { &hf_pipe_fragment,
3905 { "Fragment", "pipe.fragment", FT_FRAMENUM,
3906 BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3907 { &hf_pipe_fragments,
3908 { "Fragments", "pipe.fragments", FT_NONE,
3909 BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3910 { &hf_pipe_reassembled_in,
3911 { "This PDU is reassembled in", "pipe.reassembled_in", FT_FRAMENUM,
3912 BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3914 static gint *ett[] = {
3916 &ett_smb_pipe_fragment,
3917 &ett_smb_pipe_fragments,
3920 proto_smb_pipe = proto_register_protocol(
3921 "SMB Pipe Protocol", "SMB Pipe", "pipe");
3923 proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3924 proto_register_subtree_array(ett, array_length(ett));
3928 proto_reg_handoff_smb_pipe(void)
3930 data_handle = find_dissector("data");