2 * Common routines for smb packet dissection
3 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-pop.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/wmem/wmem.h>
34 #include <epan/strutil.h>
35 #include "packet-smb-common.h"
37 #include "packet-dns.h"
40 * Share type values - used in LANMAN and in SRVSVC.
42 * XXX - should we dissect share type values, at least in SRVSVC, as
43 * a subtree with bitfields, as the 0x80000000 bit appears to be a
44 * hidden bit, with some number of bits at the bottom being the share
47 * Does LANMAN use that bit?
49 const value_string share_type_vals
[] = {
50 {0, "Directory tree"},
52 {2, "Communications device"},
54 {0x80000000, "Hidden Directory tree"},
55 {0x80000001, "Hidden Printer queue"},
56 {0x80000002, "Hidden Communications device"},
57 {0x80000003, "Hidden IPC"},
61 int display_ms_string(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int hf_index
, char **data
)
66 /* display a string from the tree and return the new offset */
68 str
= tvb_get_stringz(wmem_packet_scope(), tvb
, offset
, &len
);
69 proto_tree_add_string(tree
, hf_index
, tvb
, offset
, len
, str
);
71 /* Return a copy of the string if requested */
80 int display_unicode_string(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int hf_index
, char **data
)
87 /* display a unicode string from the tree and return new offset */
90 * Get the length of the string.
91 * XXX - is it a bug or a feature that this will throw an exception
92 * if we don't find the '\0'? I think it's a feature.
95 while (tvb_get_letohs(tvb
, offset
+ len
) != '\0')
97 len
+= 2; /* count the '\0' too */
100 * Allocate a buffer for the string; "len" is the length in
101 * bytes, not the length in characters.
103 str
= (char *)wmem_alloc(wmem_packet_scope(), len
/2);
106 * XXX - this assumes the string is just ISO 8859-1; we need
107 * to better handle multiple character sets in Wireshark,
108 * including Unicode/ISO 10646, and multiple encodings of
109 * that character set (UCS-2, UTF-8, etc.).
113 while ((character
= tvb_get_letohs(tvb
, charoffset
)) != '\0') {
114 *p
++ = (char) character
;
119 proto_tree_add_string(tree
, hf_index
, tvb
, offset
, len
, str
);
127 /* Max string length for displaying Unicode strings. */
128 #define MAX_UNICODE_STR_LEN 256
130 int dissect_ms_compressed_string(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int hf_index
,
134 const guchar
*str
= NULL
;
136 /* The name data MUST start at offset 0 of the tvb */
137 compr_len
= expand_dns_name(tvb
, offset
, MAX_UNICODE_STR_LEN
+3+1, 0, &str
);
138 proto_tree_add_string(tree
, hf_index
, tvb
, offset
, compr_len
, str
);
143 return offset
+ compr_len
;
146 /* Turn a little-endian Unicode '\0'-terminated string into a string we
148 XXX - for now, we just handle the ISO 8859-1 characters.
149 If exactlen==TRUE then us_lenp contains the exact len of the string in
150 bytes. It might not be null terminated !
151 bc specifies the number of bytes in the byte parameters; Windows 2000,
152 at least, appears, in some cases, to put only 1 byte of 0 at the end
153 of a Unicode string if the byte count
156 unicode_to_str(tvbuff_t
*tvb
, int offset
, int *us_lenp
, gboolean exactlen
,
164 gboolean overflow
= FALSE
;
166 cur
=(gchar
*)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN
+3+1);
168 len
= MAX_UNICODE_STR_LEN
;
175 /* XXX - explain this */
177 us_len
+= 1; /* this is a one-byte null terminator */
181 uchar
= tvb_get_letohs(tvb
, offset
);
183 us_len
+= 2; /* this is a two-byte null terminator */
188 if ((uchar
& 0xFF00) == 0)
189 *p
++ = (gchar
) uchar
; /* ISO 8859-1 */
191 *p
++ = '?'; /* not 8859-1 */
201 if(us_len
>= *us_lenp
){
207 /* Note that we're not showing the full string. */
219 /* nopad == TRUE : Do not add any padding before this string
220 * exactlen == TRUE : len contains the exact len of the string in bytes.
221 * bc: pointer to variable with amount of data left in the byte parameters
225 get_unicode_or_ascii_string(tvbuff_t
*tvb
, int *offsetp
,
226 gboolean useunicode
, int *len
, gboolean nopad
, gboolean exactlen
,
233 gboolean overflow
= FALSE
;
236 /* Not enough data in buffer */
241 if ((!nopad
) && (*bcp
% 2)) {
242 (*offsetp
)++; /* Looks like a pad byte there sometimes */
246 /* Not enough data in buffer */
253 if (string_len
< 0) {
254 /* This probably means it's a very large unsigned number; just set
255 it to the largest signed number, so that we throw the appropriate
257 string_len
= INT_MAX
;
261 string
= unicode_to_str(tvb
, *offsetp
, &string_len
, exactlen
, *bcp
);
266 * The string we return must be null-terminated.
268 cur
=(gchar
*)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN
+3+1);
272 /* This probably means it's a very large unsigned number; just set
273 it to the largest signed number, so that we throw the appropriate
278 tvb_ensure_bytes_exist(tvb
, *offsetp
, copylen
);
280 if (copylen
> MAX_UNICODE_STR_LEN
) {
281 copylen
= MAX_UNICODE_STR_LEN
;
285 tvb_memcpy(tvb
, (guint8
*)cur
, *offsetp
, copylen
);
289 g_strlcat(cur
, "...",MAX_UNICODE_STR_LEN
+3+1);
294 string
= tvb_get_const_stringz(tvb
, *offsetp
, &string_len
);