source: rtems-libbsd/freebsd/contrib/tcpdump/print-smb.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

  • Update the file builder generator to handle generator specific cflags and includes. The tcpdump and libpcap have localised headers and need specific headers paths to see them. There are also module specific flags and these need to be passed to the lex and yacc generators.
  • Add the tcpdump support.
  • Property mode set to 100644
File size: 41.1 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (C) Andrew Tridgell 1995-1999
5 *
6 * This software may be distributed either under the terms of the
7 * BSD-style license that accompanies tcpdump or the GNU GPL version 2
8 * or later
9 */
10
11#ifdef HAVE_CONFIG_H
12#include "config.h"
13#endif
14
15#ifndef lint
16static const char rcsid[] _U_ =
17     "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.47 2007-12-09 00:30:47 guy Exp $";
18#endif
19
20#include <tcpdump-stdinc.h>
21
22#include <stdio.h>
23#include <string.h>
24
25#include "interface.h"
26#include "extract.h"
27#include "smb.h"
28
29static int request = 0;
30static int unicodestr = 0;
31
32const u_char *startbuf = NULL;
33
34struct smbdescript {
35    const char *req_f1;
36    const char *req_f2;
37    const char *rep_f1;
38    const char *rep_f2;
39    void (*fn)(const u_char *, const u_char *, const u_char *, const u_char *);
40};
41
42struct smbdescriptint {
43    const char *req_f1;
44    const char *req_f2;
45    const char *rep_f1;
46    const char *rep_f2;
47    void (*fn)(const u_char *, const u_char *, int, int);
48};
49
50struct smbfns
51{
52    int id;
53    const char *name;
54    int flags;
55    struct smbdescript descript;
56};
57
58struct smbfnsint
59{
60    int id;
61    const char *name;
62    int flags;
63    struct smbdescriptint descript;
64};
65
66#define DEFDESCRIPT     { NULL, NULL, NULL, NULL, NULL }
67
68#define FLG_CHAIN       (1 << 0)
69
70static struct smbfns *
71smbfind(int id, struct smbfns *list)
72{
73    int sindex;
74
75    for (sindex = 0; list[sindex].name; sindex++)
76        if (list[sindex].id == id)
77            return(&list[sindex]);
78
79    return(&list[0]);
80}
81
82static struct smbfnsint *
83smbfindint(int id, struct smbfnsint *list)
84{
85    int sindex;
86
87    for (sindex = 0; list[sindex].name; sindex++)
88        if (list[sindex].id == id)
89            return(&list[sindex]);
90
91    return(&list[0]);
92}
93
94static void
95trans2_findfirst(const u_char *param, const u_char *data, int pcnt, int dcnt)
96{
97    const char *fmt;
98
99    if (request)
100        fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n";
101    else
102        fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n";
103
104    smb_fdata(param, fmt, param + pcnt, unicodestr);
105    if (dcnt) {
106        printf("data:\n");
107        print_data(data, dcnt);
108    }
109}
110
111static void
112trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt)
113{
114    static int level = 0;
115    const char *fmt="";
116
117    if (request) {
118        TCHECK2(*param, 2);
119        level = EXTRACT_LE_16BITS(param);
120        fmt = "InfoLevel=[d]\n";
121        smb_fdata(param, fmt, param + pcnt, unicodestr);
122    } else {
123        switch (level) {
124        case 1:
125            fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n";
126            break;
127        case 2:
128            fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n";
129            break;
130        case 0x105:
131            fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n";
132            break;
133        default:
134            fmt = "UnknownLevel\n";
135            break;
136        }
137        smb_fdata(data, fmt, data + dcnt, unicodestr);
138    }
139    if (dcnt) {
140        printf("data:\n");
141        print_data(data, dcnt);
142    }
143    return;
144trunc:
145    printf("[|SMB]");
146    return;
147}
148
149struct smbfnsint trans2_fns[] = {
150    { 0, "TRANSACT2_OPEN", 0,
151        { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]",
152          NULL,
153          "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n",
154          NULL, NULL }},
155    { 1, "TRANSACT2_FINDFIRST", 0,
156        { NULL, NULL, NULL, NULL, trans2_findfirst }},
157    { 2, "TRANSACT2_FINDNEXT", 0, DEFDESCRIPT },
158    { 3, "TRANSACT2_QFSINFO", 0,
159        { NULL, NULL, NULL, NULL, trans2_qfsinfo }},
160    { 4, "TRANSACT2_SETFSINFO", 0, DEFDESCRIPT },
161    { 5, "TRANSACT2_QPATHINFO", 0, DEFDESCRIPT },
162    { 6, "TRANSACT2_SETPATHINFO", 0, DEFDESCRIPT },
163    { 7, "TRANSACT2_QFILEINFO", 0, DEFDESCRIPT },
164    { 8, "TRANSACT2_SETFILEINFO", 0, DEFDESCRIPT },
165    { 9, "TRANSACT2_FSCTL", 0, DEFDESCRIPT },
166    { 10, "TRANSACT2_IOCTL", 0, DEFDESCRIPT },
167    { 11, "TRANSACT2_FINDNOTIFYFIRST", 0, DEFDESCRIPT },
168    { 12, "TRANSACT2_FINDNOTIFYNEXT", 0, DEFDESCRIPT },
169    { 13, "TRANSACT2_MKDIR", 0, DEFDESCRIPT },
170    { -1, NULL, 0, DEFDESCRIPT }
171};
172
173
174static void
175print_trans2(const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf)
176{
177    u_int bcc;
178    static struct smbfnsint *fn = &trans2_fns[0];
179    const u_char *data, *param;
180    const u_char *w = words + 1;
181    const char *f1 = NULL, *f2 = NULL;
182    int pcnt, dcnt;
183
184    TCHECK(words[0]);
185    if (request) {
186        TCHECK2(w[14 * 2], 2);
187        pcnt = EXTRACT_LE_16BITS(w + 9 * 2);
188        param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
189        dcnt = EXTRACT_LE_16BITS(w + 11 * 2);
190        data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
191        fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns);
192    } else {
193        if (words[0] == 0) {
194            printf("%s\n", fn->name);
195            printf("Trans2Interim\n");
196            return;
197        }
198        TCHECK2(w[7 * 2], 2);
199        pcnt = EXTRACT_LE_16BITS(w + 3 * 2);
200        param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
201        dcnt = EXTRACT_LE_16BITS(w + 6 * 2);
202        data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
203    }
204
205    printf("%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt);
206
207    if (request) {
208        if (words[0] == 8) {
209            smb_fdata(words + 1,
210                "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",
211                maxbuf, unicodestr);
212            return;
213        } else {
214            smb_fdata(words + 1,
215                "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n",
216                words + 1 + 14 * 2, unicodestr);
217        }
218        f1 = fn->descript.req_f1;
219        f2 = fn->descript.req_f2;
220    } else {
221        smb_fdata(words + 1,
222            "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n",
223            words + 1 + 10 * 2, unicodestr);
224        f1 = fn->descript.rep_f1;
225        f2 = fn->descript.rep_f2;
226    }
227
228    TCHECK2(*dat, 2);
229    bcc = EXTRACT_LE_16BITS(dat);
230    printf("smb_bcc=%u\n", bcc);
231    if (fn->descript.fn)
232        (*fn->descript.fn)(param, data, pcnt, dcnt);
233    else {
234        smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr);
235        smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr);
236    }
237    return;
238trunc:
239    printf("[|SMB]");
240    return;
241}
242
243
244static void
245print_browse(const u_char *param, int paramlen, const u_char *data, int datalen)
246{
247    const u_char *maxbuf = data + datalen;
248    int command;
249
250    TCHECK(data[0]);
251    command = data[0];
252
253    smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr);
254
255    switch (command) {
256    case 0xF:
257        data = smb_fdata(data,
258            "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
259            maxbuf, unicodestr);
260        break;
261
262    case 0x1:
263        data = smb_fdata(data,
264            "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
265            maxbuf, unicodestr);
266        break;
267
268    case 0x2:
269        data = smb_fdata(data,
270            "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n",
271            maxbuf, unicodestr);
272        break;
273
274    case 0xc:
275        data = smb_fdata(data,
276            "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n",
277            maxbuf, unicodestr);
278        break;
279
280    case 0x8:
281        data = smb_fdata(data,
282            "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n",
283            maxbuf, unicodestr);
284        break;
285
286    case 0xb:
287        data = smb_fdata(data,
288            "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n",
289            maxbuf, unicodestr);
290        break;
291
292    case 0x9:
293        data = smb_fdata(data,
294            "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken=[W]\n",
295            maxbuf, unicodestr);
296        break;
297
298    case 0xa:
299        data = smb_fdata(data,
300            "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken=[W]\n*Name=[S]\n",
301            maxbuf, unicodestr);
302        break;
303
304    case 0xd:
305        data = smb_fdata(data,
306            "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n",
307            maxbuf, unicodestr);
308        break;
309
310    case 0xe:
311        data = smb_fdata(data,
312            "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr);
313        break;
314
315    default:
316        data = smb_fdata(data, "Unknown Browser Frame ", maxbuf, unicodestr);
317        break;
318    }
319    return;
320trunc:
321    printf("[|SMB]");
322    return;
323}
324
325
326static void
327print_ipc(const u_char *param, int paramlen, const u_char *data, int datalen)
328{
329    if (paramlen)
330        smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen,
331            unicodestr);
332    if (datalen)
333        smb_fdata(data, "IPC ", data + datalen, unicodestr);
334}
335
336
337static void
338print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u_char *maxbuf)
339{
340    u_int bcc;
341    const char *f1, *f2, *f3, *f4;
342    const u_char *data, *param;
343    const u_char *w = words + 1;
344    int datalen, paramlen;
345
346    if (request) {
347        TCHECK2(w[12 * 2], 2);
348        paramlen = EXTRACT_LE_16BITS(w + 9 * 2);
349        param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
350        datalen = EXTRACT_LE_16BITS(w + 11 * 2);
351        data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
352        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";
353        f2 = "|Name=[S]\n";
354        f3 = "|Param ";
355        f4 = "|Data ";
356    } else {
357        TCHECK2(w[7 * 2], 2);
358        paramlen = EXTRACT_LE_16BITS(w + 3 * 2);
359        param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
360        datalen = EXTRACT_LE_16BITS(w + 6 * 2);
361        data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
362        f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n";
363        f2 = "|Unknown ";
364        f3 = "|Param ";
365        f4 = "|Data ";
366    }
367
368    smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf),
369        unicodestr);
370
371    TCHECK2(*data1, 2);
372    bcc = EXTRACT_LE_16BITS(data1);
373    printf("smb_bcc=%u\n", bcc);
374    if (bcc > 0) {
375        smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr);
376
377        if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) {
378            print_browse(param, paramlen, data, datalen);
379            return;
380        }
381
382        if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) {
383            print_ipc(param, paramlen, data, datalen);
384            return;
385        }
386
387        if (paramlen)
388            smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf), unicodestr);
389        if (datalen)
390            smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf), unicodestr);
391    }
392    return;
393trunc:
394    printf("[|SMB]");
395    return;
396}
397
398
399static void
400print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
401{
402    u_int wct, bcc;
403    const char *f1 = NULL, *f2 = NULL;
404
405    TCHECK(words[0]);
406    wct = words[0];
407    if (request)
408        f2 = "*|Dialect=[Y]\n";
409    else {
410        if (wct == 1)
411            f1 = "Core Protocol\nDialectIndex=[d]";
412        else if (wct == 17)
413            f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey=";
414        else if (wct == 13)
415            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=";
416    }
417
418    if (f1)
419        smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf),
420            unicodestr);
421    else
422        print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1)));
423
424    TCHECK2(*data, 2);
425    bcc = EXTRACT_LE_16BITS(data);
426    printf("smb_bcc=%u\n", bcc);
427    if (bcc > 0) {
428        if (f2)
429            smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
430                maxbuf), unicodestr);
431        else
432            print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
433    }
434    return;
435trunc:
436    printf("[|SMB]");
437    return;
438}
439
440static void
441print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
442{
443    u_int wct, bcc;
444    const char *f1 = NULL, *f2 = NULL;
445
446    TCHECK(words[0]);
447    wct = words[0];
448    if (request) {
449        if (wct == 10)
450            f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n";
451        else
452            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";
453    } else {
454        if (wct == 3) {
455            f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n";
456        } else if (wct == 13) {
457            f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n";
458            f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n";
459        }
460    }
461
462    if (f1)
463        smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf),
464            unicodestr);
465    else
466        print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1)));
467
468    TCHECK2(*data, 2);
469    bcc = EXTRACT_LE_16BITS(data);
470    printf("smb_bcc=%u\n", bcc);
471    if (bcc > 0) {
472        if (f2)
473            smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
474                maxbuf), unicodestr);
475        else
476            print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
477    }
478    return;
479trunc:
480    printf("[|SMB]");
481    return;
482}
483
484static void
485print_lockingandx(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
486{
487    u_int wct, bcc;
488    const u_char *maxwords;
489    const char *f1 = NULL, *f2 = NULL;
490
491    TCHECK(words[0]);
492    wct = words[0];
493    if (request) {
494        f1 = "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n";
495        TCHECK(words[7]);
496        if (words[7] & 0x10)
497            f2 = "*Process=[d]\n[P2]Offset=[M]\nLength=[M]\n";
498        else
499            f2 = "*Process=[d]\nOffset=[D]\nLength=[D]\n";
500    } else {
501        f1 = "Com2=[w]\nOff2=[d]\n";
502    }
503
504    maxwords = SMBMIN(words + 1 + wct * 2, maxbuf);
505    if (wct)
506        smb_fdata(words + 1, f1, maxwords, unicodestr);
507
508    TCHECK2(*data, 2);
509    bcc = EXTRACT_LE_16BITS(data);
510    printf("smb_bcc=%u\n", bcc);
511    if (bcc > 0) {
512        if (f2)
513            smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
514                maxbuf), unicodestr);
515        else
516            print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
517    }
518    return;
519trunc:
520    printf("[|SMB]");
521    return;
522}
523
524
525static struct smbfns smb_fns[] = {
526    { -1, "SMBunknown", 0, DEFDESCRIPT },
527
528    { SMBtcon, "SMBtcon", 0,
529        { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n",
530          "MaxXmit=[d]\nTreeId=[d]\n", NULL,
531          NULL } },
532
533    { SMBtdis, "SMBtdis", 0, DEFDESCRIPT },
534    { SMBexit,  "SMBexit", 0, DEFDESCRIPT },
535    { SMBioctl, "SMBioctl", 0, DEFDESCRIPT },
536
537    { SMBecho, "SMBecho", 0,
538        { "ReverbCount=[d]\n", NULL,
539          "SequenceNum=[d]\n", NULL,
540          NULL } },
541
542    { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT },
543
544    { SMBgetatr, "SMBgetatr", 0,
545        { NULL, "Path=[Z]\n",
546          "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL,
547          NULL } },
548
549    { SMBsetatr, "SMBsetatr", 0,
550        { "Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n", "Path=[Z]\n",
551          NULL, NULL, NULL } },
552
553    { SMBchkpth, "SMBchkpth", 0,
554       { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
555
556    { SMBsearch, "SMBsearch", 0,
557        { "Count=[d]\nAttrib=[A]\n",
558          "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n",
559          "Count=[d]\n",
560          "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",
561          NULL } },
562
563    { SMBopen, "SMBopen", 0,
564        { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n",
565          "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n",
566          NULL, NULL } },
567
568    { SMBcreate, "SMBcreate", 0,
569        { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
570
571    { SMBmknew, "SMBmknew", 0,
572        { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
573
574    { SMBunlink, "SMBunlink", 0,
575        { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } },
576
577    { SMBread, "SMBread", 0,
578        { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
579          "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
580
581    { SMBwrite, "SMBwrite", 0,
582        { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
583          "Count=[d]\n", NULL, NULL } },
584
585    { SMBclose, "SMBclose", 0,
586        { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } },
587
588    { SMBmkdir, "SMBmkdir", 0,
589        { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
590
591    { SMBrmdir, "SMBrmdir", 0,
592        { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
593
594    { SMBdskattr, "SMBdskattr", 0,
595        { NULL, NULL,
596          "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n",
597          NULL, NULL } },
598
599    { SMBmv, "SMBmv", 0,
600        { "Attrib=[A]\n", "OldPath=[Z]\nNewPath=[Z]\n", NULL, NULL, NULL } },
601
602    /*
603     * this is a Pathworks specific call, allowing the
604     * changing of the root path
605     */
606    { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
607
608    { SMBlseek, "SMBlseek", 0,
609        { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } },
610
611    { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
612
613    { SMBsplopen, "SMBsplopen", 0,
614        { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n",
615          NULL, NULL } },
616
617    { SMBsplclose, "SMBsplclose", 0,
618        { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
619
620    { SMBsplretq, "SMBsplretq", 0,
621        { "MaxCount=[d]\nStartIndex=[d]\n", NULL,
622          "Count=[d]\nIndex=[d]\n",
623          "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n",
624          NULL } },
625
626    { SMBsplwr, "SMBsplwr", 0,
627        { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
628
629    { SMBlock, "SMBlock", 0,
630        { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
631
632    { SMBunlock, "SMBunlock", 0,
633        { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
634
635    /* CORE+ PROTOCOL FOLLOWS */
636
637    { SMBreadbraw, "SMBreadbraw", 0,
638        { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n",
639          NULL, NULL, NULL, NULL } },
640
641    { SMBwritebraw, "SMBwritebraw", 0,
642        { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n",
643          NULL, "WriteRawAck", NULL, NULL } },
644
645    { SMBwritec, "SMBwritec", 0,
646        { NULL, NULL, "Count=[d]\n", NULL, NULL } },
647
648    { SMBwriteclose, "SMBwriteclose", 0,
649        { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])",
650          NULL, "Count=[d]\n", NULL, NULL } },
651
652    { SMBlockread, "SMBlockread", 0,
653        { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
654          "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
655
656    { SMBwriteunlock, "SMBwriteunlock", 0,
657        { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
658          "Count=[d]\n", NULL, NULL } },
659
660    { SMBreadBmpx, "SMBreadBmpx", 0,
661        { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n",
662          NULL,
663          "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n",
664          NULL, NULL } },
665
666    { SMBwriteBmpx, "SMBwriteBmpx", 0,
667        { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL,
668          "Remaining=[d]\n", NULL, NULL } },
669
670    { SMBwriteBs, "SMBwriteBs", 0,
671        { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n",
672          NULL, "Count=[d]\n", NULL, NULL } },
673
674    { SMBsetattrE, "SMBsetattrE", 0,
675        { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL,
676          NULL, NULL, NULL } },
677
678    { SMBgetattrE, "SMBgetattrE", 0,
679        { "Handle=[d]\n", NULL,
680          "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n",
681          NULL, NULL } },
682
683    { SMBtranss, "SMBtranss", 0, DEFDESCRIPT },
684    { SMBioctls, "SMBioctls", 0, DEFDESCRIPT },
685
686    { SMBcopy, "SMBcopy", 0,
687        { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
688          "CopyCount=[d]\n",  "|ErrStr=[S]\n",  NULL } },
689
690    { SMBmove, "SMBmove", 0,
691        { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
692          "MoveCount=[d]\n",  "|ErrStr=[S]\n",  NULL } },
693
694    { SMBopenX, "SMBopenX", FLG_CHAIN,
695        { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n",
696          "Path=[S]\n",
697          "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",
698          NULL, NULL } },
699
700    { SMBreadX, "SMBreadX", FLG_CHAIN,
701        { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n",
702          NULL,
703          "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n",
704          NULL, NULL } },
705
706    { SMBwriteX, "SMBwriteX", FLG_CHAIN,
707        { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n",
708          NULL,
709          "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n",
710          NULL, NULL } },
711
712    { SMBffirst, "SMBffirst", 0,
713        { "Count=[d]\nAttrib=[A]\n",
714          "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
715          "Count=[d]\n",
716          "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",
717          NULL } },
718
719    { SMBfunique, "SMBfunique", 0,
720        { "Count=[d]\nAttrib=[A]\n",
721          "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
722          "Count=[d]\n",
723          "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",
724          NULL } },
725
726    { SMBfclose, "SMBfclose", 0,
727        { "Count=[d]\nAttrib=[A]\n",
728          "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
729          "Count=[d]\n",
730          "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",
731          NULL } },
732
733    { SMBfindnclose, "SMBfindnclose", 0,
734        { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
735
736    { SMBfindclose, "SMBfindclose", 0,
737        { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
738
739    { SMBsends, "SMBsends", 0,
740        { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
741
742    { SMBsendstrt, "SMBsendstrt", 0,
743        { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } },
744
745    { SMBsendend, "SMBsendend", 0,
746        { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
747
748    { SMBsendtxt, "SMBsendtxt", 0,
749        { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
750
751    { SMBsendb, "SMBsendb", 0,
752        { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
753
754    { SMBfwdname, "SMBfwdname", 0, DEFDESCRIPT },
755    { SMBcancelf, "SMBcancelf", 0, DEFDESCRIPT },
756    { SMBgetmac, "SMBgetmac", 0, DEFDESCRIPT },
757
758    { SMBnegprot, "SMBnegprot", 0,
759        { NULL, NULL, NULL, NULL, print_negprot } },
760
761    { SMBsesssetupX, "SMBsesssetupX", FLG_CHAIN,
762        { NULL, NULL, NULL, NULL, print_sesssetup } },
763
764    { SMBtconX, "SMBtconX", FLG_CHAIN,
765        { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n",
766          NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } },
767
768    { SMBlockingX, "SMBlockingX", FLG_CHAIN,
769        { NULL, NULL, NULL, NULL, print_lockingandx } },
770
771    { SMBtrans2, "SMBtrans2", 0, { NULL, NULL, NULL, NULL, print_trans2 } },
772
773    { SMBtranss2, "SMBtranss2", 0, DEFDESCRIPT },
774    { SMBctemp, "SMBctemp", 0, DEFDESCRIPT },
775    { SMBreadBs, "SMBreadBs", 0, DEFDESCRIPT },
776    { SMBtrans, "SMBtrans", 0, { NULL, NULL, NULL, NULL, print_trans } },
777
778    { SMBnttrans, "SMBnttrans", 0, DEFDESCRIPT },
779    { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT },
780
781    { SMBntcreateX, "SMBntcreateX", FLG_CHAIN,
782        { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[ld]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n",
783          "Path=[C]\n",
784          "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",
785          NULL, NULL } },
786
787    { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT },
788
789    { -1, NULL, 0, DEFDESCRIPT }
790};
791
792
793/*
794 * print a SMB message
795 */
796static void
797print_smb(const u_char *buf, const u_char *maxbuf)
798{
799    u_int16_t flags2;
800    int nterrcodes;
801    int command;
802    u_int32_t nterror;
803    const u_char *words, *maxwords, *data;
804    struct smbfns *fn;
805    const char *fmt_smbheader =
806        "[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";
807    int smboffset;
808
809    TCHECK(buf[9]);
810    request = (buf[9] & 0x80) ? 0 : 1;
811    flags2 = EXTRACT_LE_16BITS(&buf[10]);
812    unicodestr = flags2 & 0x8000;
813    nterrcodes = flags2 & 0x4000;
814    startbuf = buf;
815
816    command = buf[4];
817
818    fn = smbfind(command, smb_fns);
819
820    if (vflag > 1)
821        printf("\n");
822
823    printf("SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY");
824
825    if (vflag < 2)
826        return;
827
828    /* print out the header */
829    smb_fdata(buf, fmt_smbheader, buf + 33, unicodestr);
830
831    if (nterrcodes) {
832        nterror = EXTRACT_LE_32BITS(&buf[5]);
833        if (nterror)
834            printf("NTError = %s\n", nt_errstr(nterror));
835    } else {
836        if (buf[5])
837            printf("SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7])));
838    }
839
840    smboffset = 32;
841
842    for (;;) {
843        const char *f1, *f2;
844        int wct;
845        u_int bcc;
846        int newsmboffset;
847
848        words = buf + smboffset;
849        TCHECK(words[0]);
850        wct = words[0];
851        data = words + 1 + wct * 2;
852        maxwords = SMBMIN(data, maxbuf);
853
854        if (request) {
855            f1 = fn->descript.req_f1;
856            f2 = fn->descript.req_f2;
857        } else {
858            f1 = fn->descript.rep_f1;
859            f2 = fn->descript.rep_f2;
860        }
861
862        if (fn->descript.fn)
863            (*fn->descript.fn)(words, data, buf, maxbuf);
864        else {
865            if (wct) {
866                if (f1)
867                    smb_fdata(words + 1, f1, words + 1 + wct * 2, unicodestr);
868                else {
869                    int i;
870                    int v;
871
872                    for (i = 0; &words[1 + 2 * i] < maxwords; i++) {
873                        TCHECK2(words[1 + 2 * i], 2);
874                        v = EXTRACT_LE_16BITS(words + 1 + 2 * i);
875                        printf("smb_vwv[%d]=%d (0x%X)\n", i, v, v);
876                    }
877                }
878            }
879
880            TCHECK2(*data, 2);
881            bcc = EXTRACT_LE_16BITS(data);
882            printf("smb_bcc=%u\n", bcc);
883            if (f2) {
884                if (bcc > 0)
885                    smb_fdata(data + 2, f2, data + 2 + bcc, unicodestr);
886            } else {
887                if (bcc > 0) {
888                    printf("smb_buf[]=\n");
889                    print_data(data + 2, SMBMIN(bcc, PTR_DIFF(maxbuf, data + 2)));
890                }
891            }
892        }
893
894        if ((fn->flags & FLG_CHAIN) == 0)
895            break;
896        if (wct == 0)
897            break;
898        TCHECK(words[1]);
899        command = words[1];
900        if (command == 0xFF)
901            break;
902        TCHECK2(words[3], 2);
903        newsmboffset = EXTRACT_LE_16BITS(words + 3);
904
905        fn = smbfind(command, smb_fns);
906
907        printf("\nSMB PACKET: %s (%s) (CHAINED)\n",
908            fn->name, request ? "REQUEST" : "REPLY");
909        if (newsmboffset <= smboffset) {
910            printf("Bad andX offset: %u <= %u\n", newsmboffset, smboffset);
911            break;
912        }
913        smboffset = newsmboffset;
914    }
915
916    printf("\n");
917    return;
918trunc:
919    printf("[|SMB]");
920    return;
921}
922
923
924/*
925 * print a NBT packet received across tcp on port 139
926 */
927void
928nbt_tcp_print(const u_char *data, int length)
929{
930    int caplen;
931    int type;
932    u_int nbt_len;
933    const u_char *maxbuf;
934
935    if (length < 4)
936        goto trunc;
937    if (snapend < data)
938        goto trunc;
939    caplen = snapend - data;
940    if (caplen < 4)
941        goto trunc;
942    maxbuf = data + caplen;
943    type = data[0];
944    nbt_len = EXTRACT_16BITS(data + 2);
945    length -= 4;
946    caplen -= 4;
947
948    startbuf = data;
949
950    if (vflag < 2) {
951        printf(" NBT Session Packet: ");
952        switch (type) {
953        case 0x00:
954            printf("Session Message");
955            break;
956
957        case 0x81:
958            printf("Session Request");
959            break;
960
961        case 0x82:
962            printf("Session Granted");
963            break;
964
965        case 0x83:
966          {
967            int ecode;
968
969            if (nbt_len < 4)
970                goto trunc;
971            if (length < 4)
972                goto trunc;
973            if (caplen < 4)
974                goto trunc;
975            ecode = data[4];
976
977            printf("Session Reject, ");
978            switch (ecode) {
979            case 0x80:
980                printf("Not listening on called name");
981                break;
982            case 0x81:
983                printf("Not listening for calling name");
984                break;
985            case 0x82:
986                printf("Called name not present");
987                break;
988            case 0x83:
989                printf("Called name present, but insufficient resources");
990                break;
991            default:
992                printf("Unspecified error 0x%X", ecode);
993                break;
994            }
995          }
996            break;
997
998        case 0x85:
999            printf("Session Keepalive");
1000            break;
1001
1002        default:
1003            data = smb_fdata(data, "Unknown packet type [rB]", maxbuf, 0);
1004            break;
1005        }
1006    } else {
1007        printf ("\n>>> NBT Session Packet\n");
1008        switch (type) {
1009        case 0x00:
1010            data = smb_fdata(data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n",
1011                data + 4, 0);
1012            if (data == NULL)
1013                break;
1014            if (nbt_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) {
1015                if ((int)nbt_len > caplen) {
1016                    if ((int)nbt_len > length)
1017                        printf("WARNING: Packet is continued in later TCP segments\n");
1018                    else
1019                        printf("WARNING: Short packet. Try increasing the snap length by %d\n",
1020                            nbt_len - caplen);
1021                }
1022                print_smb(data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf);
1023            } else
1024                printf("Session packet:(raw data or continuation?)\n");
1025            break;
1026
1027        case 0x81:
1028            data = smb_fdata(data,
1029                "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n",
1030                maxbuf, 0);
1031            break;
1032
1033        case 0x82:
1034            data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0);
1035            break;
1036
1037        case 0x83:
1038          {
1039            const u_char *origdata;
1040            int ecode;
1041
1042            origdata = data;
1043            data = smb_fdata(data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n",
1044                maxbuf, 0);
1045            if (data == NULL)
1046                break;
1047            if (nbt_len >= 1 && caplen >= 1) {
1048                ecode = origdata[4];
1049                switch (ecode) {
1050                case 0x80:
1051                    printf("Not listening on called name\n");
1052                    break;
1053                case 0x81:
1054                    printf("Not listening for calling name\n");
1055                    break;
1056                case 0x82:
1057                    printf("Called name not present\n");
1058                    break;
1059                case 0x83:
1060                    printf("Called name present, but insufficient resources\n");
1061                    break;
1062                default:
1063                    printf("Unspecified error 0x%X\n", ecode);
1064                    break;
1065                }
1066            }
1067          }
1068            break;
1069
1070        case 0x85:
1071            data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0);
1072            break;
1073
1074        default:
1075            data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0);
1076            break;
1077        }
1078        printf("\n");
1079        fflush(stdout);
1080    }
1081    return;
1082trunc:
1083    printf("[|SMB]");
1084    return;
1085}
1086
1087
1088/*
1089 * print a NBT packet received across udp on port 137
1090 */
1091void
1092nbt_udp137_print(const u_char *data, int length)
1093{
1094    const u_char *maxbuf = data + length;
1095    int name_trn_id, response, opcode, nm_flags, rcode;
1096    int qdcount, ancount, nscount, arcount;
1097    const char *opcodestr;
1098    const u_char *p;
1099    int total, i;
1100
1101    TCHECK2(data[10], 2);
1102    name_trn_id = EXTRACT_16BITS(data);
1103    response = (data[2] >> 7);
1104    opcode = (data[2] >> 3) & 0xF;
1105    nm_flags = ((data[2] & 0x7) << 4) + (data[3] >> 4);
1106    rcode = data[3] & 0xF;
1107    qdcount = EXTRACT_16BITS(data + 4);
1108    ancount = EXTRACT_16BITS(data + 6);
1109    nscount = EXTRACT_16BITS(data + 8);
1110    arcount = EXTRACT_16BITS(data + 10);
1111    startbuf = data;
1112
1113    if (maxbuf <= data)
1114        return;
1115
1116    if (vflag > 1)
1117        printf("\n>>> ");
1118
1119    printf("NBT UDP PACKET(137): ");
1120
1121    switch (opcode) {
1122    case 0: opcodestr = "QUERY"; break;
1123    case 5: opcodestr = "REGISTRATION"; break;
1124    case 6: opcodestr = "RELEASE"; break;
1125    case 7: opcodestr = "WACK"; break;
1126    case 8: opcodestr = "REFRESH(8)"; break;
1127    case 9: opcodestr = "REFRESH"; break;
1128    case 15: opcodestr = "MULTIHOMED REGISTRATION"; break;
1129    default: opcodestr = "OPUNKNOWN"; break;
1130    }
1131    printf("%s", opcodestr);
1132    if (response) {
1133        if (rcode)
1134            printf("; NEGATIVE");
1135        else
1136            printf("; POSITIVE");
1137    }
1138
1139    if (response)
1140        printf("; RESPONSE");
1141    else
1142        printf("; REQUEST");
1143
1144    if (nm_flags & 1)
1145        printf("; BROADCAST");
1146    else
1147        printf("; UNICAST");
1148
1149    if (vflag < 2)
1150        return;
1151
1152    printf("\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n",
1153        name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount,
1154        arcount);
1155
1156    p = data + 12;
1157
1158    total = ancount + nscount + arcount;
1159
1160    if (qdcount > 100 || total > 100) {
1161        printf("Corrupt packet??\n");
1162        return;
1163    }
1164
1165    if (qdcount) {
1166        printf("QuestionRecords:\n");
1167        for (i = 0; i < qdcount; i++) {
1168            p = smb_fdata(p,
1169                "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#",
1170                maxbuf, 0);
1171            if (p == NULL)
1172                goto out;
1173        }
1174    }
1175
1176    if (total) {
1177        printf("\nResourceRecords:\n");
1178        for (i = 0; i < total; i++) {
1179            int rdlen;
1180            int restype;
1181
1182            p = smb_fdata(p, "Name=[n1]\n#", maxbuf, 0);
1183            if (p == NULL)
1184                goto out;
1185            restype = EXTRACT_16BITS(p);
1186            p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0);
1187            if (p == NULL)
1188                goto out;
1189            rdlen = EXTRACT_16BITS(p);
1190            printf("ResourceLength=%d\nResourceData=\n", rdlen);
1191            p += 2;
1192            if (rdlen == 6) {
1193                p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0);
1194                if (p == NULL)
1195                    goto out;
1196            } else {
1197                if (restype == 0x21) {
1198                    int numnames;
1199
1200                    TCHECK(*p);
1201                    numnames = p[0];
1202                    p = smb_fdata(p, "NumNames=[B]\n", p + 1, 0);
1203                    if (p == NULL)
1204                        goto out;
1205                    while (numnames--) {
1206                        p = smb_fdata(p, "Name=[n2]\t#", maxbuf, 0);
1207                        if (p == NULL)
1208                            goto out;
1209                        TCHECK(*p);
1210                        if (p[0] & 0x80)
1211                            printf("<GROUP> ");
1212                        switch (p[0] & 0x60) {
1213                        case 0x00: printf("B "); break;
1214                        case 0x20: printf("P "); break;
1215                        case 0x40: printf("M "); break;
1216                        case 0x60: printf("_ "); break;
1217                        }
1218                        if (p[0] & 0x10)
1219                            printf("<DEREGISTERING> ");
1220                        if (p[0] & 0x08)
1221                            printf("<CONFLICT> ");
1222                        if (p[0] & 0x04)
1223                            printf("<ACTIVE> ");
1224                        if (p[0] & 0x02)
1225                            printf("<PERMANENT> ");
1226                        printf("\n");
1227                        p += 2;
1228                    }
1229                } else {
1230                    print_data(p, min(rdlen, length - (p - data)));
1231                    p += rdlen;
1232                }
1233            }
1234        }
1235    }
1236
1237    if (p < maxbuf)
1238        smb_fdata(p, "AdditionalData:\n", maxbuf, 0);
1239
1240out:
1241    printf("\n");
1242    fflush(stdout);
1243    return;
1244trunc:
1245    printf("[|SMB]");
1246    return;
1247}
1248
1249/*
1250 * Print an SMB-over-TCP packet received across tcp on port 445
1251 */
1252void
1253smb_tcp_print (const u_char * data, int length)
1254{
1255    int caplen;
1256    u_int smb_len;
1257    const u_char *maxbuf;
1258
1259    if (length < 4)
1260        goto trunc;
1261    if (snapend < data)
1262        goto trunc;
1263    caplen = snapend - data;
1264    if (caplen < 4)
1265        goto trunc;
1266    maxbuf = data + caplen;
1267    smb_len = EXTRACT_24BITS(data + 1);
1268    length -= 4;
1269    caplen -= 4;
1270
1271    startbuf = data;
1272    data += 4;
1273
1274    if (smb_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) {
1275        if ((int)smb_len > caplen) {
1276            if ((int)smb_len > length)
1277                printf("WARNING: Packet is continued in later TCP segments\n");
1278            else
1279                printf("WARNING: Short packet. Try increasing the snap length by %d\n",
1280                    smb_len - caplen);
1281        }
1282        print_smb(data, maxbuf > data + smb_len ? data + smb_len : maxbuf);
1283    } else
1284        printf("SMB-over-TCP packet:(raw data or continuation?)\n");
1285    return;
1286trunc:
1287    printf("[|SMB]");
1288    return;
1289}
1290
1291/*
1292 * print a NBT packet received across udp on port 138
1293 */
1294void
1295nbt_udp138_print(const u_char *data, int length)
1296{
1297    const u_char *maxbuf = data + length;
1298
1299    if (maxbuf > snapend)
1300        maxbuf = snapend;
1301    if (maxbuf <= data)
1302        return;
1303    startbuf = data;
1304
1305    if (vflag < 2) {
1306        printf("NBT UDP PACKET(138)");
1307        return;
1308    }
1309
1310    data = smb_fdata(data,
1311        "\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#",
1312        maxbuf, 0);
1313
1314    if (data != NULL) {
1315        /* If there isn't enough data for "\377SMB", don't check for it. */
1316        if (&data[3] >= maxbuf)
1317            goto out;
1318
1319        if (memcmp(data, "\377SMB",4) == 0)
1320            print_smb(data, maxbuf);
1321    }
1322out:
1323    printf("\n");
1324    fflush(stdout);
1325}
1326
1327
1328/*
1329   print netbeui frames
1330*/
1331struct nbf_strings {
1332        const char      *name;
1333        const char      *nonverbose;
1334        const char      *verbose;
1335} nbf_strings[0x20] = {
1336        { "Add Group Name Query", ", [P23]Name to add=[n2]#",
1337          "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" },
1338        { "Add Name Query", ", [P23]Name to add=[n2]#",
1339          "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" },
1340        { "Name In Conflict", NULL, NULL },
1341        { "Status Query", NULL, NULL },
1342        { NULL, NULL, NULL },   /* not used */
1343        { NULL, NULL, NULL },   /* not used */
1344        { NULL, NULL, NULL },   /* not used */
1345        { "Terminate Trace", NULL, NULL },
1346        { "Datagram", NULL,
1347          "[P7]Destination=[n2]\nSource=[n2]\n" },
1348        { "Broadcast Datagram", NULL,
1349          "[P7]Destination=[n2]\nSource=[n2]\n" },
1350        { "Name Query", ", [P7]Name=[n2]#",
1351          "[P1]SessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nName=[n2]\nName of sender=[n2]\n" },
1352        { NULL, NULL, NULL },   /* not used */
1353        { NULL, NULL, NULL },   /* not used */
1354        { "Add Name Response", ", [P1]GroupName=[w] [P4]Destination=[n2] Source=[n2]#",
1355          "AddNameInProcess=[B]\nGroupName=[w]\nTransmitCorrelator=[w][P2]\nDestination=[n2]\nSource=[n2]\n" },
1356        { "Name Recognized", NULL,
1357          "[P1]Data2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n" },
1358        { "Status Response", NULL, NULL },
1359        { NULL, NULL, NULL },   /* not used */
1360        { NULL, NULL, NULL },   /* not used */
1361        { NULL, NULL, NULL },   /* not used */
1362        { "Terminate Trace", NULL, NULL },
1363        { "Data Ack", NULL,
1364          "[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1365        { "Data First/Middle", NULL,
1366          "Flags=[{RECEIVE_CONTINUE|NO_ACK||PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1367        { "Data Only/Last", NULL,
1368          "Flags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1369        { "Session Confirm", NULL,
1370          "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1371        { "Session End", NULL,
1372          "[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1373        { "Session Initialize", NULL,
1374          "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1375        { "No Receive", NULL,
1376          "Flags=[{|SEND_NO_ACK}]\nDataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1377        { "Receive Outstanding", NULL,
1378          "[P1]DataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1379        { "Receive Continue", NULL,
1380          "[P2]TransmitCorrelator=[w]\n[P2]RemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
1381        { NULL, NULL, NULL },   /* not used */
1382        { NULL, NULL, NULL },   /* not used */
1383        { "Session Alive", NULL, NULL }
1384};
1385
1386void
1387netbeui_print(u_short control, const u_char *data, int length)
1388{
1389    const u_char *maxbuf = data + length;
1390    int len;
1391    int command;
1392    const u_char *data2;
1393    int is_truncated = 0;
1394
1395    if (maxbuf > snapend)
1396        maxbuf = snapend;
1397    TCHECK(data[4]);
1398    len = EXTRACT_LE_16BITS(data);
1399    command = data[4];
1400    data2 = data + len;
1401    if (data2 >= maxbuf) {
1402        data2 = maxbuf;
1403        is_truncated = 1;
1404    }
1405
1406    startbuf = data;
1407
1408    if (vflag < 2) {
1409        printf("NBF Packet: ");
1410        data = smb_fdata(data, "[P5]#", maxbuf, 0);
1411    } else {
1412        printf("\n>>> NBF Packet\nType=0x%X ", control);
1413        data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0);
1414    }
1415    if (data == NULL)
1416        goto out;
1417
1418    if (command > 0x1f || nbf_strings[command].name == NULL) {
1419        if (vflag < 2)
1420            data = smb_fdata(data, "Unknown NBF Command#", data2, 0);
1421        else
1422            data = smb_fdata(data, "Unknown NBF Command\n", data2, 0);
1423    } else {
1424        if (vflag < 2) {
1425            printf("%s", nbf_strings[command].name);
1426            if (nbf_strings[command].nonverbose != NULL)
1427                data = smb_fdata(data, nbf_strings[command].nonverbose, data2, 0);
1428        } else {
1429            printf("%s:\n", nbf_strings[command].name);
1430            if (nbf_strings[command].verbose != NULL)
1431                data = smb_fdata(data, nbf_strings[command].verbose, data2, 0);
1432            else
1433                printf("\n");
1434        }
1435    }
1436
1437    if (vflag < 2)
1438        return;
1439
1440    if (data == NULL)
1441        goto out;
1442
1443    if (is_truncated) {
1444        /* data2 was past the end of the buffer */
1445        goto out;
1446    }
1447
1448    /* If this isn't a command that would contain an SMB message, quit. */
1449    if (command != 0x08 && command != 0x09 && command != 0x15 &&
1450        command != 0x16)
1451        goto out;
1452
1453    /* If there isn't enough data for "\377SMB", don't look for it. */
1454    if (&data2[3] >= maxbuf)
1455        goto out;
1456
1457    if (memcmp(data2, "\377SMB",4) == 0)
1458        print_smb(data2, maxbuf);
1459    else {
1460        int i;
1461        for (i = 0; i < 128; i++) {
1462            if (&data2[i + 3] >= maxbuf)
1463                break;
1464            if (memcmp(&data2[i], "\377SMB", 4) == 0) {
1465                printf("found SMB packet at %d\n", i);
1466                print_smb(&data2[i], maxbuf);
1467                break;
1468            }
1469        }
1470    }
1471
1472out:
1473    printf("\n");
1474    return;
1475trunc:
1476    printf("[|SMB]");
1477    return;
1478}
1479
1480
1481/*
1482 * print IPX-Netbios frames
1483 */
1484void
1485ipx_netbios_print(const u_char *data, u_int length)
1486{
1487    /*
1488     * this is a hack till I work out how to parse the rest of the
1489     * NetBIOS-over-IPX stuff
1490     */
1491    int i;
1492    const u_char *maxbuf;
1493
1494    maxbuf = data + length;
1495    /* Don't go past the end of the captured data in the packet. */
1496    if (maxbuf > snapend)
1497        maxbuf = snapend;
1498    startbuf = data;
1499    for (i = 0; i < 128; i++) {
1500        if (&data[i + 4] > maxbuf)
1501            break;
1502        if (memcmp(&data[i], "\377SMB", 4) == 0) {
1503            smb_fdata(data, "\n>>> IPX transport ", &data[i], 0);
1504            print_smb(&data[i], maxbuf);
1505            printf("\n");
1506            fflush(stdout);
1507            break;
1508        }
1509    }
1510    if (i == 128)
1511        smb_fdata(data, "\n>>> Unknown IPX ", maxbuf, 0);
1512}
Note: See TracBrowser for help on using the repository browser.