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