]> The Tcpdump Group git mirrors - tcpdump/blob - print-smb.c
indent (sorry, i left them behind
[tcpdump] / print-smb.c
1 /*
2 * Copyright (C) Andrew Tridgell 1995-1999
3 *
4 * This software may be distributed either under the terms of the
5 * BSD-style license that accompanies tcpdump or the GNU GPL version 2
6 * or later
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #ifndef lint
14 static const char rcsid[] =
15 "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.16 2001-06-28 03:15:38 itojun Exp $";
16 #endif
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <sys/types.h>
21
22 #include "interface.h"
23 #include "smb.h"
24
25 static int request = 0;
26
27 const uchar *startbuf = NULL;
28
29 struct smbdescript {
30 char *req_f1;
31 char *req_f2;
32 char *rep_f1;
33 char *rep_f2;
34 /*
35 * sometimes (u_char *, u_char *, u_char *, u_char *) and
36 * sometimes (u_char *, u_char *, int, int)
37 */
38 void (*fn)(const u_char *, const u_char *, ...);
39 };
40
41 struct smbfns
42 {
43 int id;
44 char *name;
45 int flags;
46 struct smbdescript descript;
47 };
48
49 #define DEFDESCRIPT { NULL, NULL, NULL, NULL, NULL }
50
51 #define FLG_CHAIN (1 << 0)
52
53 static struct smbfns *
54 smbfind(int id, struct smbfns *list)
55 {
56 int sindex;
57
58 for (sindex = 0; list[sindex].name; sindex++)
59 if (list[sindex].id == id)
60 return(&list[sindex]);
61
62 return(&list[0]);
63 }
64
65 static void
66 trans2_findfirst(const uchar *param, const uchar *data, ...)
67 {
68 char *fmt;
69 va_list ap;
70 int pcnt, dcnt;
71
72 va_start(ap, data);
73 pcnt = va_arg(ap, int);
74 dcnt = va_arg(ap, int);
75 va_end(ap);
76
77 if (request)
78 fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP5]\nFile=[S]\n";
79 else
80 fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n";
81
82 fdata(param, fmt, param + pcnt);
83 if (dcnt) {
84 printf("data:\n");
85 print_data(data, dcnt);
86 }
87 }
88
89 static void
90 trans2_qfsinfo(const uchar *param, const uchar *data, ...)
91 {
92 static int level = 0;
93 char *fmt="";
94 va_list ap;
95 int pcnt, dcnt;
96
97 va_start(ap, data);
98 pcnt = va_arg(ap, int);
99 dcnt = va_arg(ap, int);
100 va_end(ap);
101
102 if (request) {
103 level = SVAL(param, 0);
104 fmt = "InfoLevel=[d]\n";
105 fdata(param, fmt, param + pcnt);
106 } else {
107 switch (level) {
108 case 1:
109 fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n";
110 break;
111 case 2:
112 fmt = "CreationTime=[T2]VolNameLength=[B]\nVolumeLabel=[s12]\n";
113 break;
114 case 0x105:
115 fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[D]\nVolume=[S]\n";
116 break;
117 default:
118 fmt = "UnknownLevel\n";
119 break;
120 }
121 fdata(data, fmt, data + dcnt);
122 }
123 if (dcnt) {
124 printf("data:\n");
125 print_data(data, dcnt);
126 }
127 }
128
129 struct smbfns trans2_fns[] = {
130 { 0, "TRANSACT2_OPEN", 0,
131 { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]",
132 NULL,
133 "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n",
134 NULL, NULL }},
135 { 1, "TRANSACT2_FINDFIRST", 0,
136 { NULL, NULL, NULL, NULL, trans2_findfirst }},
137 { 2, "TRANSACT2_FINDNEXT", 0, DEFDESCRIPT },
138 { 3, "TRANSACT2_QFSINFO", 0,
139 { NULL, NULL, NULL, NULL, trans2_qfsinfo }},
140 { 4, "TRANSACT2_SETFSINFO", 0, DEFDESCRIPT },
141 { 5, "TRANSACT2_QPATHINFO", 0, DEFDESCRIPT },
142 { 6, "TRANSACT2_SETPATHINFO", 0, DEFDESCRIPT },
143 { 7, "TRANSACT2_QFILEINFO", 0, DEFDESCRIPT },
144 { 8, "TRANSACT2_SETFILEINFO", 0, DEFDESCRIPT },
145 { 9, "TRANSACT2_FSCTL", 0, DEFDESCRIPT },
146 { 10, "TRANSACT2_IOCTL", 0, DEFDESCRIPT },
147 { 11, "TRANSACT2_FINDNOTIFYFIRST", 0, DEFDESCRIPT },
148 { 12, "TRANSACT2_FINDNOTIFYNEXT", 0, DEFDESCRIPT },
149 { 13, "TRANSACT2_MKDIR", 0, DEFDESCRIPT },
150 { -1, NULL, 0, DEFDESCRIPT }
151 };
152
153
154 static void
155 print_trans2(const uchar *words, const uchar *dat, ...)
156 {
157 static struct smbfns *fn = &trans2_fns[0];
158 uchar *data, *param;
159 uchar *f1 = NULL, *f2 = NULL;
160 int pcnt, dcnt;
161 va_list ap;
162 uchar *buf, *maxbuf;
163
164 va_start(ap, dat);
165 buf = va_arg(ap, uchar *);
166 maxbuf = va_arg(ap, uchar *);
167 va_end(ap);
168
169 if (request) {
170 fn = smbfind(SVAL(words + 1, 14 * 2), trans2_fns);
171 data = buf+SVAL(words + 1, 12 * 2);
172 param = buf+SVAL(words + 1, 10 * 2);
173 pcnt = SVAL(words + 1, 9 * 2);
174 dcnt = SVAL(words + 1, 11 * 2);
175 } else {
176 data = buf+SVAL(words + 1, 7 * 2);
177 param = buf+SVAL(words + 1, 4 * 2);
178 pcnt = SVAL(words + 1, 3 * 2);
179 dcnt = SVAL(words + 1, 6 * 2);
180 }
181
182 printf("%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt);
183
184 if (request) {
185 if (CVAL(words, 0) == 8) {
186 fdata(words + 1,
187 "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",
188 maxbuf);
189 return;
190 } else {
191 fdata(words + 1,
192 "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[d]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[d]\n",
193 words + 1 + 14 * 2);
194 fdata(data + 1, "TransactionName=[S]\n%", maxbuf);
195 }
196 f1 = fn->descript.req_f1;
197 f2 = fn->descript.req_f2;
198 } else {
199 if (CVAL(words, 0) == 0) {
200 printf("Trans2Interim\n");
201 return;
202 } else {
203 fdata(words + 1,
204 "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[d]\n",
205 words + 1 + 10 * 2);
206 }
207 f1 = fn->descript.rep_f1;
208 f2 = fn->descript.rep_f2;
209 }
210
211 if (fn->descript.fn)
212 fn->descript.fn(param, data, pcnt, dcnt);
213 else {
214 fdata(param, f1 ? f1 : (uchar *)"Paramaters=\n", param + pcnt);
215 fdata(data, f2 ? f2 : (uchar *)"Data=\n", data + dcnt);
216 }
217 }
218
219
220 static void
221 print_browse(uchar *param, int paramlen, const uchar *data, int datalen)
222 {
223 const uchar *maxbuf = data + datalen;
224 int command = CVAL(data, 0);
225
226 fdata(param, "BROWSE PACKET\n|Param ", param+paramlen);
227
228 switch (command) {
229 case 0xF:
230 data = fdata(data,
231 "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
232 maxbuf);
233 break;
234
235 case 0x1:
236 data = fdata(data,
237 "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
238 maxbuf);
239 break;
240
241 case 0x2:
242 data = fdata(data,
243 "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n",
244 maxbuf);
245 break;
246
247 case 0xc:
248 data = fdata(data,
249 "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n",
250 maxbuf);
251 break;
252
253 case 0x8:
254 data = fdata(data,
255 "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n",
256 maxbuf);
257 break;
258
259 case 0xb:
260 data = fdata(data,
261 "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n",
262 maxbuf);
263 break;
264
265 case 0x9:
266 data = fdata(data,
267 "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken?=[B]\n",
268 maxbuf);
269 break;
270
271 case 0xa:
272 data = fdata(data,
273 "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken?=[B]*Name=[S]\n",
274 maxbuf);
275 break;
276
277 case 0xd:
278 data = fdata(data,
279 "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n",
280 maxbuf);
281 break;
282
283 case 0xe:
284 data = fdata(data,
285 "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf);
286 break;
287
288 default:
289 data = fdata(data, "Unknown Browser Frame ", maxbuf);
290 break;
291 }
292 }
293
294
295 static void
296 print_ipc(uchar *param, int paramlen, uchar *data, int datalen)
297 {
298 if (paramlen)
299 fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen);
300 if (datalen)
301 fdata(data, "IPC ", data + datalen);
302 }
303
304
305 static void
306 print_trans(const uchar *words, const uchar *data1, ...)
307 {
308 uchar *f1, *f2, *f3, *f4;
309 uchar *data, *param;
310 int datalen, paramlen;
311 va_list ap;
312 uchar *buf, *maxbuf;
313
314 va_start(ap, data1);
315 buf = va_arg(ap, uchar *);
316 maxbuf = va_arg(ap, uchar *);
317 va_end(ap);
318
319 if (request) {
320 paramlen = SVAL(words + 1, 9 * 2);
321 param = buf + SVAL(words + 1, 10 * 2);
322 datalen = SVAL(words + 1, 11 * 2);
323 data = buf + SVAL(words + 1, 12 * 2);
324 f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n";
325 f2 = "|Name=[S]\n";
326 f3 = "|Param ";
327 f4 = "|Data ";
328 } else {
329 paramlen = SVAL(words + 1, 3 * 2);
330 param = buf + SVAL(words + 1, 4 * 2);
331 datalen = SVAL(words + 1, 6 * 2);
332 data = buf + SVAL(words + 1, 7 * 2);
333 f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n";
334 f2 = "|Unknown ";
335 f3 = "|Param ";
336 f4 = "|Data ";
337 }
338
339 fdata(words + 1, f1, MIN(words + 1 + 2 * CVAL(words, 0), maxbuf));
340 fdata(data1 + 2, f2, maxbuf - (paramlen + datalen));
341
342 if (!strcmp(data1 + 2, "\\MAILSLOT\\BROWSE")) {
343 print_browse(param, paramlen, data, datalen);
344 return;
345 }
346
347 if (!strcmp(data1 + 2, "\\PIPE\\LANMAN")) {
348 print_ipc(param, paramlen, data, datalen);
349 return;
350 }
351
352 if (paramlen)
353 fdata(param, f3, MIN(param + paramlen, maxbuf));
354 if (datalen)
355 fdata(data, f4, MIN(data + datalen, maxbuf));
356 }
357
358
359 static void
360 print_negprot(const uchar *words, const uchar *data, ...)
361 {
362 uchar *f1 = NULL, *f2 = NULL;
363 va_list ap;
364 uchar *buf, *maxbuf;
365
366 va_start(ap, data);
367 buf = va_arg(ap, uchar *);
368 maxbuf = va_arg(ap, uchar *);
369 va_end(ap);
370
371 if (request)
372 f2 = "*|Dialect=[Z]\n";
373 else {
374 if (CVAL(words, 0) == 1)
375 f1 = "Core Protocol\nDialectIndex=[d]";
376 else if (CVAL(words, 0) == 17)
377 f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey=";
378 else if (CVAL(words, 0) == 13)
379 f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey=";
380 }
381
382 if (f1)
383 fdata(words + 1, f1, MIN(words + 1 + CVAL(words, 0) * 2, maxbuf));
384 else
385 print_data(words + 1, MIN(CVAL(words, 0) * 2,
386 PTR_DIFF(maxbuf, words + 1)));
387
388 if (f2)
389 fdata(data + 2, f2, MIN(data + 2 + SVAL(data, 0), maxbuf));
390 else
391 print_data(data + 2, MIN(SVAL(data, 0), PTR_DIFF(maxbuf, data + 2)));
392 }
393
394 static void
395 print_sesssetup(const uchar *words, const uchar *data, ...)
396 {
397 int wcnt = CVAL(words, 0);
398 uchar *f1 = NULL, *f2 = NULL;
399 va_list ap;
400 uchar *buf, *maxbuf;
401
402 va_start(ap, data);
403 buf = va_arg(ap, uchar *);
404 maxbuf = va_arg(ap, uchar *);
405 va_end(ap);
406
407 if (request) {
408 if (wcnt == 10)
409 f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n";
410 else
411 f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n";
412 } else {
413 if (CVAL(words,0) == 3) {
414 f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n";
415 } else if (CVAL(words,0) == 13) {
416 f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n";
417 f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n";
418 }
419 }
420
421 if (f1)
422 fdata(words + 1, f1, MIN(words + 1 + CVAL(words, 0) * 2, maxbuf));
423 else
424 print_data(words + 1, MIN(CVAL(words, 0) * 2,
425 PTR_DIFF(maxbuf, words + 1)));
426
427 if (f2)
428 fdata(data + 2, f2, MIN(data + 2 + SVAL(data, 0), maxbuf));
429 else
430 print_data(data + 2, MIN(SVAL(data, 0), PTR_DIFF(maxbuf, data+2)));
431 }
432
433
434 static struct smbfns smb_fns[] = {
435 { -1, "SMBunknown", 0, DEFDESCRIPT },
436
437 { SMBtcon, "SMBtcon", 0,
438 { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n",
439 "MaxXmit=[d]\nTreeId=[d]\n", NULL,
440 NULL } },
441
442 { SMBtdis, "SMBtdis", 0, DEFDESCRIPT },
443 { SMBexit, "SMBexit", 0, DEFDESCRIPT },
444 { SMBioctl, "SMBioctl", 0, DEFDESCRIPT },
445
446 { SMBecho, "SMBecho", 0,
447 { "ReverbCount=[d]\n", NULL,
448 "SequenceNum=[d]\n", NULL,
449 NULL } },
450
451 { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT },
452
453 { SMBgetatr, "SMBgetatr", 0,
454 { NULL, "Path=[Z]\n",
455 "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL,
456 NULL } },
457
458 { SMBsetatr, "SMBsetatr", 0,
459 { "Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n", "Path=[Z]\n",
460 NULL, NULL, NULL } },
461
462 { SMBchkpth, "SMBchkpth", 0,
463 { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
464
465 { SMBsearch, "SMBsearch", 0,
466 { "Count=[d]\nAttrib=[A]\n",
467 "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n",
468 "Count=[d]\n",
469 "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
470 NULL } },
471
472 { SMBopen, "SMBopen", 0,
473 { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n",
474 "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n",
475 NULL, NULL } },
476
477 { SMBcreate, "SMBcreate", 0,
478 { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
479
480 { SMBmknew, "SMBmknew", 0,
481 { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
482
483 { SMBunlink, "SMBunlink", 0,
484 { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } },
485
486 { SMBread, "SMBread", 0,
487 { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
488 "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
489
490 { SMBwrite, "SMBwrite", 0,
491 { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
492 "Count=[d]\n", NULL, NULL } },
493
494 { SMBclose, "SMBclose", 0,
495 { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } },
496
497 { SMBmkdir, "SMBmkdir", 0,
498 { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
499
500 { SMBrmdir, "SMBrmdir", 0,
501 { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
502
503 { SMBdskattr, "SMBdskattr", 0,
504 { NULL, NULL,
505 "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n",
506 NULL, NULL } },
507
508 { SMBmv, "SMBmv", 0,
509 { "Attrib=[A]\n", "OldPath=[Z]\nNewPath=[Z]\n", NULL, NULL, NULL } },
510
511 /*
512 * this is a Pathworks specific call, allowing the
513 * changing of the root path
514 */
515 { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
516
517 { SMBlseek, "SMBlseek", 0,
518 { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL } },
519
520 { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
521
522 { SMBsplopen, "SMBsplopen", 0,
523 { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n",
524 NULL, NULL } },
525
526 { SMBsplclose, "SMBsplclose", 0,
527 { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
528
529 { SMBsplretq, "SMBsplretq", 0,
530 { "MaxCount=[d]\nStartIndex=[d]\n", NULL,
531 "Count=[d]\nIndex=[d]\n",
532 "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n",
533 NULL } },
534
535 { SMBsplwr, "SMBsplwr", 0,
536 { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
537
538 { SMBlock, "SMBlock", 0,
539 { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
540
541 { SMBunlock, "SMBunlock", 0,
542 { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
543
544 /* CORE+ PROTOCOL FOLLOWS */
545
546 { SMBreadbraw, "SMBreadbraw", 0,
547 { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n",
548 NULL, NULL, NULL, NULL } },
549
550 { SMBwritebraw, "SMBwritebraw", 0,
551 { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n",
552 NULL, "WriteRawAck", NULL, NULL } },
553
554 { SMBwritec, "SMBwritec", 0,
555 { NULL, NULL, "Count=[d]\n", NULL, NULL } },
556
557 { SMBwriteclose, "SMBwriteclose", 0,
558 { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])",
559 NULL, "Count=[d]\n", NULL, NULL } },
560
561 { SMBlockread, "SMBlockread", 0,
562 { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
563 "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
564
565 { SMBwriteunlock, "SMBwriteunlock", 0,
566 { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
567 "Count=[d]\n", NULL, NULL } },
568
569 { SMBreadBmpx, "SMBreadBmpx", 0,
570 { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n",
571 NULL,
572 "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n",
573 NULL, NULL } },
574
575 { SMBwriteBmpx, "SMBwriteBmpx", 0,
576 { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL,
577 "Remaining=[d]\n", NULL, NULL } },
578
579 { SMBwriteBs, "SMBwriteBs", 0,
580 { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n",
581 NULL, "Count=[d]\n", NULL, NULL } },
582
583 { SMBsetattrE, "SMBsetattrE", 0,
584 { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL,
585 NULL, NULL, NULL } },
586
587 { SMBgetattrE, "SMBgetattrE", 0,
588 { "Handle=[d]\n", NULL,
589 "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n",
590 NULL, NULL } },
591
592 { SMBtranss, "SMBtranss", 0, DEFDESCRIPT },
593 { SMBioctls, "SMBioctls", 0, DEFDESCRIPT },
594
595 { SMBcopy, "SMBcopy", 0,
596 { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
597 "CopyCount=[d]\n", "|ErrStr=[S]\n", NULL } },
598
599 { SMBmove, "SMBmove", 0,
600 { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
601 "MoveCount=[d]\n", "|ErrStr=[S]\n", NULL } },
602
603 { SMBopenX, "SMBopenX", FLG_CHAIN,
604 { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n",
605 "Path=[S]\n",
606 "Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n",
607 NULL, NULL } },
608
609 { SMBreadX, "SMBreadX", FLG_CHAIN,
610 { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n",
611 NULL,
612 "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n",
613 NULL, NULL } },
614
615 { SMBwriteX, "SMBwriteX", FLG_CHAIN,
616 { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n",
617 NULL,
618 "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n",
619 NULL, NULL } },
620
621 { SMBlockingX, "SMBlockingX", FLG_CHAIN,
622 { "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n",
623 "*Process=[d]\nOffset=[D]\nLength=[D]\n",
624 "Com2=[w]\nOff2=[d]\n", NULL, NULL } },
625
626 { SMBffirst, "SMBffirst", 0,
627 { "Count=[d]\nAttrib=[A]\n",
628 "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
629 "Count=[d]\n",
630 "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
631 NULL } },
632
633 { SMBfunique, "SMBfunique", 0,
634 { "Count=[d]\nAttrib=[A]\n",
635 "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
636 "Count=[d]\n",
637 "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
638 NULL } },
639
640 { SMBfclose, "SMBfclose", 0,
641 { "Count=[d]\nAttrib=[A]\n",
642 "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
643 "Count=[d]\n",
644 "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
645 NULL } },
646
647 { SMBfindnclose, "SMBfindnclose", 0,
648 { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
649
650 { SMBfindclose, "SMBfindclose", 0,
651 { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
652
653 { SMBsends, "SMBsends", 0,
654 { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
655
656 { SMBsendstrt, "SMBsendstrt", 0,
657 { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } },
658
659 { SMBsendend, "SMBsendend", 0,
660 { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
661
662 { SMBsendtxt, "SMBsendtxt", 0,
663 { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
664
665 { SMBsendb, "SMBsendb", 0,
666 { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
667
668 { SMBfwdname, "SMBfwdname", 0, DEFDESCRIPT },
669 { SMBcancelf, "SMBcancelf", 0, DEFDESCRIPT },
670 { SMBgetmac, "SMBgetmac", 0, DEFDESCRIPT },
671
672 { SMBnegprot, "SMBnegprot", 0,
673 { NULL, NULL, NULL, NULL, print_negprot } },
674
675 { SMBsesssetupX, "SMBsesssetupX", FLG_CHAIN,
676 { NULL, NULL, NULL, NULL, print_sesssetup } },
677
678 { SMBtconX, "SMBtconX", FLG_CHAIN,
679 { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n",
680 NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[S]\n", NULL } },
681
682 { SMBtrans2, "SMBtrans2", 0, { NULL, NULL, NULL, NULL, print_trans2 } },
683
684 { SMBtranss2, "SMBtranss2", 0, DEFDESCRIPT },
685 { SMBctemp, "SMBctemp", 0, DEFDESCRIPT },
686 { SMBreadBs, "SMBreadBs", 0, DEFDESCRIPT },
687 { SMBtrans, "SMBtrans", 0, { NULL, NULL, NULL, NULL, print_trans } },
688
689 { SMBnttrans, "SMBnttrans", 0, DEFDESCRIPT },
690 { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT },
691
692 { SMBntcreateX, "SMBntcreateX", FLG_CHAIN,
693 { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[d]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n",
694 "Path=[S]\n",
695 "Com2=[w]\nOff2=[d]\nOplockLevel=[b]\nFid=[d]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n",
696 NULL } },
697
698 { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT },
699
700 { -1, NULL, 0, DEFDESCRIPT }
701 };
702
703
704 /*
705 * print a SMB message
706 */
707 static void
708 print_smb(const uchar *buf, const uchar *maxbuf)
709 {
710 int command;
711 const uchar *words, *data;
712 struct smbfns *fn;
713 char *fmt_smbheader =
714 "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [d]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [d]\nProc ID = [d]\nUID = [d]\nMID = [d]\nWord Count = [b]\n";
715
716 request = (CVAL(buf, 9) & 0x80) ? 0 : 1;
717
718 command = CVAL(buf, 4);
719
720 fn = smbfind(command, smb_fns);
721
722 if (vflag > 1)
723 printf("\n");
724
725 printf("SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY");
726
727 if (vflag < 2)
728 return;
729
730 /* print out the header */
731 fdata(buf, fmt_smbheader, buf + 33);
732
733 if (CVAL(buf, 5)) {
734 int class = CVAL(buf, 5);
735 int num = SVAL(buf, 7);
736 printf("SMBError = %s\n", smb_errstr(class, num));
737 }
738
739 words = buf + 32;
740 data = words + 1 + CVAL(words,0)*2;
741
742 while (words && data) {
743 char *f1, *f2;
744 int wct = CVAL(words, 0);
745
746 if (request) {
747 f1 = fn->descript.req_f1;
748 f2 = fn->descript.req_f2;
749 } else {
750 f1 = fn->descript.rep_f1;
751 f2 = fn->descript.rep_f2;
752 }
753
754 if (fn->descript.fn)
755 fn->descript.fn(words, data, buf, maxbuf);
756 else {
757 if (f1) {
758 printf("smbvwv[]=\n");
759 fdata(words + 1, f1, words + 1 + wct * 2);
760 } else if (wct) {
761 int i;
762 int v;
763 printf("smbvwv[]=\n");
764 for (i = 0; i < wct; i++) {
765 v = SVAL(words + 1, 2 * i);
766 printf("smb_vwv[%d]=%d (0x%X)\n", i, v, v);
767 }
768 }
769
770 if (f2) {
771 printf("smbbuf[]=\n");
772 fdata(data + 2, f2, maxbuf);
773 } else {
774 int bcc = SVAL(data, 0);
775 printf("smb_bcc=%d\n", bcc);
776 if (bcc > 0) {
777 printf("smb_buf[]=\n");
778 print_data(data + 2, MIN(bcc, PTR_DIFF(maxbuf, data + 2)));
779 }
780 }
781 }
782
783 if ((fn->flags & FLG_CHAIN) != 0&& CVAL(words, 0) &&
784 SVAL(words, 1) != 0xFF) {
785 command = SVAL(words, 1);
786 words = buf + SVAL(words, 3);
787 data = words + 1 + CVAL(words, 0) * 2;
788
789 fn = smbfind(command, smb_fns);
790
791 printf("\nSMB PACKET: %s (%s) (CHAINED)\n",
792 fn->name, request ? "REQUEST" : "REPLY");
793 } else
794 words = data = NULL;
795 }
796
797 printf("\n");
798 }
799
800
801 /*
802 * print a NBT packet received across tcp on port 139
803 */
804 void
805 nbt_tcp_print(const uchar *data, int length)
806 {
807 const uchar *maxbuf = data + length;
808 int flags = CVAL(data, 0);
809 int nbt_len = RSVAL(data, 2);
810
811 startbuf = data;
812 if (maxbuf <= data)
813 return;
814
815 if (vflag > 1)
816 printf ("\n>>> ");
817
818 printf("NBT Packet");
819
820 if (vflag < 2)
821 return;
822
823 printf("\n");
824
825 switch (flags) {
826 case 1:
827 printf("flags=0x%x\n", flags);
828 case 0:
829 data = fdata(data, "NBT Session Packet\nFlags=[rw]\nLength=[rd]\n",
830 data + 4);
831 if (data == NULL)
832 break;
833 if (memcmp(data,"\377SMB",4) == 0) {
834 if (nbt_len > PTR_DIFF(maxbuf, data))
835 printf("WARNING: Short packet. Try increasing the snap length (%lu)\n",
836 (unsigned long)PTR_DIFF(maxbuf, data));
837 print_smb(data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf);
838 } else
839 printf("Session packet:(raw data?)\n");
840 break;
841
842 case 0x81:
843 data = fdata(data,
844 "NBT Session Request\nFlags=[rW]\nDestination=[n1]\nSource=[n1]\n",
845 maxbuf);
846 break;
847
848 case 0x82:
849 data = fdata(data, "NBT Session Granted\nFlags=[rW]\n", maxbuf);
850 break;
851
852 case 0x83:
853 {
854 int ecode = CVAL(data,4);
855
856 data = fdata(data, "NBT SessionReject\nFlags=[rW]\nReason=[B]\n",
857 maxbuf);
858 switch (ecode) {
859 case 0x80:
860 printf("Not listening on called name\n");
861 break;
862 case 0x81:
863 printf("Not listening for calling name\n");
864 break;
865 case 0x82:
866 printf("Called name not present\n");
867 break;
868 case 0x83:
869 printf("Called name present, but insufficient resources\n");
870 break;
871 default:
872 printf("Unspecified error 0x%X\n", ecode);
873 break;
874 }
875 }
876 break;
877
878 case 0x85:
879 data = fdata(data, "NBT Session Keepalive\nFlags=[rW]\n", maxbuf);
880 break;
881
882 default:
883 printf("flags=0x%x\n", flags);
884 data = fdata(data, "NBT - Unknown packet type\nType=[rW]\n", maxbuf);
885 }
886 printf("\n");
887 fflush(stdout);
888 }
889
890
891 /*
892 * print a NBT packet received across udp on port 137
893 */
894 void
895 nbt_udp137_print(const uchar *data, int length)
896 {
897 const uchar *maxbuf = data + length;
898 int name_trn_id = RSVAL(data, 0);
899 int response = (CVAL(data, 2) >> 7);
900 int opcode = (CVAL(data, 2) >> 3) & 0xF;
901 int nm_flags = ((CVAL(data, 2) & 0x7) << 4) + (CVAL(data, 3) >> 4);
902 int rcode = CVAL(data, 3) & 0xF;
903 int qdcount = RSVAL(data, 4);
904 int ancount = RSVAL(data, 6);
905 int nscount = RSVAL(data, 8);
906 int arcount = RSVAL(data, 10);
907 char *opcodestr;
908 const char *p;
909 int total, i;
910
911 startbuf = data;
912
913 if (maxbuf <= data)
914 return;
915
916 if (vflag > 1)
917 printf("\n>>> ");
918
919 printf("NBT UDP PACKET(137): ");
920
921 switch (opcode) {
922 case 0: opcodestr = "QUERY"; break;
923 case 5: opcodestr = "REGISTRATION"; break;
924 case 6: opcodestr = "RELEASE"; break;
925 case 7: opcodestr = "WACK"; break;
926 case 8: opcodestr = "REFRESH(8)"; break;
927 case 9: opcodestr = "REFRESH"; break;
928 default: opcodestr = "OPUNKNOWN"; break;
929 }
930 printf("%s", opcodestr);
931 if (response) {
932 if (rcode)
933 printf("; NEGATIVE");
934 else
935 printf("; POSITIVE");
936 }
937
938 if (response)
939 printf("; RESPONSE");
940 else
941 printf("; REQUEST");
942
943 if (nm_flags & 1)
944 printf("; BROADCAST");
945 else
946 printf("; UNICAST");
947
948 if (vflag < 2)
949 return;
950
951 printf("\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n",
952 name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount,
953 arcount);
954
955 p = data + 12;
956
957 total = ancount + nscount + arcount;
958
959 if (qdcount > 100 || total > 100) {
960 printf("Corrupt packet??\n");
961 return;
962 }
963
964 if (qdcount) {
965 printf("QuestionRecords:\n");
966 for (i = 0; i < qdcount; i++)
967 p = fdata(p,
968 "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#",
969 maxbuf);
970 if (p == NULL)
971 goto out;
972 }
973
974 if (total) {
975 printf("\nResourceRecords:\n");
976 for (i = 0; i < total; i++) {
977 int rdlen;
978 int restype;
979
980 p = fdata(p, "Name=[n1]\n#", maxbuf);
981 if (p == NULL)
982 goto out;
983 restype = RSVAL(p, 0);
984 p = fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8);
985 if (p == NULL)
986 goto out;
987 rdlen = RSVAL(p, 0);
988 printf("ResourceLength=%d\nResourceData=\n", rdlen);
989 p += 2;
990 if (rdlen == 6) {
991 p = fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen);
992 if (p == NULL)
993 goto out;
994 } else {
995 if (restype == 0x21) {
996 int numnames = CVAL(p, 0);
997 p = fdata(p, "NumNames=[B]\n", p + 1);
998 if (p == NULL)
999 goto out;
1000 while (numnames--) {
1001 p = fdata(p, "Name=[n2]\t#", maxbuf);
1002 if (p[0] & 0x80)
1003 printf("<GROUP> ");
1004 switch (p[0] & 0x60) {
1005 case 0x00: printf("B "); break;
1006 case 0x20: printf("P "); break;
1007 case 0x40: printf("M "); break;
1008 case 0x60: printf("_ "); break;
1009 }
1010 if (p[0] & 0x10)
1011 printf("<DEREGISTERING> ");
1012 if (p[0] & 0x08)
1013 printf("<CONFLICT> ");
1014 if (p[0] & 0x04)
1015 printf("<ACTIVE> ");
1016 if (p[0] & 0x02)
1017 printf("<PERMANENT> ");
1018 printf("\n");
1019 p += 2;
1020 }
1021 } else {
1022 print_data(p, min(rdlen, length - ((const uchar *)p - data)));
1023 p += rdlen;
1024 }
1025 }
1026 }
1027 }
1028
1029 if ((uchar*)p < maxbuf)
1030 fdata(p, "AdditionalData:\n", maxbuf);
1031
1032 out:
1033 printf("\n");
1034 fflush(stdout);
1035 }
1036
1037
1038
1039 /*
1040 * print a NBT packet received across udp on port 138
1041 */
1042 void
1043 nbt_udp138_print(const uchar *data, int length)
1044 {
1045 const uchar *maxbuf = data + length;
1046
1047 if (maxbuf > snapend)
1048 maxbuf = snapend;
1049 if (maxbuf <= data)
1050 return;
1051 startbuf = data;
1052
1053 if (vflag < 2) {
1054 printf("NBT UDP PACKET(138)");
1055 return;
1056 }
1057
1058 data = fdata(data,
1059 "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#",
1060 maxbuf);
1061
1062 if (data != NULL)
1063 print_smb(data, maxbuf);
1064
1065 printf("\n");
1066 fflush(stdout);
1067 }
1068
1069
1070 /*
1071 print netbeui frames
1072 */
1073 void
1074 netbeui_print(u_short control, const uchar *data, int length)
1075 {
1076 const uchar *maxbuf = data + length;
1077 int len;
1078 int command;
1079 const uchar *data2;
1080 int is_truncated = 0;
1081
1082 if (maxbuf > snapend)
1083 maxbuf = snapend;
1084 if (&data[7] >= maxbuf)
1085 goto out;
1086 len = SVAL(data,0);
1087 command = CVAL(data,4);
1088 data2 = data + len;
1089 if (data2 >= maxbuf) {
1090 data2 = maxbuf;
1091 is_truncated = 1;
1092 }
1093
1094 startbuf = data;
1095
1096 if (vflag < 2) {
1097 printf("NetBeui Packet");
1098 return;
1099 }
1100
1101 printf("\n>>> NetBeui Packet\nType=0x%X ", control);
1102 data = fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf);
1103 if (data == NULL)
1104 goto out;
1105
1106 switch (command) {
1107 case 0xA:
1108 data = fdata(data, "NameQuery:[P1]\nSessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nDestination=[n2]\nSource=[n2]\n", data2);
1109 break;
1110
1111 case 0x8:
1112 data = fdata(data,
1113 "NetbiosDataGram:[P7]\nDestination=[n2]\nSource=[n2]\n", data2);
1114 break;
1115
1116 case 0xE:
1117 data = fdata(data,
1118 "NameRecognise:\n[P1]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n",
1119 data2);
1120 break;
1121
1122 case 0x19:
1123 data = fdata(data,
1124 "SessionInitialise:\nData1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",
1125 data2);
1126 break;
1127
1128 case 0x17:
1129 data = fdata(data,
1130 "SessionConfirm:\nData1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",
1131 data2);
1132 break;
1133
1134 case 0x16:
1135 data = fdata(data,
1136 "NetbiosDataOnlyLast:\nFlags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",
1137 data2);
1138 break;
1139
1140 case 0x14:
1141 data = fdata(data,
1142 "NetbiosDataAck:\n[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",
1143 data2);
1144 break;
1145
1146 case 0x18:
1147 data = fdata(data,
1148 "SessionEnd:\n[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",
1149 data2);
1150 break;
1151
1152 case 0x1f:
1153 data = fdata(data, "SessionAlive\n", data2);
1154 break;
1155
1156 default:
1157 data = fdata(data, "Unknown Netbios Command ", data2);
1158 break;
1159 }
1160 if (data == NULL)
1161 goto out;
1162
1163 if (is_truncated) {
1164 /* data2 was past the end of the buffer */
1165 goto out;
1166 }
1167
1168 /* If there isn't enough data for "\377SMB", don't look for it. */
1169 if (&data2[3] >= maxbuf)
1170 goto out;
1171
1172 if (memcmp(data2, "\377SMB",4) == 0)
1173 print_smb(data2, maxbuf);
1174 else {
1175 int i;
1176 for (i = 0; i < 128; i++) {
1177 if (&data2[i + 3] >= maxbuf)
1178 break;
1179 if (memcmp(&data2[i], "\377SMB", 4) == 0) {
1180 printf("found SMB packet at %d\n", i);
1181 print_smb(&data2[i], maxbuf);
1182 break;
1183 }
1184 }
1185 }
1186
1187 out:
1188 printf("\n");
1189 }
1190
1191
1192 /*
1193 * print IPX-Netbios frames
1194 */
1195 void
1196 ipx_netbios_print(const uchar *data, u_int length)
1197 {
1198 /*
1199 * this is a hack till I work out how to parse the rest of the
1200 * NetBIOS-over-IPX stuff
1201 */
1202 int i;
1203 const uchar *maxbuf;
1204
1205 maxbuf = data + length;
1206 /* Don't go past the end of the captured data in the packet. */
1207 if (maxbuf > snapend)
1208 maxbuf = snapend;
1209 startbuf = data;
1210 for (i = 0; i < 128; i++) {
1211 if (&data[i + 4] > maxbuf)
1212 break;
1213 if (memcmp(&data[i], "\377SMB", 4) == 0) {
1214 fdata(data, "\n>>> IPX transport ", &data[i]);
1215 if (data != NULL)
1216 print_smb(&data[i], maxbuf);
1217 printf("\n");
1218 fflush(stdout);
1219 break;
1220 }
1221 }
1222 if (i == 128)
1223 fdata(data, "\n>>> Unknown IPX ", maxbuf);
1224 }