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