1 /* $OpenBSD: print-smb.c,v 1.5 2017/05/30 20:10:45 deraadt Exp $ */ 2 3 /* 4 Copyright (C) Andrew Tridgell 1995-1999 5 6 This software may be distributed either under the terms of the 7 BSD-style license that accompanies tcpdump or the GNU GPL version 2 8 or later */ 9 10 #ifdef HAVE_CONFIG_H 11 #include "config.h" 12 #endif 13 14 #include <stdio.h> 15 #include <string.h> 16 #include <sys/types.h> 17 18 #include "interface.h" 19 #include "smb.h" 20 21 static int request=0; 22 23 const uchar *startbuf=NULL; 24 25 struct smbdescript 26 { 27 char *req_f1; 28 char *req_f2; 29 char *rep_f1; 30 char *rep_f2; 31 void (*fn)(); /* sometimes (u_char *, u_char *, u_char *, u_char *) 32 and sometimes (u_char *, u_char *, int, int) */ 33 }; 34 35 struct smbfns 36 { 37 int id; 38 char *name; 39 int flags; 40 struct smbdescript descript; 41 }; 42 43 #define DEFDESCRIPT {NULL,NULL,NULL,NULL,NULL} 44 45 #define FLG_CHAIN (1<<0) 46 47 static struct smbfns *smbfind(int id,struct smbfns *list) 48 { 49 int sindex; 50 51 for (sindex=0;list[sindex].name;sindex++) 52 if (list[sindex].id == id) return(&list[sindex]); 53 54 return(&list[0]); 55 } 56 57 static void trans2_findfirst(uchar *param,uchar *data,int pcnt,int dcnt) 58 { 59 char *fmt; 60 61 if (request) { 62 fmt = "attr [A] searchcnt [d] flags [w] level [dP5] file [S] "; 63 } else { 64 fmt = "handle [w] cnt [d] eos [w] eoffset [d] lastnameofs [w] "; 65 } 66 67 fdata(param,fmt,param+pcnt); 68 } 69 70 static void trans2_qfsinfo(uchar *param,uchar *data,int pcnt,int dcnt) 71 { 72 static int level=0; 73 char *fmt=""; 74 75 if (request) { 76 level = SVAL(param,0); 77 fmt = "info level [d] "; 78 fdata(param,fmt,param+pcnt); 79 } else { 80 switch (level) { 81 case 1: 82 fmt = "fsid [W] sectorunit [D] unit [D] avail [D] sectorsize [d] "; 83 break; 84 case 2: 85 fmt = "creat [T2] volnamelen [B] volume [s12] "; 86 break; 87 case 0x105: 88 fmt = "capabilities [W] maxfilelen [D] volnamelen [D] volume [S] "; 89 break; 90 default: 91 fmt = "unknown level "; 92 } 93 fdata(data,fmt,data+dcnt); 94 } 95 } 96 97 struct smbfns trans2_fns[] = { 98 {0,"TRANSACT2_OPEN",0, 99 {"flags2 [w] mode [w] searchattr [A] attr [A] time [T2] ofun [w] size [D] res [w,w,w,w,w] path [S]",NULL, 100 "handle [d] attr [A] time [T2] size [D] access [w] type [w] state [w] action [w] inode [W] offerr [d] |ealen [d] ",NULL,NULL}}, 101 102 {1,"TRANSACT2_FINDFIRST",0, 103 {NULL,NULL,NULL,NULL,trans2_findfirst}}, 104 105 {2,"TRANSACT2_FINDNEXT",0,DEFDESCRIPT}, 106 107 {3,"TRANSACT2_QFSINFO",0, 108 {NULL,NULL,NULL,NULL,trans2_qfsinfo}}, 109 110 {4,"TRANSACT2_SETFSINFO",0,DEFDESCRIPT}, 111 {5,"TRANSACT2_QPATHINFO",0,DEFDESCRIPT}, 112 {6,"TRANSACT2_SETPATHINFO",0,DEFDESCRIPT}, 113 {7,"TRANSACT2_QFILEINFO",0,DEFDESCRIPT}, 114 {8,"TRANSACT2_SETFILEINFO",0,DEFDESCRIPT}, 115 {9,"TRANSACT2_FSCTL",0,DEFDESCRIPT}, 116 {10,"TRANSACT2_IOCTL",0,DEFDESCRIPT}, 117 {11,"TRANSACT2_FINDNOTIFYFIRST",0,DEFDESCRIPT}, 118 {12,"TRANSACT2_FINDNOTIFYNEXT",0,DEFDESCRIPT}, 119 {13,"TRANSACT2_MKDIR",0,DEFDESCRIPT}, 120 {-1,NULL,0,DEFDESCRIPT}}; 121 122 123 static void print_trans2(uchar *words,uchar *dat,uchar *buf,uchar *maxbuf) 124 { 125 static struct smbfns *fn = &trans2_fns[0]; 126 uchar *data,*param; 127 uchar *f1=NULL,*f2=NULL; 128 int pcnt,dcnt; 129 130 if (request) { 131 fn = smbfind(SVAL(words+1,14*2),trans2_fns); 132 data = buf+SVAL(words+1,12*2); 133 param = buf+SVAL(words+1,10*2); 134 pcnt = SVAL(words+1,9*2); 135 dcnt = SVAL(words+1,11*2); 136 } else { 137 data = buf+SVAL(words+1,7*2); 138 param = buf+SVAL(words+1,4*2); 139 pcnt = SVAL(words+1,3*2); 140 dcnt = SVAL(words+1,6*2); 141 } 142 143 printf("%s paramlen %d datalen %d ", 144 fn->name,pcnt,dcnt); 145 146 if (request) { 147 if (CVAL(words,0) == 8) { 148 fdata(words+1,"trans2secondary totparam [d] totdata [d] paramcnt [d] paramoff [d] paramdisp [d] datacnt [d] dataoff [d] datadisp [d] handle [d] ",maxbuf); 149 return; 150 } else { 151 fdata(words+1,"totparam [d] totdata [d] maxparam [d] maxdata [d] maxsetup [d] flags [w] timeout [D] res1 [w] paramcnt [d] paramoff [d] datacnt=[d] dataoff [d] setupcnt [d] ",words+1+14*2); 152 fdata(data+1,"transname [S] %",maxbuf); 153 } 154 f1 = fn->descript.req_f1; 155 f2 = fn->descript.req_f2; 156 } else { 157 if (CVAL(words,0) == 0) { 158 printf("trans2interim "); 159 return; 160 } else { 161 fdata(words+1,"totparam [d] totdata [d] res1 [w] paramcnt [d] paramoff [d] paramdisp [d] datacnt [d] dataoff [d] datadisp [d] setupcnt [d] ",words+1+10*2); 162 } 163 f1 = fn->descript.rep_f1; 164 f2 = fn->descript.rep_f2; 165 } 166 167 if (fn->descript.fn) { 168 fn->descript.fn(param,data,pcnt,dcnt); 169 } else { 170 fdata(param,f1?f1:(uchar*)"params ",param+pcnt); 171 fdata(data,f2?f2:(uchar*)"data ",data+dcnt); 172 } 173 } 174 175 176 static void print_browse(uchar *param,int paramlen,const uchar *data,int datalen) 177 { 178 const uchar *maxbuf = data + datalen; 179 int command = CVAL(data,0); 180 181 fdata(param,"browse |param ",param+paramlen); 182 183 switch (command) { 184 case 0xF: 185 data = fdata(data,"browse [B] (LocalMasterAnnouncement) updatecnt [w] res1 [B] announceintv [d] name [n2] version [B].[B] servertype [W] electionversion [w] browserconst [w] ",maxbuf); 186 break; 187 188 case 0x1: 189 data = fdata(data,"browse [B] (HostAnnouncement) updatecnt [w] res1 [B] announceintv [d] name [n2] version [B].[B] servertype [W] electionversion [w] browserconst [w] ",maxbuf); 190 break; 191 192 case 0x2: 193 data = fdata(data,"browse [B] (AnnouncementRequest) flags [B] replysysname [S] ",maxbuf); 194 break; 195 196 case 0xc: 197 data = fdata(data,"browse [B] (WorkgroupAnnouncement) updatecnt [w] res1 [B] announceintv [d] name [n2] version [B].[B] servertype [W] commentptr [W] servername [S] ",maxbuf); 198 break; 199 200 case 0x8: 201 data = fdata(data,"browse [B] (ElectionFrame) electionversion [B] ossummary [W] uptime [(W,W)] servername [S] ",maxbuf); 202 break; 203 204 case 0xb: 205 data = fdata(data,"browse [B] (BecomeBackupBrowser) name [S] ",maxbuf); 206 break; 207 208 case 0x9: 209 data = fdata(data,"browse [B] (GetBackupList) listcnt? [B] token? [B] ",maxbuf); 210 break; 211 212 case 0xa: 213 data = fdata(data,"browse [B] (BackupListResponse) servercnt? [B] token? [B] *name [S] ",maxbuf); 214 break; 215 216 case 0xd: 217 data = fdata(data,"browse [B] (MasterAnnouncement) master-name [S] ",maxbuf); 218 break; 219 220 case 0xe: 221 data = fdata(data,"browse [B] (ResetBrowser) options [B] ",maxbuf); 222 break; 223 224 default: 225 data = fdata(data,"browse unknown-frame",maxbuf); 226 break; 227 } 228 } 229 230 231 static void print_ipc(uchar *param,int paramlen,uchar *data,int datalen) 232 { 233 if (paramlen) 234 fdata(param,"cmd [w] str1 [S] str2 [S] ",param+paramlen); 235 if (datalen) 236 fdata(data,"IPC ",data+datalen); 237 } 238 239 240 static void print_trans(uchar *words,uchar *data1,uchar *buf,uchar *maxbuf) 241 { 242 uchar *f1,*f2,*f3,*f4; 243 uchar *data,*param; 244 int datalen,paramlen; 245 246 if (request) { 247 paramlen = SVAL(words+1,9*2); 248 param = buf + SVAL(words+1,10*2); 249 datalen = SVAL(words+1,11*2); 250 data = buf + SVAL(words+1,12*2); 251 f1 = " totparamcnt [d] totdatacnt [d] maxparmcnt [d] maxdatacnt [d] maxscnt [d] transflags [w] res [w] [w] [w] paramcnt [d] paramoff [d] datacnt [d] dataoff [d] sucnt [d] "; 252 f2 = "|[S] "; 253 f3 = "|param "; 254 f4 = "|data "; 255 } else { 256 paramlen = SVAL(words+1,3*2); 257 param = buf + SVAL(words+1,4*2); 258 datalen = SVAL(words+1,6*2); 259 data = buf + SVAL(words+1,7*2); 260 f1 = "totparamcnt [d] totdatacnt [d] res1 [d] paramcnt [d] paramoff [d] res2 [d] datacnt [d] dataoff [d] res3 [d] Lsetup [d] "; 261 f2 = "|unk "; 262 f3 = "|param "; 263 f4 = "|data "; 264 } 265 266 fdata(words+1,f1,MINIMUM(words+1+2*CVAL(words,0),maxbuf)); 267 fdata(data1+2,f2,maxbuf - (paramlen + datalen)); 268 269 if (!strcmp(data1+2,"\\MAILSLOT\\BROWSE")) { 270 print_browse(param,paramlen,data,datalen); 271 return; 272 } 273 274 if (!strcmp(data1+2,"\\PIPE\\LANMAN")) { 275 print_ipc(param,paramlen,data,datalen); 276 return; 277 } 278 279 if (paramlen) fdata(param,f3,MINIMUM(param+paramlen,maxbuf)); 280 if (datalen) fdata(data,f4,MINIMUM(data+datalen,maxbuf)); 281 } 282 283 284 285 static void print_negprot(uchar *words,uchar *data,uchar *buf,uchar *maxbuf) 286 { 287 uchar *f1=NULL,*f2=NULL; 288 289 if (request) { 290 f2 = "*|dialect [Z] "; 291 } else { 292 if (CVAL(words,0) == 1) { 293 f1 = "core-proto dialect index [d]"; 294 } else if (CVAL(words,0) == 17) { 295 f1 = "NT1-proto dialect index [d] secmode [B] maxmux [d] numvcs [d] maxbuf [D] rawsize [D] sesskey [W] capabilities [W] servertime [T3] tz [d] cryptkey "; 296 } else if (CVAL(words,0) == 13) { 297 f1 = "coreplus/lanman1/lanman2-proto dialect index [d] secmode [w] maxxmit [d] maxmux [d] maxvcs [d] blkmode [w] sesskey [W] servertime [T1] tz [d] res [W] cryptkey "; 298 } 299 } 300 301 if (f1) 302 fdata(words+1,f1,MINIMUM(words + 1 + CVAL(words,0)*2,maxbuf)); 303 304 if (f2) 305 fdata(data+2,f2,MINIMUM(data + 2 + SVAL(data,0),maxbuf)); 306 } 307 308 static void print_sesssetup(uchar *words,uchar *data,uchar *buf,uchar *maxbuf) 309 { 310 int wcnt = CVAL(words,0); 311 uchar *f1=NULL,*f2=NULL; 312 313 if (request) { 314 if (wcnt==10) { 315 f1 = "com2 [w] off2 [d] bufsize [d] maxmpx [d] vcnum [d] sesskey [W] passlen [d] cryptlen [d] cryptoff [d] pass&name "; 316 } else { 317 f1 = "com2 [B] res1 [B] off2 [d] maxbuf [d] maxmpx [d] vcnum [d] sesskey [W] case-insensitive-passlen [d] case-sensitive-passlen [d] res [W] capabilities [W] pass1&pass2&account&domain&os&lanman "; 318 } 319 } else { 320 if (CVAL(words,0) == 3) { 321 f1 = "com2 [w] off2 [d] action [w] "; 322 } else if (CVAL(words,0) == 13) { 323 f1 = "com2 [B] res [B] off2 [d] action [w] "; 324 f2 = "native-os [S] nativelanman [S] primarydomain [S] "; 325 } 326 } 327 328 if (f1) 329 fdata(words+1,f1,MINIMUM(words + 1 + CVAL(words,0)*2,maxbuf)); 330 331 if (f2) 332 fdata(data+2,f2,MINIMUM(data + 2 + SVAL(data,0),maxbuf)); 333 } 334 335 336 static struct smbfns smb_fns[] = 337 { 338 {-1,"SMBunknown",0,DEFDESCRIPT}, 339 340 {SMBtcon,"SMBtcon",0, 341 {NULL,"path [Z] pass [Z] dev [Z] ", "xmitmax [d] treeid [d] ",NULL, NULL}}, 342 343 344 {SMBtdis,"SMBtdis",0,DEFDESCRIPT}, 345 {SMBexit,"SMBexit",0,DEFDESCRIPT}, 346 {SMBioctl,"SMBioctl",0,DEFDESCRIPT}, 347 348 {SMBecho,"SMBecho",0, 349 {"reverbcount [d] ",NULL, "seqnum [d] ",NULL, NULL}}, 350 351 {SMBulogoffX, "SMBulogoffX",FLG_CHAIN,DEFDESCRIPT}, 352 353 {SMBgetatr,"SMBgetatr",0, {NULL,"path [Z] ", 354 "attr [A] time [T2] size [D] res ([w,w,w,w,w]) ",NULL, NULL}}, 355 356 {SMBsetatr,"SMBsetatr",0, 357 {"attr [A] time [T2] res ([w,w,w,w,w]) ","path [Z] ", NULL,NULL,NULL}}, 358 359 {SMBchkpth,"SMBchkpth",0, {NULL,"path [Z] ",NULL,NULL,NULL}}, 360 361 {SMBsearch,"SMBsearch",0, 362 {"cnt [d] attr [A] ","path [Z] blktype [B] blklen [d] |res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] res2 [W] ", 363 "cnt [d] ","blktype [B] blklen [d] * res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] res2 [W] attr [a] time [T1] size [D] name [s13] ",NULL}}, 364 365 {SMBopen,"SMBopen",0, {"mode [w] attr [A] ","path [Z] ", "handle [d] oattr [A] time [T2] size [D] access [w] ",NULL, NULL}}, 366 367 {SMBcreate,"SMBcreate",0, {"attr [A] time [T2]","path [Z] ", "handle [d]",NULL, NULL}}, 368 369 {SMBmknew,"SMBmknew",0, {"attr [A] time [T2]","path [Z] ", "handle [d] ",NULL, NULL}}, 370 371 {SMBunlink,"SMBunlink",0, {"attr [A] ","path [Z] ",NULL,NULL,NULL}}, 372 373 {SMBread,"SMBread",0, {"handle [d] bytecnt [d] offset [D] cntleft [d] ",NULL, "cnt [d] res ([w,w,w,w]) ",NULL,NULL}}, 374 375 {SMBwrite,"SMBwrite",0, {"handle [d] bytecnt [d] offset [D] cntleft [d] ",NULL, "cnt [d] ",NULL,NULL}}, 376 377 {SMBclose,"SMBclose",0, {"handle [d] time [T2]",NULL,NULL,NULL,NULL}}, 378 379 {SMBmkdir,"SMBmkdir",0, {NULL,"path [Z] ",NULL,NULL,NULL}}, 380 381 {SMBrmdir,"SMBrmdir",0, {NULL,"path [Z] ",NULL,NULL,NULL}}, 382 383 {SMBdskattr,"SMBdskattr",0, {NULL,NULL, "totalunits [d] blks/unit [d] blksize [d] freeunits [d] media [w] ", NULL,NULL}}, 384 385 {SMBmv,"SMBmv",0, {"attr [A] ","oldpath [Z] newpath [Z] ",NULL,NULL,NULL}}, 386 387 /* this is a Pathworks specific call, allowing the 388 changing of the root path */ 389 {pSETDIR,"SMBsetdir",0, {NULL,"path [Z] ",NULL,NULL,NULL}}, 390 391 {SMBlseek,"SMBlseek",0, {"handle [d] mode [w] offset [D] ","offset [D] ",NULL,NULL}}, 392 393 {SMBflush,"SMBflush",0, {"handle [d] ",NULL,NULL,NULL,NULL}}, 394 395 {SMBsplopen,"SMBsplopen",0, {"setuplen [d] mode [w] ","ident [Z] ","handle [d] ",NULL,NULL}}, 396 397 {SMBsplclose,"SMBsplclose",0, {"handle [d] ",NULL,NULL,NULL,NULL}}, 398 399 {SMBsplretq,"SMBsplretq",0, {"maxcnt [d] startindex [d] ",NULL, "cnt [d] index [d] ", "*time [T2] status [B] jobid [d] size [D] res [B] name [s16] ", NULL}}, 400 401 {SMBsplwr,"SMBsplwr",0, {"handle [d] ",NULL,NULL,NULL,NULL}}, 402 403 {SMBlock,"SMBlock",0, {"handle [d] count [D] offset [D] ",NULL,NULL,NULL,NULL}}, 404 405 {SMBunlock,"SMBunlock",0, {"handle [d] count [D] offset [D] ",NULL,NULL,NULL,NULL}}, 406 407 /* CORE+ PROTOCOL FOLLOWS */ 408 409 {SMBreadbraw,"SMBreadbraw",0, {"handle [d] offset [D] maxcnt [d] mincnt [d] timeout [D] res [d] ", NULL,NULL,NULL,NULL}}, 410 411 {SMBwritebraw,"SMBwritebraw",0, {"handle [d] totalcnt [d] res [w] offset [D] timeout [D] wmode [w] res2 [W] |datasize [d] dataoff [d] ", NULL,"write-raw-ack",NULL,NULL}}, 412 413 {SMBwritec,"SMBwritec",0, {NULL,NULL,"count [d] ",NULL,NULL}}, 414 415 {SMBwriteclose,"SMBwriteclose",0, {"handle [d] count [d] offset [D] time [T2] res ([w,w,w,w,w,w])",NULL, "count [d] ",NULL,NULL}}, 416 417 {SMBlockread,"SMBlockread",0, {"handle [d] bytecnt [d] offset [D] cntleft [d] ",NULL, "count [d] res ([w,w,w,w]) ",NULL,NULL}}, 418 419 {SMBwriteunlock,"SMBwriteunlock",0, {"handle [d] bytecnt [d] offset [D] cntleft [d] ",NULL, "count [d] ",NULL,NULL}}, 420 421 {SMBreadBmpx,"SMBreadBmpx",0, {"handle [d] offset [D] maxcnt [d] mincnt [d] timeout [D] res [w] ", NULL, "offset [D] totcnt [d] remain [d] res ([w,w]) datasize [d] dataoff [d] ", NULL,NULL}}, 422 423 {SMBwriteBmpx,"SMBwriteBmpx",0, {"handle [d] totcnt [d] res [w] offset [D] timeout [D] wmode [w] res2 [W] datasize [d] dataoff [d] ",NULL, "remain [d] ",NULL,NULL}}, 424 425 {SMBwriteBs,"SMBwriteBs",0, {"handle [d] totcnt [d] offset [D] res [W] datasize [d] dataoff [d] ",NULL, "count [d] ",NULL,NULL}}, 426 427 {SMBsetattrE,"SMBsetattrE",0, {"handle [d] ctime [T2] atime [T2] mtime [T2]",NULL, NULL,NULL,NULL}}, 428 429 {SMBgetattrE,"SMBgetattrE",0, {"handle [d] ",NULL, "ctime [T2] atime [T2] mtime [T2] size [D] allocsize [D] attr [A] ",NULL,NULL}}, 430 431 {SMBtranss,"SMBtranss",0,DEFDESCRIPT}, 432 {SMBioctls,"SMBioctls",0,DEFDESCRIPT}, 433 434 {SMBcopy,"SMBcopy",0, {"treeid2 [d] ofun [w] flags [w] ","path [S] newpath [S] ", "copycnt [d] ","|errstr [S] ",NULL}}, 435 436 {SMBmove,"SMBmove",0, {"treeid2 [d] ofun [w] flags [w] ","path [S] newpath [S] ", "movecnt [d] ","|errstr [S] ",NULL}}, 437 438 {SMBopenX,"SMBopenX",FLG_CHAIN, {"com2 [w] off2 [d] flags [w] mode [w] searchattr [A] attr [A] time [T2] ofun [w] size [D] timeout [D] res [W] ","path [S] ", "com2 [w] off2 [d] handle [d] attr [A] time [T2] size [D] access [w] type [w] state [w] action [w] fileid [W] res [w] ",NULL,NULL}}, 439 440 {SMBreadX,"SMBreadX",FLG_CHAIN, {"com2 [w] off2 [d] handle [d] offset [D] maxcnt [d] mincnt [d] timeout [D] cntleft [d] ",NULL, "com2 [w] off2 [d] remain [d] res [W] datasize [d] dataoff [d] res ([w,w,w,w]) ",NULL,NULL}}, 441 442 {SMBwriteX,"SMBwriteX",FLG_CHAIN, {"com2 [w] off2 [d] handle [d] offset [D] timeout [D] wmode [w] cntleft [d] res [w] datasize [d] dataoff [d] ",NULL, "com2 [w] off2 [d] count [d] remain [d] res [W] ",NULL,NULL}}, 443 444 {SMBlockingX,"SMBlockingX",FLG_CHAIN, {"com2 [w] off2 [d] handle [d] locktype [w] timeout [D] unlockcnt [d] lockcnt [d] ", "*process [d] offset [D] len [D] ", "com2 [w] off2 [d] "}}, 445 446 {SMBffirst,"SMBffirst",0, {"count [d] attr [A] ","path [Z] blktype [B] blklen [d] |res1 [B] mask [s11] srv2 [B] dirindex [d] srv2 [w] ", "count [d] ","blktype [B] blklen [d] * res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] res2 [W] attr [a] time [T1] size [D] name [s13] ",NULL}}, 447 448 {SMBfunique,"SMBfunique",0, {"count [d] attr [A] ","path [Z] blktype [B] blklen [d] |res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] ", "count [d] ","blktype [B] blklen [d] * res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] res2 [W] attr [a] time [T1] size [D] name [s13] ",NULL}}, 449 450 {SMBfclose,"SMBfclose",0, {"count [d] attr [A] ","path [Z] blktype [B] blklen [d] |res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] ", "count [d] ","blktype [B] blklen [d] * res1 [B] mask [s11] srv1 [B] dirindex [d] srv2 [w] res2 [W] attr [a] time [T1] size [D] name [s13] ",NULL}}, 451 452 {SMBfindnclose, "SMBfindnclose", 0, {"handle [d] ",NULL,NULL,NULL,NULL}}, 453 454 {SMBfindclose, "SMBfindclose", 0, {"handle [d] ",NULL,NULL,NULL,NULL}}, 455 456 {SMBsends,"SMBsends",0, {NULL,"src [Z] dst [Z] ",NULL,NULL,NULL}}, 457 458 {SMBsendstrt,"SMBsendstrt",0, {NULL,"src [Z] dst [Z] ","groupid [d] ",NULL,NULL}}, 459 460 {SMBsendend,"SMBsendend",0, {"groupid [d] ",NULL,NULL,NULL,NULL}}, 461 462 {SMBsendtxt,"SMBsendtxt",0, {"groupid [d] ",NULL,NULL,NULL,NULL}}, 463 464 {SMBsendb,"SMBsendb",0, {NULL,"src [Z] dst [Z] ",NULL,NULL,NULL}}, 465 466 {SMBfwdname,"SMBfwdname",0,DEFDESCRIPT}, 467 {SMBcancelf,"SMBcancelf",0,DEFDESCRIPT}, 468 {SMBgetmac,"SMBgetmac",0,DEFDESCRIPT}, 469 470 {SMBnegprot,"SMBnegprot",0, {NULL,NULL,NULL,NULL,print_negprot}}, 471 472 {SMBsesssetupX,"SMBsesssetupX",FLG_CHAIN,{NULL,NULL,NULL,NULL,print_sesssetup}}, 473 474 {SMBtconX,"SMBtconX",FLG_CHAIN, {"com2 [w] off2 [d] flags [w] passlen [d] passwd&path&dev ",NULL, "com2 [w] off2 [d] ","servicetype [S] ",NULL}}, 475 476 {SMBtrans2, "SMBtrans2",0,{NULL,NULL,NULL,NULL,print_trans2}}, 477 478 {SMBtranss2, "SMBtranss2", 0,DEFDESCRIPT}, 479 {SMBctemp,"SMBctemp",0,DEFDESCRIPT}, 480 {SMBreadBs,"SMBreadBs",0,DEFDESCRIPT}, 481 {SMBtrans,"SMBtrans",0,{NULL,NULL,NULL,NULL,print_trans}}, 482 483 {SMBnttrans,"SMBnttrans", 0, DEFDESCRIPT}, 484 {SMBnttranss,"SMBnttranss", 0, DEFDESCRIPT}, 485 486 {SMBntcreateX,"SMBntcreateX", FLG_CHAIN, {"com2 [w] off2 [d] res [b] namelen [d] flags [W] rootdirfid [D] accessmask [W] allocsize [L] extfileattr [W] shareaccess [W] createdisposition [W] createopts [W] impersonallevel [W] securityflags [b] ","path [S] ", "com2 [w] off2 [d] oplocklvl [b] fid [d] createaction [W] createtime [T3] lastaccesstime [T3] lastwritetime [T3] ctime [T3]extfileattr [W] allocsize [L] eof [L] filetype [w] devstate [w] dir [b] ", NULL}}, 487 488 {SMBntcancel,"SMBntcancel", 0, DEFDESCRIPT}, 489 490 {-1,NULL,0,DEFDESCRIPT}}; 491 492 493 /******************************************************************* 494 print a SMB message 495 ********************************************************************/ 496 static void print_smb(const uchar *buf, const uchar *maxbuf) 497 { 498 int command; 499 const uchar *words, *data; 500 struct smbfns *fn; 501 char *fmt_smbheader = 502 "[P4] cmd [B] error [BP1]/[d] flags [B] [B][P13] treeid [d] procid [d] uid [d] mid [d] wordcnt [b] "; 503 504 request = (CVAL(buf,9)&0x80)?0:1; 505 506 command = CVAL(buf,4); 507 508 fn = smbfind(command,smb_fns); 509 510 printf("%s-%s",fn->name,request?"request":"reply"); 511 512 if (vflag == 0) return; 513 514 /* print out the header */ 515 fdata(buf,fmt_smbheader,buf+33); 516 517 if (CVAL(buf,5)) { 518 int class = CVAL(buf,5); 519 int num = SVAL(buf,7); 520 printf("SMBError %s ",smb_errstr(class,num)); 521 } 522 523 words = buf+32; 524 data = words + 1 + CVAL(words,0)*2; 525 526 527 while (words && data) 528 { 529 char *f1,*f2; 530 int wct = CVAL(words,0); 531 532 if (request) { 533 f1 = fn->descript.req_f1; 534 f2 = fn->descript.req_f2; 535 } else { 536 f1 = fn->descript.rep_f1; 537 f2 = fn->descript.rep_f2; 538 } 539 540 if (fn->descript.fn) { 541 fn->descript.fn(words,data,buf,maxbuf); 542 } else { 543 if (f1) { 544 printf("smbvwv[]="); 545 fdata(words+1,f1,words + 1 + wct*2); 546 } else if (wct) { 547 int i; 548 int v; 549 printf("smbvwv[]="); 550 for (i=0;i<wct;i++) { 551 v = SVAL(words+1,2*i); 552 printf("smb_vwv[%d]=%d (0x%X) ",i,v,v); 553 } 554 } 555 556 if (f2) { 557 printf("smbbuf[]="); 558 fdata(data+2,f2,maxbuf); 559 } else { 560 int bcc = SVAL(data,0); 561 printf("smb_bcc=%d",bcc); 562 } 563 } 564 565 if ((fn->flags & FLG_CHAIN) && CVAL(words,0) && SVAL(words,1)!=0xFF) { 566 command = SVAL(words,1); 567 words = buf + SVAL(words,3); 568 data = words + 1 + CVAL(words,0)*2; 569 570 fn = smbfind(command,smb_fns); 571 572 printf("chained-%s-%s ",fn->name,request?"request":"reply"); 573 } else { 574 words = data = NULL; 575 } 576 } 577 } 578 579 580 /* 581 print a NBT packet received across tcp on port 139 582 */ 583 void nbt_tcp_print(const uchar *data,int length) 584 { 585 const uchar *maxbuf = data + length; 586 int flags = CVAL(data,0); 587 int nbt_len = RSVAL(data,2); 588 589 startbuf = data; 590 if (maxbuf <= data) return; 591 592 printf(": nbt "); 593 594 switch (flags) { 595 case 1: 596 printf("flags 0x%x ", flags); 597 case 0: 598 data = fdata(data,"session flags [rw] len [rd] ",data+4); 599 if (data == NULL) 600 break; 601 if (memcmp(data,"\377SMB",4)==0) { 602 if (nbt_len>PTR_DIFF(maxbuf,data)) 603 printf("[|nbt]"); 604 print_smb(data,maxbuf>data+nbt_len?data+nbt_len:maxbuf); 605 } else { 606 printf("session packet :(raw data?) "); 607 } 608 break; 609 610 case 0x81: 611 data = fdata(data,"session-request flags [rW] dst [n1] src [n1] ",maxbuf); 612 break; 613 614 case 0x82: 615 data = fdata(data,"sessionr-granted flags [rW] ",maxbuf); 616 break; 617 618 case 0x83: 619 { 620 int ecode = CVAL(data,4); 621 data = fdata(data,"session-reject flags [rW] reason [B] ",maxbuf); 622 switch (ecode) { 623 case 0x80: 624 printf("(Not listening on called name) "); 625 break; 626 case 0x81: 627 printf("(Not listening for calling name) "); 628 break; 629 case 0x82: 630 printf("(Called name not present) "); 631 break; 632 case 0x83: 633 printf("(Insufficient resources) "); 634 break; 635 default: 636 printf("(Unspecified error 0x%X) ",ecode); 637 break; 638 } 639 } 640 break; 641 642 case 0x85: 643 data = fdata(data,"keepalive flags [rW] ",maxbuf); 644 break; 645 646 default: 647 printf("flags=0x%x ", flags); 648 data = fdata(data,"unknown packet type [rW] ",maxbuf); 649 } 650 fflush(stdout); 651 } 652 653 654 /* 655 print a NBT packet received across udp on port 137 656 */ 657 void nbt_udp137_print(const uchar *data, int length) 658 { 659 const uchar *maxbuf = data + length; 660 int name_trn_id = RSVAL(data,0); 661 int response = (CVAL(data,2)>>7); 662 int opcode = (CVAL(data,2) >> 3) & 0xF; 663 int nm_flags = ((CVAL(data,2) & 0x7) << 4) + (CVAL(data,3)>>4); 664 int rcode = CVAL(data,3) & 0xF; 665 int qdcount = RSVAL(data,4); 666 int ancount = RSVAL(data,6); 667 int nscount = RSVAL(data,8); 668 int arcount = RSVAL(data,10); 669 char *opcodestr; 670 const char *p; 671 672 startbuf = data; 673 674 if (maxbuf <= data) return; 675 676 switch (opcode) { 677 case 0: opcodestr = "query"; break; 678 case 5: opcodestr = "registration"; break; 679 case 6: opcodestr = "release"; break; 680 case 7: opcodestr = "wack"; break; 681 case 8: opcodestr = "refresh(8)"; break; 682 case 9: opcodestr = "refresh"; break; 683 default: opcodestr = "unknown"; break; 684 } 685 printf("nbt-%s", opcodestr); 686 if (response) { 687 if (rcode) 688 printf("-negative"); 689 else 690 printf("-positive"); 691 printf("-resp"); 692 } else 693 printf("-req"); 694 695 if (nm_flags&1) 696 printf("-bcast"); 697 698 if (vflag == 0) return; 699 700 printf(" transid 0x%X opcode %d nmflags 0x%X rcode %d querycnt %d answercnt %d authoritycnt %d addrreccnt %d ", name_trn_id,opcode,nm_flags,rcode,qdcount,ancount,nscount,arcount); 701 702 p = data + 12; 703 704 { 705 int total = ancount+nscount+arcount; 706 int i; 707 708 if (qdcount>100 || total>100) { 709 printf("(corrupt packet?) "); 710 return; 711 } 712 713 if (qdcount) { 714 printf("question: "); 715 for (i=0;i<qdcount;i++) 716 p = fdata(p,"|name [n1] type [rw] class [rw] #",maxbuf); 717 if (p == NULL) 718 return; 719 } 720 721 if (total) { 722 printf("rr: "); 723 for (i=0;i<total;i++) { 724 int rdlen; 725 int restype; 726 p = fdata(p,"name [n1] #",maxbuf); 727 if (p == NULL) 728 return; 729 restype = RSVAL(p,0); 730 p = fdata(p,"type [rw] class [rw] ttl [rD] ",p+8); 731 if (p == NULL) 732 return; 733 rdlen = RSVAL(p,0); 734 printf("len %d data ",rdlen); 735 p += 2; 736 if (rdlen == 6) { 737 p = fdata(p,"addrtype [rw] addr [b.b.b.b] ",p+rdlen); 738 if (p == NULL) 739 return; 740 } else { 741 if (restype == 0x21) { 742 int numnames = CVAL(p,0); 743 p = fdata(p,"numnames [B] ",p+1); 744 if (p == NULL) 745 return; 746 while (numnames--) { 747 p = fdata(p,"name [n2] #",maxbuf); 748 if (p[0] & 0x80) printf("<GROUP> "); 749 switch (p[0] & 0x60) { 750 case 0x00: printf("B "); break; 751 case 0x20: printf("P "); break; 752 case 0x40: printf("M "); break; 753 case 0x60: printf("_ "); break; 754 } 755 if (p[0] & 0x10) printf("<DEREGISTERING> "); 756 if (p[0] & 0x08) printf("<CONFLICT> "); 757 if (p[0] & 0x04) printf("<ACTIVE> "); 758 if (p[0] & 0x02) printf("<PERMANENT> "); 759 p += 2; 760 } 761 } else 762 p += rdlen; 763 } 764 } 765 } 766 } 767 768 if ((uchar*)p < maxbuf) { 769 fdata(p,"extra: ",maxbuf); 770 } 771 772 fflush(stdout); 773 } 774 775 776 777 /* 778 print a NBT packet received across udp on port 138 779 */ 780 void nbt_udp138_print(const uchar *data, int length) 781 { 782 const uchar *maxbuf = data + length; 783 startbuf = data; 784 if (maxbuf <= data) return; 785 786 /* EMF - figure out how to skip fields inside maxbuf easily, IP and PORT here are bloody redundant */ 787 data = fdata(data,"nbt res [rw] id [rw] ip [b.b.b.b] port [rd] len [rd] res2 [rw] srcname [n1] dstname [n1] #",maxbuf); 788 789 if (data != NULL) 790 print_smb(data,maxbuf); 791 792 fflush(stdout); 793 } 794 795 796 797 /* 798 print netbeui frames 799 */ 800 void netbeui_print(u_short control, const uchar *data, const uchar *maxbuf) 801 { 802 int len = SVAL(data,0); 803 int command = CVAL(data,4); 804 const uchar *data2 = data + len; 805 int is_truncated = 0; 806 807 if (data2 >= maxbuf) { 808 data2 = maxbuf; 809 is_truncated = 1; 810 } 811 812 startbuf = data; 813 814 printf("NetBeui type 0x%X ", control); 815 data = fdata(data,"len [d] signature [w] cmd [B] #",maxbuf); 816 if (data == NULL) 817 return; 818 819 switch (command) { 820 case 0xA: 821 data = fdata(data,"namequery [P1] sessnum [B] nametype [B][P2] respcorrelator [w] dst [n2] src [n2] ",data2); 822 break; 823 824 case 0x8: 825 data = fdata(data,"netbios dgram [P7] dst [n2] src [n2] ",data2); 826 break; 827 828 case 0xE: 829 data = fdata(data,"namerecognize [P1] data2 [w] xmitcorrelator [w] respcorrelator [w] dst [n2] src [n2] ",data2); 830 break; 831 832 case 0x19: 833 data = fdata(data,"sessinit data1 [B] data2 [w] xmitcorrelator [w] respcorrelator [w] remsessnum [B] lclsessnum [B] ",data2); 834 break; 835 836 case 0x17: 837 data = fdata(data,"sessconf data1 [B] data2 [w] xmitcorrelator [w] respcorrelator [w] remsessnum [B] lclsessnum [B] ",data2); 838 break; 839 840 case 0x16: 841 data = fdata(data,"netbios data only last flags [{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}] resyncindicator [w][P2] respcorrelator [w] remsessnum [B] lclsessnum [B] ",data2); 842 break; 843 844 case 0x14: 845 data = fdata(data,"netbios data ack [P3] xmitcorrelator [w][P2] remsessnum [B] lclsessnum [B] ",data2); 846 break; 847 848 case 0x18: 849 data = fdata(data,"end session [P1] data2 [w][P4] remsessnum [B] lclsessnum [B] ",data2); 850 break; 851 852 case 0x1f: 853 data = fdata(data,"session alive ",data2); 854 break; 855 856 default: 857 data = fdata(data,"unknown netbios command ",data2); 858 break; 859 } 860 if (data == NULL) 861 return; 862 863 if (is_truncated) { 864 /* data2 was past the end of the buffer */ 865 return; 866 } 867 868 if (memcmp(data2,"\377SMB",4)==0) { 869 print_smb(data2,maxbuf); 870 } else { 871 int i; 872 for (i=0;i<128;i++) { 873 if (&data2[i] >= maxbuf) 874 break; 875 if (memcmp(&data2[i],"\377SMB",4)==0) { 876 printf("smb @ %d", i); 877 print_smb(&data2[i],maxbuf); 878 break; 879 } 880 } 881 } 882 } 883 884 885 /* 886 print IPX-Netbios frames 887 */ 888 void ipx_netbios_print(const uchar *data, const uchar *maxbuf) 889 { 890 /* this is a hack till I work out how to parse the rest of the IPX stuff */ 891 int i; 892 startbuf = data; 893 for (i=0;i<128;i++) 894 if (memcmp(&data[i],"\377SMB",4)==0) { 895 fdata(data,"IPX ",&data[i]); 896 print_smb(&data[i],maxbuf); 897 fflush(stdout); 898 break; 899 } 900 if (i==128) 901 fdata(data,"unknown IPX ",maxbuf); 902 } 903