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