2 * Common routines for smb packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-pop.c
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include <epan/wmem/wmem.h>
32 #include <epan/strutil.h>
33 #include "packet-smb-common.h"
35 #include "packet-dns.h"
38 * Share type values - used in LANMAN and in SRVSVC.
40 * XXX - should we dissect share type values, at least in SRVSVC, as
41 * a subtree with bitfields, as the 0x80000000 bit appears to be a
42 * hidden bit, with some number of bits at the bottom being the share
45 * Does LANMAN use that bit?
47 const value_string share_type_vals[] = {
48 {0, "Directory tree"},
50 {2, "Communications device"},
52 {0x80000000, "Hidden Directory tree"},
53 {0x80000001, "Hidden Printer queue"},
54 {0x80000002, "Hidden Communications device"},
55 {0x80000003, "Hidden IPC"},
59 int display_ms_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, char **data)
64 /* display a string from the tree and return the new offset */
66 str = tvb_get_stringz(wmem_packet_scope(), tvb, offset, &len);
67 proto_tree_add_string(tree, hf_index, tvb, offset, len, str);
69 /* Return a copy of the string if requested */
78 int display_unicode_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, char **data)
85 /* display a unicode string from the tree and return new offset */
88 * Get the length of the string.
89 * XXX - is it a bug or a feature that this will throw an exception
90 * if we don't find the '\0'? I think it's a feature.
93 while (tvb_get_letohs(tvb, offset + len) != '\0')
95 len += 2; /* count the '\0' too */
98 * Allocate a buffer for the string; "len" is the length in
99 * bytes, not the length in characters.
101 str = (char *)wmem_alloc(wmem_packet_scope(), len/2);
104 * XXX - this assumes the string is just ISO 8859-1; we need
105 * to better handle multiple character sets in Wireshark,
106 * including Unicode/ISO 10646, and multiple encodings of
107 * that character set (UCS-2, UTF-8, etc.).
111 while ((character = tvb_get_letohs(tvb, charoffset)) != '\0') {
112 *p++ = (char) character;
117 proto_tree_add_string(tree, hf_index, tvb, offset, len, str);
125 /* Max string length for displaying Unicode strings. */
126 #define MAX_UNICODE_STR_LEN 256
128 int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
132 const guchar *str = NULL;
134 /* The name data MUST start at offset 0 of the tvb */
135 compr_len = expand_dns_name(tvb, offset, MAX_UNICODE_STR_LEN+3+1, 0, &str);
136 proto_tree_add_string(tree, hf_index, tvb, offset, compr_len, str);
141 return offset + compr_len;
144 /* Turn a little-endian Unicode '\0'-terminated string into a string we
146 XXX - for now, we just handle the ISO 8859-1 characters.
147 If exactlen==TRUE then us_lenp contains the exact len of the string in
148 bytes. It might not be null terminated !
149 bc specifies the number of bytes in the byte parameters; Windows 2000,
150 at least, appears, in some cases, to put only 1 byte of 0 at the end
151 of a Unicode string if the byte count
154 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
162 gboolean overflow = FALSE;
164 cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
166 len = MAX_UNICODE_STR_LEN;
173 /* XXX - explain this */
175 us_len += 1; /* this is a one-byte null terminator */
179 uchar = tvb_get_letohs(tvb, offset);
181 us_len += 2; /* this is a two-byte null terminator */
186 if ((uchar & 0xFF00) == 0)
187 *p++ = (gchar) uchar; /* ISO 8859-1 */
189 *p++ = '?'; /* not 8859-1 */
199 if(us_len>= *us_lenp){
205 /* Note that we're not showing the full string. */
217 /* nopad == TRUE : Do not add any padding before this string
218 * exactlen == TRUE : len contains the exact len of the string in bytes.
219 * bc: pointer to variable with amount of data left in the byte parameters
223 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
224 gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
231 gboolean overflow = FALSE;
234 /* Not enough data in buffer */
239 if ((!nopad) && (*offsetp % 2)) {
240 (*offsetp)++; /* Looks like a pad byte there sometimes */
244 /* Not enough data in buffer */
251 if (string_len < 0) {
252 /* This probably means it's a very large unsigned number; just set
253 it to the largest signed number, so that we throw the appropriate
255 string_len = INT_MAX;
259 string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
264 * The string we return must be null-terminated.
266 cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
270 /* This probably means it's a very large unsigned number; just set
271 it to the largest signed number, so that we throw the appropriate
276 tvb_ensure_bytes_exist(tvb, *offsetp, copylen);
278 if (copylen > MAX_UNICODE_STR_LEN) {
279 copylen = MAX_UNICODE_STR_LEN;
283 tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
287 g_strlcat(cur, "...",MAX_UNICODE_STR_LEN+3+1);
292 string = tvb_get_const_stringz(tvb, *offsetp, &string_len);