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