1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * References used throughout this code:
30 *
31 * [CIFS/1.0] : A Common Internet File System (CIFS/1.0) Protocol
32 * Internet Engineering Task Force (IETF) draft
33 * Paul J. Leach, Microsoft, Dec. 1997
34 *
35 * [X/Open-SMB] : X/Open CAE Specification;
36 * Protocols for X/Open PC Interworking: SMB, Version 2
37 * X/Open Document Number: C209
38 */
39
40 #include <fcntl.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "snoop.h"
46
47 /* some macros just for compactness */
48 #define GETLINE get_line(0, 0)
49 #define DECARGS int flags, uchar_t *data, int len, char *extrainfo
50
51 /*
52 * SMB Format (header)
53 * [X/Open-SMB, Sec. 5.1]
54 */
55 struct smb {
56 uchar_t idf[4]; /* identifier, contains 0xff, 'SMB' */
57 uchar_t com; /* command code */
58 uchar_t rcls; /* error class */
59 uchar_t res;
60 uchar_t err[2]; /* error code */
61 uchar_t flags;
62 uchar_t flags2[2];
63 uchar_t re[12];
64 uchar_t tid[2];
65 uchar_t pid[2];
66 uchar_t uid[2];
67 uchar_t mid[2];
68 /*
69 * immediately after the above 32 byte header:
70 * unsigned char WordCount;
71 * unsigned short ParameterWords[ WordCount ];
72 * unsigned short ByteCount;
73 * unsigned char ParameterBytes[ ByteCount ];
74 */
75 };
76
77 /* smb flags */
78 #define SERVER_RESPONSE 0x80
79
80 static void interpret_sesssetupX(DECARGS);
81 static void interpret_tconX(DECARGS);
82 static void interpret_trans(DECARGS);
83 static void interpret_trans2(DECARGS);
84 static void interpret_negprot(DECARGS);
85 static void interpret_default(DECARGS);
86
87 /*
88 * Trans2 subcommand codes
89 * [X/Open-SMB, Sec. 16.1.7]
90 */
91 #define TRANS2_OPEN 0x00
92 #define TRANS2_FIND_FIRST 0x01
93 #define TRANS2_FIND_NEXT2 0x02
94 #define TRANS2_QUERY_FS_INFORMATION 0x03
95 #define TRANS2_QUERY_PATH_INFORMATION 0x05
96 #define TRANS2_SET_PATH_INFORMATION 0x06
97 #define TRANS2_QUERY_FILE_INFORMATION 0x07
98 #define TRANS2_SET_FILE_INFORMATION 0x08
99 #define TRANS2_CREATE_DIRECTORY 0x0D
100
101
102 struct decode {
103 char *name;
104 void (*func)(DECARGS);
105 char *callfmt;
106 char *replyfmt;
107 };
108
109 /*
110 * SMB command codes (function names)
111 * [X/Open-SMB, Sec. 5.2]
112 */
113 static struct decode SMBtable[256] = {
114 /* 0x00 */
115 { "mkdir", 0, 0, 0 },
116 { "rmdir", 0, 0, 0 },
117 { "open", 0, 0, 0 },
118 { "create", 0, 0, 0 },
119
120 {
121 "close", 0,
122 /* [X/Open-SMB, Sec. 7.10] */
123 "WFileID\0lLastModTime\0wByteCount\0\0",
124 "wByteCount\0\0"
125 },
126
127 { "flush", 0, 0, 0 },
128 { "unlink", 0, 0, 0 },
129
130 {
131 "mv", 0,
132 /* [X/Open-SMB, Sec. 7.11] */
133 "wFileAttributes\0wByteCount\0"
134 "r\0UFileName\0r\0UNewPath\0\0",
135 "wByteCount\0\0"
136 },
137
138 {
139 "getatr", 0,
140 /* [X/Open-SMB, Sec. 8.4] */
141 "dBytecount\0r\0UFileName\0\0",
142 "wFileAttributes\0lTime\0lSize\0R\0R\0R\0"
143 "R\0R\0wByteCount\0\0"
144 },
145
146 { "setatr", 0, 0, 0 },
147
148 {
149 "read", 0,
150 /* [X/Open-SMB, Sec. 7.4] */
151 "WFileID\0wI/0 Bytes\0LFileOffset\0"
152 "WBytesLeft\0wByteCount\0\0",
153 "WDataLength\0R\0R\0R\0R\0wByteCount\0\0"
154 },
155
156 {
157 "write", 0,
158 /* [X/Open-SMB, Sec. 7.5] */
159 "WFileID\0wI/0 Bytes\0LFileOffset\0WBytesLeft\0"
160 "wByteCount\0\0",
161 "WDataLength\0wByteCount\0\0"
162 },
163
164 { "lock", 0, 0, 0 },
165 { "unlock", 0, 0, 0 },
166 { "ctemp", 0, 0, 0 },
167 { "mknew", 0, 0, 0 },
168
169 /* 0x10 */
170 {
171 "chkpth", 0,
172 /* [X/Open-SMB, Sec. 8.7] */
173 "wByteCount\0r\0UFile\0\0",
174 "wByteCount\0\0"
175 },
176
177 { "exit", 0, 0, 0 },
178 { "lseek", 0, 0, 0 },
179 { "lockread", 0, 0, 0 },
180 { "writeunlock", 0, 0, 0 },
181 { 0, 0, 0, 0 },
182 { 0, 0, 0, 0 },
183 { 0, 0, 0, 0 },
184 { 0, 0, 0, 0 },
185 { 0, 0, 0, 0 },
186
187 {
188 "readbraw", 0,
189 /* [X/Open-SMB, Sec. 10.1] */
190 "WFileID\0LFileOffset\0wMaxCount\0"
191 "wMinCount\0lTimeout\0R\0wByteCount\0\0", 0
192 },
193
194 { "readbmpx", 0, 0, 0 },
195 { "readbs", 0, 0, 0 },
196 { "writebraw", 0, 0, 0 },
197 { "writebmpx", 0, 0, 0 },
198 { "writebs", 0, 0, 0 },
199
200 /* 0x20 */
201 { "writec", 0, 0, 0 },
202 { "qrysrv", 0, 0, 0 },
203 { "setattrE", 0, 0, 0 },
204 { "getattrE", 0, 0, 0 },
205
206 {
207 "lockingX", 0,
208 /* [X/Open-SMB, Sec. 12.2] */
209 "wChainedCommand\0wNextOffset\0WFileID\0"
210 "wLockType\0lOpenTimeout\0"
211 "W#Unlocks\0W#Locks\0wByteCount\0\0", 0
212 },
213
214 { "trans", interpret_trans, 0, 0 },
215 { "transs", 0, 0, 0 },
216 { "ioctl", 0, 0, 0 },
217 { "ioctls", 0, 0, 0 },
218 { "copy", 0, 0, 0 },
219 { "move", 0, 0, 0 },
220 { "echo", 0, 0, 0 },
221 { "writeclose", 0, 0, 0 },
222
223 {
224 "openX", 0,
225 /* [X/Open-SMB, Sec. 12.1] */
226 "wChainedCommand\0wNextOffset\0wFlags\0"
227 "wMode\0wSearchAttributes\0wFileAttributes\0"
228 "lTime\0wOpenFunction\0lFileSize\0lOpenTimeout\0"
229 "R\0R\0wByteCount\0r\0UFileName\0\0",
230 "wChainedCommand\0wNextOffset\0WFileID\0"
231 "wAttributes\0lTime\0LSize\0wOpenMode\0"
232 "wFileType\0wDeviceState\0wActionTaken\0"
233 "lUniqueFileID\0R\0wBytecount\0\0"
234 },
235
236 { "readX", 0, 0, 0 },
237 { "writeX", 0, 0, 0 },
238
239 /* 0x30 */
240 { 0, 0, 0, 0 },
241 { "closeTD", 0, 0, 0 },
242 { "trans2", interpret_trans2, 0, 0 },
243 { "trans2s", 0, 0, 0 },
244 {
245 "findclose", 0,
246 /* [X/Open-SMB, Sec. 15.4 ] */
247 "WFileID\0wByteCount\0\0",
248 "wByteCount\0\0"
249 },
250 { 0, 0, 0, 0 },
251 { 0, 0, 0, 0 },
252 { 0, 0, 0, 0 },
253 { 0, 0, 0, 0 },
254 { 0, 0, 0, 0 },
255 { 0, 0, 0, 0 },
256 { 0, 0, 0, 0 },
257 { 0, 0, 0, 0 },
258 { 0, 0, 0, 0 },
259 { 0, 0, 0, 0 },
260 { 0, 0, 0, 0 },
261
262 /* 0x40 */
263 { 0, 0, 0, 0 },
264 { 0, 0, 0, 0 },
265 { 0, 0, 0, 0 },
266 { 0, 0, 0, 0 },
267 { 0, 0, 0, 0 },
268 { 0, 0, 0, 0 },
269 { 0, 0, 0, 0 },
270 { 0, 0, 0, 0 },
271 { 0, 0, 0, 0 },
272 { 0, 0, 0, 0 },
273 { 0, 0, 0, 0 },
274 { 0, 0, 0, 0 },
275 { 0, 0, 0, 0 },
276 { 0, 0, 0, 0 },
277 { 0, 0, 0, 0 },
278 { 0, 0, 0, 0 },
279
280 /* 0x50 */
281 { 0, 0, 0, 0 },
282 { 0, 0, 0, 0 },
283 { 0, 0, 0, 0 },
284 { 0, 0, 0, 0 },
285 { 0, 0, 0, 0 },
286 { 0, 0, 0, 0 },
287 { 0, 0, 0, 0 },
288 { 0, 0, 0, 0 },
289 { 0, 0, 0, 0 },
290 { 0, 0, 0, 0 },
291 { 0, 0, 0, 0 },
292 { 0, 0, 0, 0 },
293 { 0, 0, 0, 0 },
294 { 0, 0, 0, 0 },
295 { 0, 0, 0, 0 },
296 { 0, 0, 0, 0 },
297
298 /* 0x60 */
299 { 0, 0, 0, 0 },
300 { 0, 0, 0, 0 },
301 { 0, 0, 0, 0 },
302 { 0, 0, 0, 0 },
303 { 0, 0, 0, 0 },
304 { 0, 0, 0, 0 },
305 { 0, 0, 0, 0 },
306 { 0, 0, 0, 0 },
307 { 0, 0, 0, 0 },
308 { 0, 0, 0, 0 },
309 { 0, 0, 0, 0 },
310 { 0, 0, 0, 0 },
311 { 0, 0, 0, 0 },
312 { 0, 0, 0, 0 },
313 { 0, 0, 0, 0 },
314 { 0, 0, 0, 0 },
315
316 /* 0x70 */
317 { "tcon", 0, 0, 0 },
318 {
319 "tdis", 0,
320 /* [X/Open-SMB, Sec. 6.3] */
321 "wByteCount\0\0",
322 "wByteCount\0\0"
323 },
324 { "negprot", interpret_negprot, 0, 0 },
325 { "sesssetupX", interpret_sesssetupX, 0, 0 },
326 {
327 "uloggoffX", 0,
328 /* [X/Open-SMB, Sec. 15.5] */
329 "wChainedCommand\0wNextOffset\0\0",
330 "wChainedCommnad\0wNextOffset\0\0" },
331 { "tconX", interpret_tconX, 0, 0 },
332 { 0, 0, 0, 0 },
333 { 0, 0, 0, 0 },
334 { 0, 0, 0, 0 },
335 { 0, 0, 0, 0 },
336 { 0, 0, 0, 0 },
337 { 0, 0, 0, 0 },
338 { 0, 0, 0, 0 },
339 { 0, 0, 0, 0 },
340 { 0, 0, 0, 0 },
341 { 0, 0, 0, 0 },
342
343 /* 0x80 */
344 { "dskattr", 0, 0, 0 },
345 { "search", 0, 0, 0 },
346 { "ffirst", 0, 0, 0 },
347 { "funique", 0, 0, 0 },
348 { "fclose", 0, 0, 0 },
349 { 0, 0, 0, 0 },
350 { 0, 0, 0, 0 },
351 { 0, 0, 0, 0 },
352 { 0, 0, 0, 0 },
353 { 0, 0, 0, 0 },
354 { 0, 0, 0, 0 },
355 { 0, 0, 0, 0 },
356 { 0, 0, 0, 0 },
357 { 0, 0, 0, 0 },
358 { 0, 0, 0, 0 },
359 { 0, 0, 0, 0 },
360
361 /* 0x90 */
362 { 0, 0, 0, 0 },
363 { 0, 0, 0, 0 },
364 { 0, 0, 0, 0 },
365 { 0, 0, 0, 0 },
366 { 0, 0, 0, 0 },
367 { 0, 0, 0, 0 },
368 { 0, 0, 0, 0 },
369 { 0, 0, 0, 0 },
370 { 0, 0, 0, 0 },
371 { 0, 0, 0, 0 },
372 { 0, 0, 0, 0 },
373 { 0, 0, 0, 0 },
374 { 0, 0, 0, 0 },
375 { 0, 0, 0, 0 },
376 { 0, 0, 0, 0 },
377 { 0, 0, 0, 0 },
378
379 /* 0xa0 */
380 /*
381 * Command codes 0xa0 to 0xa7 are from
382 * [CIFS/1.0, Sec. 5.1]
383 */
384 { " NT_Trans", 0, 0, 0 },
385 { " NT_Trans2", 0, 0, 0 },
386 {
387 " NT_CreateX", 0,
388 /* [CIFS/1.0, Sec. 4.2.1] */
389 "wChainedCommand\0wNextOffset\0r\0"
390 "wNameLength\0lCreateFlags\0lRootDirFID\0"
391 "lDesiredAccess\0R\0R\0R\0R\0"
392 "lNTFileAttributes\0lFileShareAccess\0"
393 "R\0R\0lCreateOption\0lImpersonationLevel\0"
394 "bSecurityFlags\0wByteCount\0r\0"
395 "UFileName\0\0",
396 "wChainedCommand\0wNextOffset\0"
397 "bOplockLevel\0WFileID\0lCreateAction\0\0"
398 },
399 { 0, 0, 0, 0 },
400 {
401 " NT_Cancel", 0,
402 /* [CIFS/1.0, Sec. 4.1.8] */
403 "wByteCount\0", 0
404 },
405 { 0, 0, 0, 0 },
406 { 0, 0, 0, 0 },
407 { 0, 0, 0, 0 },
408 { 0, 0, 0, 0 },
409 { 0, 0, 0, 0 },
410 { 0, 0, 0, 0 },
411 { 0, 0, 0, 0 },
412 { 0, 0, 0, 0 },
413 { 0, 0, 0, 0 },
414 { 0, 0, 0, 0 },
415 { 0, 0, 0, 0 },
416
417 /* 0xb0 */
418 { 0, 0, 0, 0 },
419 { 0, 0, 0, 0 },
420 { 0, 0, 0, 0 },
421 { 0, 0, 0, 0 },
422 { 0, 0, 0, 0 },
423 { 0, 0, 0, 0 },
424 { 0, 0, 0, 0 },
425 { 0, 0, 0, 0 },
426 { 0, 0, 0, 0 },
427 { 0, 0, 0, 0 },
428 { 0, 0, 0, 0 },
429 { 0, 0, 0, 0 },
430 { 0, 0, 0, 0 },
431 { 0, 0, 0, 0 },
432 { 0, 0, 0, 0 },
433 { 0, 0, 0, 0 },
434
435 /* 0xc0 */
436 { "splopen", 0, 0, 0 },
437 { "splwr", 0, 0, 0 },
438 { "splclose", 0, 0, 0 },
439 { "splretq", 0, 0, 0 },
440 { 0, 0, 0, 0 },
441 { 0, 0, 0, 0 },
442 { 0, 0, 0, 0 },
443 { 0, 0, 0, 0 },
444 { 0, 0, 0, 0 },
445 { 0, 0, 0, 0 },
446 { 0, 0, 0, 0 },
447 { 0, 0, 0, 0 },
448 { 0, 0, 0, 0 },
449 { 0, 0, 0, 0 },
450 { 0, 0, 0, 0 },
451 { 0, 0, 0, 0 },
452
453 /* 0xd0 */
454 { "sends", 0, 0, 0 },
455 { "sendb", 0, 0, 0 },
456 { "fwdname", 0, 0, 0 },
457 { "cancelf", 0, 0, 0 },
458 { "getmac", 0, 0, 0 },
459 { "sendstrt", 0, 0, 0 },
460 { "sendend", 0, 0, 0 },
461 { "sendtxt", 0, 0, 0 },
462 { 0, 0, 0, 0 },
463 { 0, 0, 0, 0 },
464 { 0, 0, 0, 0 },
465 { 0, 0, 0, 0 },
466 { 0, 0, 0, 0 },
467 { 0, 0, 0, 0 },
468 { 0, 0, 0, 0 },
469 { 0, 0, 0, 0 },
470
471 /* 0xe0 */
472 { 0, 0, 0, 0 },
473 { 0, 0, 0, 0 },
474 { 0, 0, 0, 0 },
475 { 0, 0, 0, 0 },
476 { 0, 0, 0, 0 },
477 { 0, 0, 0, 0 },
478 { 0, 0, 0, 0 },
479 { 0, 0, 0, 0 },
480 { 0, 0, 0, 0 },
481 { 0, 0, 0, 0 },
482 { 0, 0, 0, 0 },
483 { 0, 0, 0, 0 },
484 { 0, 0, 0, 0 },
485 { 0, 0, 0, 0 },
486 { 0, 0, 0, 0 },
487 { 0, 0, 0, 0 },
488
489 /* 0xf0 */
490 { 0, 0, 0, 0 },
491 { 0, 0, 0, 0 },
492 { 0, 0, 0, 0 },
493 { 0, 0, 0, 0 },
494 { 0, 0, 0, 0 },
495 { 0, 0, 0, 0 },
496 { 0, 0, 0, 0 },
497 { 0, 0, 0, 0 },
498 { 0, 0, 0, 0 },
499 { 0, 0, 0, 0 },
500 { 0, 0, 0, 0 },
501 { 0, 0, 0, 0 },
502 { 0, 0, 0, 0 },
503 { 0, 0, 0, 0 },
504 { 0, 0, 0, 0 },
505 { 0, 0, 0, 0 }
506 };
507
508 /* Helpers to get short and int values in Intel order. */
509 static ushort_t
get2(uchar_t * p)510 get2(uchar_t *p) {
511 return (p[0] + (p[1]<<8));
512 }
513 static uint_t
get4(uchar_t * p)514 get4(uchar_t *p) {
515 return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
516 }
517
518 /*
519 * This is called by snoop_netbios.c.
520 * This is the external entry point.
521 */
522 void
interpret_smb(int flags,uchar_t * data,int len)523 interpret_smb(int flags, uchar_t *data, int len)
524 {
525 struct smb *smb;
526 char *call_reply_detail, *call_reply_sum;
527 struct decode *decoder;
528 char xtra[300];
529 char *line;
530
531 smb = (struct smb *)data;
532 decoder = &SMBtable[smb->com & 255];
533 if (smb->flags & SERVER_RESPONSE) {
534 call_reply_detail = "SERVER RESPONSE";
535 call_reply_sum = "R";
536 } else {
537 call_reply_detail = "CLIENT REQUEST";
538 call_reply_sum = "C";
539 }
540 xtra[0] = '\0';
541
542 /*
543 * SMB Header description
544 * [X/Open-SMB, Sec. 5.1]
545 */
546 if (flags & F_DTAIL) {
547 show_header("SMB: ", "SMB Header", len);
548 show_space();
549 sprintf(GETLINE, "%s", call_reply_detail);
550
551 (void) sprintf(GETLINE, "Command code = 0x%x",
552 smb->com);
553 if (decoder->name)
554 (void) sprintf(GETLINE,
555 "Command name = SMB%s", decoder->name);
556
557 show_space();
558 sprintf(GETLINE, "SMB Status:");
559
560 /* Error classes [X/Open-SMB, Sec. 5.6] */
561 switch (smb->rcls) {
562 case 0x00:
563 sprintf(GETLINE,
564 " - Error class = No error");
565 break;
566 case 0x01:
567 sprintf(GETLINE,
568 " - Error class = Operating System");
569 break;
570 case 0x02:
571 sprintf(GETLINE,
572 " - Error class = LMX server");
573 break;
574 case 0x03:
575 sprintf(GETLINE,
576 " - Error class = Hardware");
577 break;
578 case 0xff:
579 default:
580 sprintf(GETLINE,
581 " - Error class = Incorrect format.");
582 break;
583 }
584
585 if (smb->err[0] != 0x00) {
586 sprintf(GETLINE,
587 " - Error code = %x", smb->err[0]);
588 } else
589 sprintf(GETLINE, " - Error code = No error");
590
591 show_space();
592
593 sprintf(GETLINE, "Header:");
594 sprintf(GETLINE, " - Tree ID (TID) = 0x%.4x",
595 get2(smb->tid));
596 sprintf(GETLINE, " - Process ID (PID) = 0x%.4x",
597 get2(smb->pid));
598 sprintf(GETLINE, " - User ID (UID) = 0x%.4x",
599 get2(smb->uid));
600 sprintf(GETLINE, " - Multiplex ID (MID) = 0x%.4x",
601 get2(smb->mid));
602 sprintf(GETLINE, " - Flags summary = 0x%.2x",
603 smb->flags);
604 sprintf(GETLINE, " - Flags2 summary = 0x%.4x",
605 get2(smb->flags2));
606 show_space();
607 }
608
609 if (decoder->func)
610 (decoder->func)(flags, (uchar_t *)data, len, xtra);
611 else
612 interpret_default(flags, (uchar_t *)data, len, xtra);
613
614 if (flags & F_SUM) {
615 line = get_sum_line();
616 if (decoder->name)
617 sprintf(line,
618 "SMB %s Code=0x%x Name=SMB%s %sError=%x ",
619 call_reply_sum, smb->com, decoder->name, xtra,
620 smb->err[0]);
621
622 else sprintf(line, "SMB %s Code=0x%x Error=%x ",
623 call_reply_sum, smb->com, smb->err[0]);
624
625 line += strlen(line);
626 }
627
628 if (flags & F_DTAIL)
629 show_trailer();
630 }
631
632 static void
output_bytes(uchar_t * data,int bytecount)633 output_bytes(uchar_t *data, int bytecount)
634 {
635 int i;
636 char buff[80];
637 char word[10];
638
639 buff[0] = word[0] = '\0';
640 sprintf(GETLINE, "Byte values (in hex):");
641 for (i = 0; i < bytecount; i++) {
642 sprintf(word, "%.2x ", data[i]);
643 strcat(buff, word);
644 if ((i+1)%16 == 0 || i == (bytecount-1)) {
645 sprintf(GETLINE, "%s", buff);
646 strcpy(buff, "");
647 }
648 }
649 }
650
651 /*
652 * Based on the Unicode Standard, http://www.unicode.org/
653 * "The Unicode Standard: A Technical Introduction", June 1998
654 */
655 static int
unicode2ascii(char * outstr,int outlen,uchar_t * instr,int inlen)656 unicode2ascii(char *outstr, int outlen, uchar_t *instr, int inlen)
657 {
658 int i = 0, j = 0;
659 char c;
660
661 while (i < inlen && j < (outlen-1)) {
662 /* Show unicode chars >= 256 as '?' */
663 if (instr[i+1])
664 c = '?';
665 else
666 c = instr[i];
667 if (c == '\0')
668 break;
669 outstr[j] = c;
670 i += 2;
671 j++;
672 }
673 outstr[j] = '\0';
674 return (j);
675 }
676
677 /*
678 * TRANS2 information levels
679 * [X/Open-SMB, Sec. 16.1.6]
680 */
681 static void
get_info_level(char * outstr,int value)682 get_info_level(char *outstr, int value)
683 {
684
685 switch (value) {
686 case 1:
687 sprintf(outstr, "Standard"); break;
688 case 2:
689 sprintf(outstr, "Query EA Size"); break;
690 case 3:
691 sprintf(outstr, "Query EAS from List"); break;
692 case 0x101:
693 sprintf(outstr, "Directory Info"); break;
694 case 0x102:
695 sprintf(outstr, "Full Directory Info"); break;
696 case 0x103:
697 sprintf(outstr, "Names Info"); break;
698 case 0x104:
699 sprintf(outstr, "Both Directory Info"); break;
700 default:
701 sprintf(outstr, "Unknown"); break;
702 }
703 }
704
705 /*
706 * Interpret TRANS2_QUERY_PATH subcommand
707 * [X/Open-SMB, Sec. 16.7]
708 */
709 /* ARGSUSED */
710 static void
output_trans2_querypath(int flags,uchar_t * data,char * xtra)711 output_trans2_querypath(int flags, uchar_t *data, char *xtra)
712 {
713 int length;
714 char filename[256];
715
716 if (flags & F_SUM) {
717 length = sprintf(xtra, "QueryPathInfo ");
718 xtra += length;
719 data += 6;
720 (void) unicode2ascii(filename, 256, data, 512);
721 sprintf(xtra, "File=%s ", filename);
722 }
723
724 if (flags & F_DTAIL) {
725 sprintf(GETLINE, "FunctionName = QueryPathInfo");
726 sprintf(GETLINE, "InfoLevel = 0x%.4x",
727 get2(data));
728 data += 6;
729 (void) unicode2ascii(filename, 256, data, 512);
730 sprintf(GETLINE, "FileName = %s",
731 filename);
732 }
733 }
734
735 /*
736 * Interpret TRANS2_QUERY_FILE subcommand
737 * [X/Open-SMB, Sec. 16.9]
738 */
739 /* ARGSUSED */
740 static void
output_trans2_queryfile(int flags,uchar_t * data,char * xtra)741 output_trans2_queryfile(int flags, uchar_t *data, char *xtra)
742 {
743 int length;
744
745 if (flags & F_SUM) {
746 length = sprintf(xtra, "QueryFileInfo ");
747 xtra += length;
748 sprintf(xtra, "FileID=0x%x ", get2(data));
749 }
750
751 if (flags & F_DTAIL) {
752 sprintf(GETLINE, "FunctionName = QueryFileInfo");
753 sprintf(GETLINE, "FileID = 0x%.4x",
754 get2(data));
755 data += 2;
756 sprintf(GETLINE, "InfoLevel = 0x%.4x",
757 get2(data));
758 }
759 }
760
761 /*
762 * Interpret TRANS2_SET_FILE subcommand
763 * [X/Open-SMB, Sec. 16.10]
764 */
765 /* ARGSUSED */
766 static void
output_trans2_setfile(int flags,uchar_t * data,char * xtra)767 output_trans2_setfile(int flags, uchar_t *data, char *xtra)
768 {
769 int length;
770
771 if (flags & F_SUM) {
772 length = sprintf(xtra, "SetFileInfo ");
773 xtra += length;
774 sprintf(xtra, "FileID=0x%x ", get2(data));
775 }
776
777 if (flags & F_DTAIL) {
778 sprintf(GETLINE, "FunctionName = SetFileInfo");
779 sprintf(GETLINE, "FileID = 0x%.4x",
780 get2(data));
781 data += 2;
782 sprintf(GETLINE, "InfoLevel = 0x%.4x",
783 get2(data));
784 }
785 }
786
787 /*
788 * Interpret TRANS2_FIND_FIRST subcommand
789 * [X/Open-SMB, Sec. 16.3]
790 */
791 /* ARGSUSED */
792 static void
output_trans2_findfirst(int flags,uchar_t * data,char * xtra)793 output_trans2_findfirst(int flags, uchar_t *data, char *xtra)
794 {
795 int length;
796 char filename[256];
797 char infolevel[100];
798
799 if (flags & F_SUM) {
800 length = sprintf(xtra, "Findfirst ");
801 xtra += length;
802 data += 12;
803 (void) unicode2ascii(filename, 256, data, 512);
804 sprintf(xtra, "File=%s ", filename);
805 }
806
807 if (flags & F_DTAIL) {
808 sprintf(GETLINE, "FunctionName = Findfirst");
809 sprintf(GETLINE, "SearchAttributes = 0x%.4x",
810 get2(data));
811 data += 2;
812 sprintf(GETLINE, "FindCount = 0x%.4x",
813 get2(data));
814 data += 2;
815 sprintf(GETLINE, "FindFlags = 0x%.4x",
816 get2(data));
817 data += 2;
818 get_info_level(infolevel, get2(data));
819 sprintf(GETLINE, "InfoLevel = %s",
820 infolevel);
821 data += 6;
822 (void) unicode2ascii(filename, 256, data, 512);
823 sprintf(GETLINE, "FileName = %s",
824 filename);
825 }
826 }
827
828
829 /*
830 * Interpret TRANS2_FIND_NEXT subcommand
831 * [X/Open-SMB, Sec. 16.4]
832 */
833 /* ARGSUSED */
834 static void
output_trans2_findnext(int flags,uchar_t * data,char * xtra)835 output_trans2_findnext(int flags, uchar_t *data, char *xtra)
836 {
837 int length;
838 char filename[256];
839 char infolevel[100];
840
841 if (flags & F_SUM) {
842 length = sprintf(xtra, "Findnext ");
843 xtra += length;
844 data += 12;
845 (void) unicode2ascii(filename, 256, data, 512);
846 sprintf(xtra, "File=%s ", filename);
847 }
848
849 if (flags & F_DTAIL) {
850 sprintf(GETLINE, "FunctionName = Findnext");
851 sprintf(GETLINE, "FileID = 0x%.4x",
852 get2(data));
853 data += 2;
854 sprintf(GETLINE, "FindCount = 0x%.4x",
855 get2(data));
856 data += 2;
857 get_info_level(infolevel, get2(data));
858 sprintf(GETLINE, "InfoLevel = %s",
859 infolevel);
860 data += 2;
861 sprintf(GETLINE, "FindKey = 0x%.8x",
862 get4(data));
863 data += 4;
864 sprintf(GETLINE, "FindFlags = 0x%.4x",
865 get2(data));
866 data += 2;
867 (void) unicode2ascii(filename, 256, data, 512);
868 sprintf(GETLINE, "FileName = %s",
869 filename);
870 }
871 }
872
873 /*
874 * Interpret a "Negprot" SMB
875 * [X/Open-SMB, Sec. 6.1]
876 */
877 /* ARGSUSED */
878 static void
interpret_negprot(int flags,uchar_t * data,int len,char * xtra)879 interpret_negprot(int flags, uchar_t *data, int len, char *xtra)
880 {
881 int length;
882 int bytecount;
883 char dialect[256];
884 struct smb *smbdata;
885 uchar_t *protodata;
886
887 smbdata = (struct smb *)data;
888 protodata = (uchar_t *)data + sizeof (struct smb);
889 protodata++; /* skip wordcount */
890
891 if (smbdata->flags & SERVER_RESPONSE) {
892 if (flags & F_SUM) {
893 sprintf(xtra, "Dialect#=%d ", protodata[0]);
894 }
895 if (flags & F_DTAIL) {
896 sprintf(GETLINE, "Protocol Index = %d",
897 protodata[0]);
898 }
899 } else {
900 /*
901 * request packet:
902 * short bytecount;
903 * struct { char fmt; char name[]; } dialects
904 */
905 bytecount = get2(protodata);
906 protodata += 2;
907 if (flags & F_SUM) {
908 while (bytecount > 1) {
909 length = snprintf(dialect, sizeof (dialect),
910 "%s", (char *)protodata+1);
911 protodata += (length+2);
912 if (protodata >= data+len)
913 break;
914 bytecount -= (length+2);
915 }
916 sprintf(xtra, "LastDialect=%s ", dialect);
917 }
918 if (flags & F_DTAIL) {
919 sprintf(GETLINE, "ByteCount = %d", bytecount);
920 while (bytecount > 1) {
921 length = snprintf(dialect, sizeof (dialect),
922 "%s", (char *)protodata+1);
923 sprintf(GETLINE, "Dialect String = %s",
924 dialect);
925 protodata += (length+2);
926 if (protodata >= data+len)
927 break;
928 bytecount -= (length+2);
929 }
930 }
931 }
932 }
933
934 /*
935 * LAN Manager remote admin function names.
936 * [X/Open-SMB, Appendix B.8]
937 */
938 static const char *apinames[] = {
939 "RNetShareEnum",
940 "RNetShareGetInfo",
941 "NetShareSetInfo",
942 "NetShareAdd",
943 "NetShareDel",
944 "NetShareCheck",
945 "NetSessionEnum",
946 "NetSessionGetInfo",
947 "NetSessionDel",
948 "NetConnectionEnum",
949 "NetFileEnum",
950 "NetFileGetInfo",
951 "NetFileClose",
952 "RNetServerGetInfo",
953 "NetServerSetInfo",
954 "NetServerDiskEnum",
955 "NetServerAdminCommand",
956 "NetAuditOpen",
957 "NetAuditClear",
958 "NetErrorLogOpen",
959 "NetErrorLogClear",
960 "NetCharDevEnum",
961 "NetCharDevGetInfo",
962 "NetCharDevControl",
963 "NetCharDevQEnum",
964 "NetCharDevQGetInfo",
965 "NetCharDevQSetInfo",
966 "NetCharDevQPurge",
967 "RNetCharDevQPurgeSelf",
968 "NetMessageNameEnum",
969 "NetMessageNameGetInfo",
970 "NetMessageNameAdd",
971 "NetMessageNameDel",
972 "NetMessageNameFwd",
973 "NetMessageNameUnFwd",
974 "NetMessageBufferSend",
975 "NetMessageFileSend",
976 "NetMessageLogFileSet",
977 "NetMessageLogFileGet",
978 "NetServiceEnum",
979 "RNetServiceInstall",
980 "RNetServiceControl",
981 "RNetAccessEnum",
982 "RNetAccessGetInfo",
983 "RNetAccessSetInfo",
984 "RNetAccessAdd",
985 "RNetAccessDel",
986 "NetGroupEnum",
987 "NetGroupAdd",
988 "NetGroupDel",
989 "NetGroupAddUser",
990 "NetGroupDelUser",
991 "NetGroupGetUsers",
992 "NetUserEnum",
993 "RNetUserAdd",
994 "NetUserDel",
995 "NetUserGetInfo",
996 "RNetUserSetInfo",
997 "RNetUserPasswordSet",
998 "NetUserGetGroups",
999 "NetWkstaLogon",
1000 "NetWkstaLogoff",
1001 "NetWkstaSetUID",
1002 "NetWkstaGetInfo",
1003 "NetWkstaSetInfo",
1004 "NetUseEnum",
1005 "NetUseAdd",
1006 "NetUseDel",
1007 "NetUseGetInfo",
1008 "DosPrintQEnum",
1009 "DosPrintQGetInfo",
1010 "DosPrintQSetInfo",
1011 "DosPrintQAdd",
1012 "DosPrintQDel",
1013 "DosPrintQPause",
1014 "DosPrintQContinue",
1015 "DosPrintJobEnum",
1016 "DosPrintJobGetInfo",
1017 "RDosPrintJobSetInfo",
1018 "DosPrintJobAdd",
1019 "DosPrintJobSchedule",
1020 "RDosPrintJobDel",
1021 "RDosPrintJobPause",
1022 "RDosPrintJobContinue",
1023 "DosPrintDestEnum",
1024 "DosPrintDestGetInfo",
1025 "DosPrintDestControl",
1026 "NetProfileSave",
1027 "NetProfileLoad",
1028 "NetStatisticsGet",
1029 "NetStatisticsClear",
1030 "NetRemoteTOD",
1031 "NetBiosEnum",
1032 "NetBiosGetInfo",
1033 "NetServerEnum",
1034 "I_NetServerEnum",
1035 "NetServiceGetInfo",
1036 "NetSplQmAbort",
1037 "NetSplQmClose",
1038 "NetSplQmEndDoc",
1039 "NetSplQmOpen",
1040 "NetSplQmStartDoc",
1041 "NetSplQmWrite",
1042 "DosPrintQPurge",
1043 "NetServerEnum2"
1044 };
1045 static const int apimax = (
1046 sizeof (apinames) /
1047 sizeof (apinames[0]));
1048
1049 /*
1050 * Interpret a "trans" SMB
1051 * [X/Open-SMB, Appendix B]
1052 *
1053 * This is very much like "trans2" below.
1054 */
1055 /* ARGSUSED */
1056 static void
interpret_trans(int flags,uchar_t * data,int len,char * xtra)1057 interpret_trans(int flags, uchar_t *data, int len, char *xtra)
1058 {
1059 struct smb *smb;
1060 uchar_t *vwv; /* word parameters */
1061 int wordcount;
1062 uchar_t *byteparms;
1063 int bytecount;
1064 int parambytes;
1065 int paramoffset;
1066 int setupcount;
1067 int subcode;
1068 uchar_t *setupdata;
1069 uchar_t *params;
1070 int apinum;
1071 int isunicode;
1072 char filename[256];
1073
1074 smb = (struct smb *)data;
1075 vwv = (uchar_t *)data + sizeof (struct smb);
1076 wordcount = *vwv++;
1077
1078 byteparms = vwv + (2 * wordcount);
1079 bytecount = get2(byteparms);
1080 byteparms += 2;
1081
1082 /*
1083 * Print the lengths before we (potentially) bail out
1084 * due to lack of data (so the user knows why we did).
1085 */
1086 if (flags & F_DTAIL) {
1087 sprintf(GETLINE, "WordCount = %d", wordcount);
1088 sprintf(GETLINE, "ByteCount = %d", bytecount);
1089 }
1090
1091 /* Get length and location of params and setup data. */
1092 if (!(smb->flags & SERVER_RESPONSE)) {
1093 /* CALL */
1094 if (wordcount < 14)
1095 return;
1096 parambytes = get2(vwv + (2 * 9));
1097 paramoffset = get2(vwv + (2 * 10));
1098 setupcount = *(vwv + (2 * 13));
1099 setupdata = vwv + (2 * 14);
1100 } else {
1101 /* REPLY */
1102 if (wordcount < 10)
1103 return;
1104 parambytes = get2(vwv + (2 * 3));
1105 paramoffset = get2(vwv + (2 * 4));
1106 setupcount = *(vwv + (2 * 9));
1107 setupdata = vwv + (2 * 10);
1108 }
1109 if (setupcount > 0)
1110 subcode = get2(setupdata);
1111 else
1112 subcode = -1; /* invalid */
1113
1114 /* The parameters are offset from the SMB header. */
1115 params = data + paramoffset;
1116 if (parambytes > 0)
1117 apinum = params[0];
1118 else
1119 apinum = -1; /* invalid */
1120
1121 /* Is the pathname in unicode? */
1122 isunicode = smb->flags2[1] & 0x80;
1123
1124 if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
1125 /* This is a CALL. */
1126 /* print the word parameters */
1127 sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
1128 sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
1129 sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
1130 sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
1131 sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
1132 sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
1133 sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
1134 /* skip Reserved2 */
1135 sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
1136 sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
1137 sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
1138 sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
1139 sprintf(GETLINE, "SetupWords = %d", setupcount);
1140
1141 /* That finishes the VWV, now the misc. stuff. */
1142 if (subcode >= 0)
1143 sprintf(GETLINE, "Setup[0] = %d", subcode);
1144 if (apinum >= 0)
1145 sprintf(GETLINE, "APIcode = %d", apinum);
1146 if (0 <= apinum && apinum < apimax)
1147 sprintf(GETLINE, "APIname = %s", apinames[apinum]);
1148
1149 /* Finally, print the byte parameters. */
1150 if (isunicode) {
1151 byteparms += 1; /* alignment padding */
1152 (void) unicode2ascii(
1153 filename, 256, byteparms, bytecount);
1154 } else {
1155 strlcpy(filename, (char *)byteparms, sizeof (filename));
1156 }
1157 sprintf(GETLINE, "FileName = %s", filename);
1158 }
1159
1160 if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
1161 /* This is a REPLY. */
1162 /* print the word parameters */
1163 sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
1164 sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
1165 /* skip Reserved */
1166 sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
1167 sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
1168 sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
1169 sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
1170 sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
1171 sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
1172 sprintf(GETLINE, "SetupWords = %d", setupcount);
1173
1174 output_bytes(byteparms, bytecount);
1175 }
1176 }
1177
1178 /*
1179 * Interpret a "TconX" SMB
1180 * [X/Open-SMB, Sec. 11.4]
1181 */
1182 /* ARGSUSED */
1183 static void
interpret_tconX(int flags,uchar_t * data,int len,char * xtra)1184 interpret_tconX(int flags, uchar_t *data, int len, char *xtra)
1185 {
1186 int length;
1187 int bytecount;
1188 int passwordlength;
1189 int wordcount;
1190 char tempstring[256];
1191 struct smb *smbdata;
1192 uchar_t *tcondata;
1193
1194 smbdata = (struct smb *)data;
1195 tcondata = (uchar_t *)data + sizeof (struct smb);
1196 wordcount = *tcondata++;
1197
1198 if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
1199 tcondata += 6;
1200 passwordlength = get2(tcondata);
1201 tcondata = tcondata + 4 + passwordlength;
1202 length = snprintf(tempstring, sizeof (tempstring), "%s",
1203 (char *)tcondata);
1204 sprintf(xtra, "Share=%s ", tempstring);
1205 }
1206
1207 if (flags & F_SUM && smbdata->flags & SERVER_RESPONSE) {
1208 tcondata += 8;
1209 length = snprintf(tempstring, sizeof (tempstring), "%s",
1210 (char *)tcondata);
1211 sprintf(xtra, "Type=%s ", tempstring);
1212 }
1213
1214 if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
1215 sprintf(GETLINE, "WordCount = %d", wordcount);
1216 sprintf(GETLINE, "ChainedCommand = 0x%.2x",
1217 tcondata[0]);
1218 tcondata += 2;
1219 sprintf(GETLINE, "NextOffset = 0x%.4x",
1220 get2(tcondata));
1221 tcondata += 2;
1222 sprintf(GETLINE, "DisconnectFlag = 0x%.4x",
1223 get2(tcondata));
1224 tcondata += 2;
1225 passwordlength = get2(tcondata);
1226 sprintf(GETLINE, "PasswordLength = 0x%.4x",
1227 passwordlength);
1228 tcondata += 2;
1229 bytecount = get2(tcondata);
1230 sprintf(GETLINE, "ByteCount = %d", bytecount);
1231 tcondata = tcondata + 2 + passwordlength;
1232 length = snprintf(tempstring, sizeof (tempstring), "%s",
1233 (char *)tcondata);
1234 tcondata += (length+1);
1235 sprintf(GETLINE, "FileName = %s", tempstring);
1236 length = snprintf(tempstring, sizeof (tempstring), "%s",
1237 (char *)tcondata);
1238 tcondata += (length+1);
1239 sprintf(GETLINE, "ServiceName = %s", tempstring);
1240 }
1241
1242 if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
1243 sprintf(GETLINE, "WordCount = %d", wordcount);
1244 sprintf(GETLINE, "ChainedCommand = 0x%.2x",
1245 tcondata[0]);
1246 tcondata += 2;
1247 sprintf(GETLINE, "NextOffset = 0x%.4x",
1248 get2(tcondata));
1249 tcondata += 2;
1250 sprintf(GETLINE, "OptionalSupport = 0x%.4x",
1251 get2(tcondata));
1252 tcondata += 2;
1253 bytecount = get2(tcondata);
1254 sprintf(GETLINE, "ByteCount = %d", bytecount);
1255 tcondata += 2;
1256 length = snprintf(tempstring, sizeof (tempstring), "%s",
1257 (char *)tcondata);
1258 tcondata += (length+1);
1259 sprintf(GETLINE, "ServiceName = %s", tempstring);
1260 length = snprintf(tempstring, sizeof (tempstring), "%s",
1261 (char *)tcondata);
1262 tcondata += (length+1);
1263 sprintf(GETLINE, "NativeFS = %s", tempstring);
1264 }
1265 }
1266
1267 /*
1268 * Interpret a "SesssetupX" SMB
1269 * [X/Open-SMB, Sec. 11.3]
1270 */
1271 /* ARGSUSED */
1272 static void
interpret_sesssetupX(int flags,uchar_t * data,int len,char * xtra)1273 interpret_sesssetupX(int flags, uchar_t *data, int len, char *xtra)
1274 {
1275 int length;
1276 int bytecount;
1277 int passwordlength;
1278 int isunicode;
1279 int upasswordlength;
1280 int wordcount;
1281 int cap;
1282 char tempstring[256];
1283 struct smb *smbdata;
1284 uchar_t *setupdata;
1285
1286 smbdata = (struct smb *)data;
1287 setupdata = (uchar_t *)data + sizeof (struct smb);
1288 wordcount = *setupdata++;
1289
1290 isunicode = smbdata->flags2[1] & 0x80;
1291
1292 if (flags & F_SUM && !(smbdata->flags & SERVER_RESPONSE)) {
1293 if (wordcount != 13)
1294 return;
1295 setupdata += 14;
1296 passwordlength = get2(setupdata);
1297 setupdata += 2;
1298 upasswordlength = get2(setupdata);
1299 setupdata += 6;
1300 cap = get4(setupdata);
1301 setupdata = setupdata + 6 + passwordlength + upasswordlength;
1302 if (isunicode) {
1303 setupdata += 1;
1304 (void) unicode2ascii(tempstring, 256, setupdata, 256);
1305 sprintf(xtra, "Username=%s ", tempstring);
1306 } else {
1307 length = snprintf(tempstring, sizeof (tempstring), "%s",
1308 (char *)setupdata);
1309 sprintf(xtra, "Username=%s ", tempstring);
1310 }
1311 }
1312
1313 if (flags & F_DTAIL && !(smbdata->flags & SERVER_RESPONSE)) {
1314 if (wordcount != 13)
1315 return;
1316 sprintf(GETLINE, "ChainedCommand = 0x%.2x",
1317 setupdata[0]);
1318 setupdata += 2;
1319 sprintf(GETLINE, "NextOffset = 0x%.4x",
1320 get2(setupdata));
1321 setupdata += 2;
1322 sprintf(GETLINE, "MaxBufferSize = 0x%.4x",
1323 get2(setupdata));
1324 setupdata += 2;
1325 sprintf(GETLINE, "MaxMPXRequests = %d",
1326 get2(setupdata));
1327 setupdata += 2;
1328 sprintf(GETLINE, "VCNumber = %d",
1329 get2(setupdata));
1330 setupdata += 2;
1331 sprintf(GETLINE, "SessionKey = %d",
1332 get4(setupdata));
1333 setupdata += 4;
1334 passwordlength = get2(setupdata);
1335 sprintf(GETLINE, "PasswordLength = 0x%.4x",
1336 passwordlength);
1337 setupdata += 2;
1338 upasswordlength = get2(setupdata);
1339 sprintf(GETLINE, "UnicodePasswordLength = 0x%.4x",
1340 upasswordlength);
1341 setupdata += 6;
1342 cap = get4(setupdata);
1343 sprintf(GETLINE, "Capabilities = 0x%0.8x", cap);
1344 setupdata += 4;
1345 bytecount = get2(setupdata);
1346 sprintf(GETLINE, "ByteCount = %d", bytecount);
1347 setupdata = setupdata + 2 + passwordlength + upasswordlength;
1348 if (isunicode) {
1349 setupdata++;
1350 length = 2*unicode2ascii(
1351 tempstring, 256, setupdata, 256);
1352 if (length == 2) {
1353 sprintf(GETLINE,
1354 "AccountName = %s", tempstring);
1355 sprintf(GETLINE,
1356 "DomainName = %s", tempstring);
1357 setupdata += 3;
1358 } else {
1359 setupdata += length;
1360 sprintf(GETLINE,
1361 "AccountName = %s", tempstring);
1362 length = 2*unicode2ascii(
1363 tempstring, 256, setupdata, 256);
1364 setupdata += length;
1365 sprintf(GETLINE,
1366 "DomainName = %s", tempstring);
1367 }
1368 length = 2*unicode2ascii(
1369 tempstring, 256, setupdata, 256);
1370 setupdata += (length+2);
1371 sprintf(GETLINE,
1372 "NativeOS = %s", tempstring);
1373 length = 2*unicode2ascii(
1374 tempstring, 256, setupdata, 256);
1375 sprintf(GETLINE,
1376 "NativeLanman = %s", tempstring);
1377 } else {
1378 length = snprintf(tempstring, sizeof (tempstring), "%s",
1379 (char *)setupdata);
1380 setupdata += (length+1);
1381 sprintf(GETLINE, "AccountName = %s", tempstring);
1382 length = snprintf(tempstring, sizeof (tempstring), "%s",
1383 (char *)setupdata);
1384 setupdata += (length+1);
1385 sprintf(GETLINE, "DomainName = %s", tempstring);
1386 length = snprintf(tempstring, sizeof (tempstring), "%s",
1387 (char *)setupdata);
1388 setupdata += (length+1);
1389 sprintf(GETLINE, "NativeOS = %s", tempstring);
1390 snprintf(tempstring, sizeof (tempstring), "%s",
1391 (char *)setupdata);
1392 sprintf(GETLINE, "NativeLanman = %s", tempstring);
1393 }
1394 }
1395
1396 if (flags & F_DTAIL && smbdata->flags & SERVER_RESPONSE) {
1397 if (wordcount != 3)
1398 return;
1399 sprintf(GETLINE, "ChainedCommand = 0x%.2x",
1400 setupdata[0]);
1401 setupdata += 2;
1402 sprintf(GETLINE, "NextOffset = 0x%.4x",
1403 get2(setupdata));
1404 setupdata += 2;
1405 sprintf(GETLINE, "SetupAction = 0x%.4x",
1406 get2(setupdata));
1407 setupdata += 2;
1408 bytecount = get2(setupdata);
1409 sprintf(GETLINE, "ByteCount = %d", bytecount);
1410 setupdata += 2;
1411 length = snprintf(tempstring, sizeof (tempstring), "%s",
1412 (char *)setupdata);
1413 setupdata += (length+1);
1414 sprintf(GETLINE, "NativeOS = %s", tempstring);
1415 length = snprintf(tempstring, sizeof (tempstring), "%s",
1416 (char *)setupdata);
1417 setupdata += (length+1);
1418 sprintf(GETLINE, "NativeLanman = %s", tempstring);
1419 length = snprintf(tempstring, sizeof (tempstring), "%s",
1420 (char *)setupdata);
1421 sprintf(GETLINE, "DomainName = %s", tempstring);
1422 }
1423 }
1424
1425 /*
1426 * Interpret "Trans2" SMB
1427 * [X/Open-SMB, Sec. 16]
1428 *
1429 * This is very much like "trans" above.
1430 */
1431 /* ARGSUSED */
1432 static void
interpret_trans2(int flags,uchar_t * data,int len,char * xtra)1433 interpret_trans2(int flags, uchar_t *data, int len, char *xtra)
1434 {
1435 struct smb *smb;
1436 uchar_t *vwv; /* word parameters */
1437 int wordcount;
1438 uchar_t *byteparms;
1439 int bytecount;
1440 int parambytes;
1441 int paramoffset;
1442 int setupcount;
1443 int subcode;
1444 uchar_t *setupdata;
1445 uchar_t *params;
1446 char *name;
1447
1448 smb = (struct smb *)data;
1449 vwv = (uchar_t *)data + sizeof (struct smb);
1450 wordcount = *vwv++;
1451
1452 byteparms = vwv + (2 * wordcount);
1453 bytecount = get2(byteparms);
1454 byteparms += 2;
1455
1456 /*
1457 * Print the lengths before we (potentially) bail out
1458 * due to lack of data (so the user knows why we did).
1459 */
1460 if (flags & F_DTAIL) {
1461 sprintf(GETLINE, "WordCount = %d", wordcount);
1462 sprintf(GETLINE, "ByteCount = %d", bytecount);
1463 }
1464
1465 /* Get length and location of params and setup data. */
1466 if (!(smb->flags & SERVER_RESPONSE)) {
1467 /* CALL */
1468 if (wordcount < 14)
1469 return;
1470 parambytes = get2(vwv + (2 * 9));
1471 paramoffset = get2(vwv + (2 * 10));
1472 setupcount = *(vwv + (2 * 13));
1473 setupdata = vwv + (2 * 14);
1474 } else {
1475 /* REPLY */
1476 if (wordcount < 10)
1477 return;
1478 parambytes = get2(vwv + (2 * 3));
1479 paramoffset = get2(vwv + (2 * 4));
1480 setupcount = *(vwv + (2 * 9));
1481 setupdata = vwv + (2 * 10);
1482 }
1483 if (setupcount > 0)
1484 subcode = get2(setupdata);
1485 else
1486 subcode = -1; /* invalid */
1487
1488 /* The parameters are offset from the SMB header. */
1489 params = data + paramoffset;
1490
1491 if (flags & F_DTAIL && !(smb->flags & SERVER_RESPONSE)) {
1492 /* This is a CALL. */
1493 /* print the word parameters */
1494 sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
1495 sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
1496 sprintf(GETLINE, "MaxParamBytes = %d", get2(vwv+4));
1497 sprintf(GETLINE, "MaxDataBytes = %d", get2(vwv+6));
1498 sprintf(GETLINE, "MaxSetupWords = %d", vwv[8]);
1499 sprintf(GETLINE, "TransFlags = 0x%.4x", get2(vwv+10));
1500 sprintf(GETLINE, "Timeout = 0x%.8x", get4(vwv+12));
1501 /* skip Reserved2 */
1502 sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
1503 sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
1504 sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+22));
1505 sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+24));
1506 sprintf(GETLINE, "SetupWords = %d", setupcount);
1507
1508 /* That finishes the VWV, now the misc. stuff. */
1509 sprintf(GETLINE, "FunctionCode = %d", subcode);
1510 }
1511
1512 if (!(smb->flags & SERVER_RESPONSE)) {
1513 /* This is a CALL. Do sub-function. */
1514 switch (subcode) {
1515 case TRANS2_OPEN:
1516 name = "Open";
1517 goto name_only;
1518 case TRANS2_FIND_FIRST:
1519 output_trans2_findfirst(flags, params, xtra);
1520 break;
1521 case TRANS2_FIND_NEXT2:
1522 output_trans2_findnext(flags, params, xtra);
1523 break;
1524 case TRANS2_QUERY_FS_INFORMATION:
1525 name = "QueryFSInfo";
1526 goto name_only;
1527 case TRANS2_QUERY_PATH_INFORMATION:
1528 output_trans2_querypath(flags, params, xtra);
1529 break;
1530 case TRANS2_SET_PATH_INFORMATION:
1531 name = "SetPathInfo";
1532 goto name_only;
1533 case TRANS2_QUERY_FILE_INFORMATION:
1534 output_trans2_queryfile(flags, params, xtra);
1535 break;
1536 case TRANS2_SET_FILE_INFORMATION:
1537 output_trans2_setfile(flags, params, xtra);
1538 break;
1539 case TRANS2_CREATE_DIRECTORY:
1540 name = "CreateDir";
1541 goto name_only;
1542
1543 default:
1544 name = "Unknown";
1545 /* fall through */
1546 name_only:
1547 if (flags & F_SUM)
1548 sprintf(xtra, "%s ", name);
1549 if (flags & F_DTAIL)
1550 sprintf(GETLINE, "FunctionName = %s", name);
1551 break;
1552 }
1553 }
1554
1555 if (flags & F_DTAIL && smb->flags & SERVER_RESPONSE) {
1556 /* This is a REPLY. */
1557 /* print the word parameters */
1558 sprintf(GETLINE, "TotalParamBytes = %d", get2(vwv));
1559 sprintf(GETLINE, "TotalDataBytes = %d", get2(vwv+2));
1560 /* skip Reserved */
1561 sprintf(GETLINE, "ParamBytes = 0x%.4x", parambytes);
1562 sprintf(GETLINE, "ParamOffset = 0x%.4x", paramoffset);
1563 sprintf(GETLINE, "ParamDispl. = 0x%.4x", get2(vwv+10));
1564 sprintf(GETLINE, "DataBytes = 0x%.4x", get2(vwv+12));
1565 sprintf(GETLINE, "DataOffset = 0x%.4x", get2(vwv+14));
1566 sprintf(GETLINE, "DataDispl. = 0x%.4x", get2(vwv+16));
1567 sprintf(GETLINE, "SetupWords = %d", setupcount);
1568
1569 output_bytes(byteparms, bytecount);
1570 }
1571 }
1572
1573
1574 static void
interpret_default(int flags,uchar_t * data,int len,char * xtra)1575 interpret_default(int flags, uchar_t *data, int len, char *xtra)
1576 {
1577 int slength;
1578 int i;
1579 int printit;
1580 int wordcount;
1581 char *outstr;
1582 char *prfmt;
1583 char *format;
1584 char valuetype;
1585 char word[10];
1586 char *label;
1587 char tempstring[256];
1588 uchar_t *comdata, *limit;
1589 char buff[80];
1590 struct smb *smbdata;
1591 struct decode *decoder;
1592
1593 smbdata = (struct smb *)data;
1594 comdata = (uchar_t *)data + sizeof (struct smb);
1595 wordcount = *comdata++;
1596 limit = data + len;
1597
1598 decoder = &SMBtable[smbdata->com & 255];
1599
1600 if (smbdata->flags & SERVER_RESPONSE)
1601 format = decoder->replyfmt;
1602 else
1603 format = decoder->callfmt;
1604
1605 if (!format || strlen(format) == 0) {
1606 if (wordcount == 0 || flags & F_SUM)
1607 return;
1608 sprintf(GETLINE, "WordCount = %d", wordcount);
1609 sprintf(GETLINE, "Word values (in hex):");
1610 for (i = 0; i < wordcount; i++) {
1611 sprintf(word, "%.4x ", get2(comdata));
1612 comdata += 2;
1613 if (comdata >= limit)
1614 wordcount = i+1; /* terminate */
1615 strcat(buff, word);
1616 if (((i+1) & 7) == 0 || i == (wordcount-1)) {
1617 sprintf(GETLINE, "%s", buff);
1618 strcpy(buff, "");
1619 }
1620 }
1621 return;
1622 }
1623
1624
1625 valuetype = format[0];
1626 while (valuetype != '\0') {
1627 if (comdata >= limit)
1628 break;
1629 if ((flags & F_DTAIL) && valuetype != 'r' && valuetype != 'R')
1630 outstr = GETLINE;
1631 else
1632 outstr = xtra + strlen(xtra);
1633 label = format+1;
1634 printit = (flags & F_DTAIL) || (valuetype <= 'Z');
1635
1636 switch (valuetype) {
1637 case 'W':
1638 case 'w':
1639 prfmt = (flags & F_DTAIL) ? "%s = 0x%.4x" : "%s=0x%x ";
1640 if (printit)
1641 sprintf(outstr, prfmt, label, get2(comdata));
1642 comdata += 2;
1643 break;
1644 case 'D':
1645 case 'd':
1646 prfmt = (flags & F_DTAIL) ? "%s = %d" : "%s=%d ";
1647 if (printit)
1648 sprintf(outstr, prfmt, label, get2(comdata));
1649 comdata += 2;
1650 break;
1651 case 'L':
1652 case 'l':
1653 prfmt = (flags & F_DTAIL) ? "%s = 0x%.8x" : "%s=0x%x ";
1654 if (printit)
1655 sprintf(outstr, prfmt, label, get4(comdata));
1656 comdata += 4;
1657 break;
1658 case 'B':
1659 case 'b':
1660 prfmt = (flags & F_DTAIL) ? "%s = 0x%.2x" : "%s=0x%x ";
1661 if (printit)
1662 sprintf(outstr, prfmt, label, comdata[0]);
1663 comdata += 1;
1664 break;
1665 case 'r':
1666 comdata++;
1667 break;
1668 case 'R':
1669 comdata += 2;
1670 break;
1671 case 'U':
1672 case 'u':
1673 prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
1674 slength = unicode2ascii(tempstring, 256, comdata, 256);
1675 if (printit)
1676 sprintf(outstr, prfmt, label, tempstring);
1677 comdata += (slength*2 + 1);
1678 break;
1679 case 'S':
1680 case 's':
1681 prfmt = (flags & F_DTAIL) ? "%s = %s" : "%s=%s ";
1682 slength = snprintf(tempstring, sizeof (tempstring),
1683 "%s", (char *)comdata);
1684 if (printit)
1685 sprintf(outstr, prfmt, label, tempstring);
1686 comdata += (slength+1);
1687 break;
1688 }
1689 format += (strlen(format) + 1);
1690 valuetype = format[0];
1691 }
1692 }
1693