/src/wireshark/epan/dissectors/packet-smb-mailslot.c
Line | Count | Source |
1 | | /* packet-smb-mailslot.c |
2 | | * Routines for SMB mailslot packet dissection |
3 | | * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * Copied from packet-pop.c |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include "packet-smb.h" |
19 | | #include "packet-smb-mailslot.h" |
20 | | |
21 | | void proto_register_smb_mailslot(void); |
22 | | void proto_reg_handoff_smb_mailslot(void); |
23 | | |
24 | | static int proto_smb_msp; |
25 | | static int hf_opcode; |
26 | | static int hf_priority; |
27 | | static int hf_class; |
28 | | static int hf_size; |
29 | | static int hf_name; |
30 | | |
31 | | static int ett_smb_msp; |
32 | | |
33 | | static dissector_handle_t mailslot_browse_handle; |
34 | | static dissector_handle_t mailslot_lanman_handle; |
35 | | static dissector_handle_t netlogon_handle; |
36 | | |
37 | 0 | #define MAILSLOT_UNKNOWN 0 |
38 | 0 | #define MAILSLOT_BROWSE 1 |
39 | 0 | #define MAILSLOT_LANMAN 2 |
40 | 0 | #define MAILSLOT_NET 3 |
41 | 0 | #define MAILSLOT_TEMP_NETLOGON 4 |
42 | 0 | #define MAILSLOT_MSSP 5 |
43 | | |
44 | | static const value_string opcode_vals[] = { |
45 | | {1, "Write Mail Slot"}, |
46 | | {0, NULL} |
47 | | }; |
48 | | |
49 | | static const value_string class_vals[] = { |
50 | | {1, "Reliable"}, |
51 | | {2, "Unreliable & Broadcast"}, |
52 | | {0, NULL} |
53 | | }; |
54 | | |
55 | | /* decode the SMB mail slot protocol |
56 | | for requests |
57 | | mailslot is the name of the mailslot, e.g. BROWSE |
58 | | si->trans_subcmd is set to the symbolic constant matching the mailslot name. |
59 | | for responses |
60 | | mailslot is NULL |
61 | | si->trans_subcmd gives us which mailslot this response refers to. |
62 | | */ |
63 | | |
64 | | bool |
65 | | dissect_mailslot_smb(tvbuff_t *mshdr_tvb, tvbuff_t *setup_tvb, |
66 | | tvbuff_t *tvb, const char *mailslot, packet_info *pinfo, |
67 | | proto_tree *parent_tree, smb_info_t* smb_info) |
68 | 0 | { |
69 | 0 | smb_transact_info_t *tri; |
70 | 0 | int trans_subcmd; |
71 | 0 | proto_tree *tree = NULL; |
72 | 0 | proto_item *item = NULL; |
73 | 0 | uint16_t opcode; |
74 | 0 | int offset = 0; |
75 | 0 | int len; |
76 | |
|
77 | 0 | if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_msp))) { |
78 | 0 | return false; |
79 | 0 | } |
80 | 0 | pinfo->current_proto = "SMB Mailslot"; |
81 | |
|
82 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Mailslot"); |
83 | |
|
84 | 0 | if ((tvb==NULL) || (tvb_reported_length(tvb)==0)) { |
85 | | /* Interim reply */ |
86 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Interim reply"); |
87 | 0 | return true; |
88 | 0 | } |
89 | | |
90 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
91 | |
|
92 | 0 | if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI) |
93 | 0 | tri = (smb_transact_info_t *)smb_info->sip->extra_info; |
94 | 0 | else |
95 | 0 | tri = NULL; |
96 | | |
97 | | /* check which mailslot this is about */ |
98 | 0 | trans_subcmd=MAILSLOT_UNKNOWN; |
99 | 0 | if(smb_info->request){ |
100 | 0 | if(strncmp(mailslot,"BROWSE",6) == 0){ |
101 | 0 | trans_subcmd=MAILSLOT_BROWSE; |
102 | 0 | } else if(strncmp(mailslot,"LANMAN",6) == 0){ |
103 | 0 | trans_subcmd=MAILSLOT_LANMAN; |
104 | 0 | } else if(strncmp(mailslot,"NET",3) == 0){ |
105 | 0 | trans_subcmd=MAILSLOT_NET; |
106 | 0 | } else if(strncmp(mailslot,"TEMP\\NETLOGON",13) == 0){ |
107 | 0 | trans_subcmd=MAILSLOT_TEMP_NETLOGON; |
108 | 0 | } else if(strncmp(mailslot,"MSSP",4) == 0){ |
109 | 0 | trans_subcmd=MAILSLOT_MSSP; |
110 | 0 | } |
111 | 0 | if (!pinfo->fd->visited) { |
112 | 0 | if (tri != NULL) |
113 | 0 | tri->trans_subcmd = trans_subcmd; |
114 | 0 | } |
115 | 0 | } else { |
116 | 0 | if(!tri){ |
117 | 0 | return false; |
118 | 0 | } else { |
119 | 0 | trans_subcmd = tri->trans_subcmd; |
120 | 0 | } |
121 | 0 | } |
122 | | |
123 | | /* Only do these ones if we have them. For fragmented SMB Transactions |
124 | | we may only have the setup area for the first fragment |
125 | | */ |
126 | 0 | if(mshdr_tvb && setup_tvb){ |
127 | 0 | if (parent_tree) { |
128 | 0 | item = proto_tree_add_item(parent_tree, proto_smb_msp, |
129 | 0 | mshdr_tvb, 0, -1, ENC_NA); |
130 | 0 | tree = proto_item_add_subtree(item, ett_smb_msp); |
131 | 0 | } |
132 | | |
133 | | /* do the opcode field */ |
134 | 0 | opcode = tvb_get_letohs(setup_tvb, offset); |
135 | |
|
136 | 0 | col_add_str(pinfo->cinfo, COL_INFO, |
137 | 0 | val_to_str(pinfo->pool, opcode, opcode_vals, "Unknown opcode: 0x%04x")); |
138 | | |
139 | | |
140 | | /* These are in the setup words; use "setup_tvb". */ |
141 | | |
142 | | /* opcode */ |
143 | 0 | proto_tree_add_uint(tree, hf_opcode, setup_tvb, offset, 2, |
144 | 0 | opcode); |
145 | 0 | offset += 2; |
146 | | |
147 | | /* priority */ |
148 | 0 | proto_tree_add_item(tree, hf_priority, setup_tvb, offset, 2, |
149 | 0 | ENC_LITTLE_ENDIAN); |
150 | 0 | offset += 2; |
151 | | |
152 | | /* class */ |
153 | 0 | proto_tree_add_item(tree, hf_class, setup_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
154 | 0 | offset += 2; |
155 | | |
156 | | /* These are in the rest of the data; use "mshdr_tvb", which |
157 | | starts at the same place "setup_tvb" does. */ |
158 | | |
159 | | /* size */ |
160 | | /* this is actually bytecount in the SMB Transaction command */ |
161 | 0 | proto_tree_add_item(tree, hf_size, mshdr_tvb, offset, 2, ENC_LITTLE_ENDIAN); |
162 | 0 | offset += 2; |
163 | | |
164 | | /* mailslot name */ |
165 | 0 | len = tvb_strsize(mshdr_tvb, offset); |
166 | 0 | proto_tree_add_item(tree, hf_name, mshdr_tvb, offset, len, ENC_ASCII); |
167 | 0 | offset += len; |
168 | 0 | proto_item_set_len(item, offset); |
169 | 0 | } |
170 | |
|
171 | 0 | switch(trans_subcmd){ |
172 | 0 | case MAILSLOT_BROWSE: |
173 | 0 | call_dissector(mailslot_browse_handle, tvb, pinfo, |
174 | 0 | parent_tree); |
175 | 0 | break; |
176 | | |
177 | 0 | case MAILSLOT_LANMAN: |
178 | 0 | call_dissector(mailslot_lanman_handle, tvb, pinfo, |
179 | 0 | parent_tree); |
180 | 0 | break; |
181 | | |
182 | 0 | case MAILSLOT_NET: |
183 | 0 | case MAILSLOT_TEMP_NETLOGON: |
184 | 0 | case MAILSLOT_MSSP: |
185 | 0 | call_dissector(netlogon_handle, tvb, pinfo, |
186 | 0 | parent_tree); |
187 | 0 | break; |
188 | | |
189 | 0 | default: |
190 | | /* |
191 | | * We dissected the mailslot header, but we don't know |
192 | | * how to dissect the message; dissect the latter as data, |
193 | | * but indicate that we successfully dissected the mailslot |
194 | | * stuff. |
195 | | */ |
196 | 0 | call_data_dissector(tvb, pinfo, parent_tree); |
197 | 0 | break; |
198 | 0 | } |
199 | 0 | return true; |
200 | 0 | } |
201 | | |
202 | | void |
203 | | proto_register_smb_mailslot(void) |
204 | 15 | { |
205 | 15 | static hf_register_info hf[] = { |
206 | 15 | { &hf_opcode, |
207 | 15 | { "Opcode", "mailslot.opcode", FT_UINT16, BASE_DEC, |
208 | 15 | VALS(opcode_vals), 0, "MAILSLOT OpCode", HFILL }}, |
209 | | |
210 | 15 | { &hf_priority, |
211 | 15 | { "Priority", "mailslot.priority", FT_UINT16, BASE_DEC, |
212 | 15 | NULL, 0, "MAILSLOT Priority of transaction", HFILL }}, |
213 | | |
214 | 15 | { &hf_class, |
215 | 15 | { "Class", "mailslot.class", FT_UINT16, BASE_DEC, |
216 | 15 | VALS(class_vals), 0, "MAILSLOT Class of transaction", HFILL }}, |
217 | | |
218 | 15 | { &hf_size, |
219 | 15 | { "Size", "mailslot.size", FT_UINT16, BASE_DEC, |
220 | 15 | NULL, 0, "MAILSLOT Total size of mail data", HFILL }}, |
221 | | |
222 | 15 | { &hf_name, |
223 | 15 | { "Mailslot Name", "mailslot.name", FT_STRING, BASE_NONE, |
224 | 15 | NULL, 0, "MAILSLOT Name of mailslot", HFILL }}, |
225 | | |
226 | 15 | }; |
227 | | |
228 | 15 | static int *ett[] = { |
229 | 15 | &ett_smb_msp |
230 | 15 | }; |
231 | | |
232 | 15 | proto_smb_msp = proto_register_protocol("SMB MailSlot Protocol", "SMB Mailslot", "mailslot"); |
233 | | |
234 | 15 | proto_register_field_array(proto_smb_msp, hf, array_length(hf)); |
235 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
236 | 15 | } |
237 | | |
238 | | void |
239 | | proto_reg_handoff_smb_mailslot(void) |
240 | 15 | { |
241 | 15 | mailslot_browse_handle = find_dissector_add_dependency("mailslot_browse", proto_smb_msp); |
242 | 15 | mailslot_lanman_handle = find_dissector_add_dependency("mailslot_lanman", proto_smb_msp); |
243 | 15 | netlogon_handle = find_dissector_add_dependency("smb_netlogon", proto_smb_msp); |
244 | 15 | } |
245 | | |
246 | | /* |
247 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
248 | | * |
249 | | * Local variables: |
250 | | * c-basic-offset: 8 |
251 | | * tab-width: 8 |
252 | | * indent-tabs-mode: t |
253 | | * End: |
254 | | * |
255 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
256 | | * :indentSize=8:tabSize=8:noTabs=false: |
257 | | */ |