From: guy Date: Tue, 28 Dec 2004 22:29:44 +0000 (+0000) Subject: Correctly handle Unicode strings - skip padding to put them on a 2-byte X-Git-Tag: tcpdump-3.9.1~225 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/9ce2222dfe0350ab2535775a14e49139fc033f3d Correctly handle Unicode strings - skip padding to put them on a 2-byte boundary, and base the Unicode-vs-non-Unicode decision on the "strings are Unicode" bit in Flags2, except for those few strings that are always ASCII, rather than doing a heuristic check. Fix the padding in FindFirst2 requests. --- diff --git a/print-smb.c b/print-smb.c index 95bd8d3b..c7f5f688 100644 --- a/print-smb.c +++ b/print-smb.c @@ -12,7 +12,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.36 2004-12-28 20:38:27 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.37 2004-12-28 22:29:44 guy Exp $"; #endif #include @@ -25,6 +25,7 @@ static const char rcsid[] _U_ = #include "smb.h" static int request = 0; +static int unicodestr = 0; const u_char *startbuf = NULL; @@ -94,11 +95,11 @@ trans2_findfirst(const u_char *param, const u_char *data, int pcnt, int dcnt) const char *fmt; if (request) - fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP5]\nFile=[S]\n"; + fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n"; else fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n"; - smb_fdata(param, fmt, param + pcnt); + smb_fdata(param, fmt, param + pcnt, unicodestr); if (dcnt) { printf("data:\n"); print_data(data, dcnt); @@ -115,7 +116,7 @@ trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt) TCHECK2(*param, 2); level = EXTRACT_LE_16BITS(param); fmt = "InfoLevel=[d]\n"; - smb_fdata(param, fmt, param + pcnt); + smb_fdata(param, fmt, param + pcnt, unicodestr); } else { switch (level) { case 1: @@ -131,7 +132,7 @@ trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt) fmt = "UnknownLevel\n"; break; } - smb_fdata(data, fmt, data + dcnt); + smb_fdata(data, fmt, data + dcnt, unicodestr); } if (dcnt) { printf("data:\n"); @@ -204,20 +205,20 @@ print_trans2(const u_char *words, const u_char *dat _U_, const u_char *buf, cons if (words[0] == 8) { smb_fdata(words + 1, "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n", - maxbuf); + maxbuf, unicodestr); return; } else { smb_fdata(words + 1, "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[d]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[d]\n", - words + 1 + 14 * 2); - smb_fdata(data + 1, "TransactionName=[S]\n%", maxbuf); + words + 1 + 14 * 2, unicodestr); + smb_fdata(data + 1, "TransactionName=[S]\n%", maxbuf, unicodestr); } f1 = fn->descript.req_f1; f2 = fn->descript.req_f2; } else { smb_fdata(words + 1, "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[d]\n", - words + 1 + 10 * 2); + words + 1 + 10 * 2, unicodestr); f1 = fn->descript.rep_f1; f2 = fn->descript.rep_f2; } @@ -225,8 +226,8 @@ print_trans2(const u_char *words, const u_char *dat _U_, const u_char *buf, cons if (fn->descript.fn) (*fn->descript.fn)(param, data, pcnt, dcnt); else { - smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt); - smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt); + smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr); + smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr); } return; trunc: @@ -244,70 +245,70 @@ print_browse(const u_char *param, int paramlen, const u_char *data, int datalen) TCHECK(data[0]); command = data[0]; - smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen); + smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr); switch (command) { case 0xF: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", - maxbuf); + maxbuf, unicodestr); break; case 0x1: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", - maxbuf); + maxbuf, unicodestr); break; case 0x2: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0xc: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0x8: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0xb: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0x9: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken?=[B]\n", - maxbuf); + maxbuf, unicodestr); break; case 0xa: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken?=[B]*Name=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0xd: data = smb_fdata(data, "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n", - maxbuf); + maxbuf, unicodestr); break; case 0xe: data = smb_fdata(data, - "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf); + "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr); break; default: - data = smb_fdata(data, "Unknown Browser Frame ", maxbuf); + data = smb_fdata(data, "Unknown Browser Frame ", maxbuf, unicodestr); break; } return; @@ -321,9 +322,10 @@ static void print_ipc(const u_char *param, int paramlen, const u_char *data, int datalen) { if (paramlen) - smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen); + smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen, + unicodestr); if (datalen) - smb_fdata(data, "IPC ", data + datalen); + smb_fdata(data, "IPC ", data + datalen, unicodestr); } @@ -358,13 +360,14 @@ print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u f4 = "|Data "; } - smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf)); + smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf), + unicodestr); TCHECK2(*data1, 2); bcc = EXTRACT_LE_16BITS(data1); printf("smb_bcc=%u\n", bcc); if (bcc > 0) { - smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen)); + smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr); if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) { print_browse(param, paramlen, data, datalen); @@ -377,9 +380,9 @@ print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u } if (paramlen) - smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf)); + smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf), unicodestr); if (datalen) - smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf)); + smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf), unicodestr); } return; trunc: @@ -397,7 +400,7 @@ print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, co TCHECK(words[0]); wct = words[0]; if (request) - f2 = "*|Dialect=[Z]\n"; + f2 = "*|Dialect=[Y]\n"; else { if (wct == 1) f1 = "Core Protocol\nDialectIndex=[d]"; @@ -408,7 +411,8 @@ print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, co } if (f1) - smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf)); + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); else print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); @@ -417,7 +421,8 @@ print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, co printf("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), maxbuf)); + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); else print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } @@ -450,7 +455,8 @@ print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, } if (f1) - smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf)); + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); else print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); @@ -459,7 +465,8 @@ print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, printf("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), maxbuf)); + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); else print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } @@ -491,14 +498,15 @@ print_lockingandx(const u_char *words, const u_char *data, const u_char *buf _U_ maxwords = SMBMIN(words + 1 + wct * 2, maxbuf); if (wct) - smb_fdata(words + 1, f1, maxwords); + smb_fdata(words + 1, f1, maxwords, unicodestr); TCHECK2(*data, 2); bcc = EXTRACT_LE_16BITS(data); printf("smb_bcc=%u\n", bcc); if (bcc > 0) { if (f2) - smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), maxbuf)); + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); else print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); } @@ -750,7 +758,7 @@ static struct smbfns smb_fns[] = { { SMBtconX, "SMBtconX", FLG_CHAIN, { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n", - NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[S]\n", NULL } }, + NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } }, { SMBlockingX, "SMBlockingX", FLG_CHAIN, { NULL, NULL, NULL, NULL, print_lockingandx } }, @@ -792,6 +800,8 @@ print_smb(const u_char *buf, const u_char *maxbuf) TCHECK(buf[9]); request = (buf[9] & 0x80) ? 0 : 1; + unicodestr = EXTRACT_LE_16BITS(&buf[10]) & 0x8000; + startbuf = buf; command = buf[4]; @@ -806,7 +816,7 @@ print_smb(const u_char *buf, const u_char *maxbuf) return; /* print out the header */ - smb_fdata(buf, fmt_smbheader, buf + 33); + smb_fdata(buf, fmt_smbheader, buf + 33, unicodestr); if (buf[5]) printf("SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7]))); @@ -838,7 +848,7 @@ print_smb(const u_char *buf, const u_char *maxbuf) else { if (wct) { if (f1) - smb_fdata(words + 1, f1, maxwords); + smb_fdata(words + 1, f1, words + 1 + wct * 2, unicodestr); else { int i; int v; @@ -856,7 +866,7 @@ print_smb(const u_char *buf, const u_char *maxbuf) printf("smb_bcc=%u\n", bcc); if (f2) { if (bcc > 0) - smb_fdata(data + 2, f2, data + 2 + bcc); + smb_fdata(data + 2, f2, data + 2 + bcc, unicodestr); } else { if (bcc > 0) { printf("smb_buf[]=\n"); @@ -961,7 +971,7 @@ nbt_tcp_print(const u_char *data, int length) break; default: - data = smb_fdata(data, "Unknown packet type [rB]", maxbuf); + data = smb_fdata(data, "Unknown packet type [rB]", maxbuf, 0); break; } } else { @@ -969,7 +979,7 @@ nbt_tcp_print(const u_char *data, int length) switch (type) { case 0x00: data = smb_fdata(data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n", - data + 4); + data + 4, 0); if (data == NULL) break; if (memcmp(data,"\377SMB",4) == 0) { @@ -984,11 +994,11 @@ nbt_tcp_print(const u_char *data, int length) case 0x81: data = smb_fdata(data, "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n", - maxbuf); + maxbuf, 0); break; case 0x82: - data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf); + data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); break; case 0x83: @@ -999,7 +1009,7 @@ nbt_tcp_print(const u_char *data, int length) ecode = data[4]; data = smb_fdata(data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n", - maxbuf); + maxbuf, 0); switch (ecode) { case 0x80: printf("Not listening on called name\n"); @@ -1021,11 +1031,11 @@ nbt_tcp_print(const u_char *data, int length) break; case 0x85: - data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf); + data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); break; default: - data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf); + data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0); break; } printf("\n"); @@ -1120,7 +1130,7 @@ nbt_udp137_print(const u_char *data, int length) for (i = 0; i < qdcount; i++) p = smb_fdata(p, "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#", - maxbuf); + maxbuf, 0); if (p == NULL) goto out; } @@ -1131,18 +1141,18 @@ nbt_udp137_print(const u_char *data, int length) int rdlen; int restype; - p = smb_fdata(p, "Name=[n1]\n#", maxbuf); + p = smb_fdata(p, "Name=[n1]\n#", maxbuf, 0); if (p == NULL) goto out; restype = EXTRACT_16BITS(p); - p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8); + p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0); if (p == NULL) goto out; rdlen = EXTRACT_16BITS(p); printf("ResourceLength=%d\nResourceData=\n", rdlen); p += 2; if (rdlen == 6) { - p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen); + p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0); if (p == NULL) goto out; } else { @@ -1151,11 +1161,11 @@ nbt_udp137_print(const u_char *data, int length) TCHECK(*p); numnames = p[0]; - p = smb_fdata(p, "NumNames=[B]\n", p + 1); + p = smb_fdata(p, "NumNames=[B]\n", p + 1, 0); if (p == NULL) goto out; while (numnames--) { - p = smb_fdata(p, "Name=[n2]\t#", maxbuf); + p = smb_fdata(p, "Name=[n2]\t#", maxbuf, 0); TCHECK(*p); if (p[0] & 0x80) printf(" "); @@ -1185,7 +1195,7 @@ nbt_udp137_print(const u_char *data, int length) } if (p < maxbuf) - smb_fdata(p, "AdditionalData:\n", maxbuf); + smb_fdata(p, "AdditionalData:\n", maxbuf, 0); out: printf("\n"); @@ -1219,7 +1229,7 @@ nbt_udp138_print(const u_char *data, int length) data = smb_fdata(data, "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#", - maxbuf); + maxbuf, 0); if (data != NULL) { /* If there isn't enough data for "\377SMB", don't check for it. */ @@ -1317,28 +1327,28 @@ netbeui_print(u_short control, const u_char *data, int length) if (vflag < 2) { printf("NBF Packet: "); - data = smb_fdata(data, "[P5]#", maxbuf); + data = smb_fdata(data, "[P5]#", maxbuf, 0); } else { printf("\n>>> NBF Packet\nType=0x%X ", control); - data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf); + data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0); } if (data == NULL) goto out; if (command > 0x1f || nbf_strings[command].name == NULL) { if (vflag < 2) - data = smb_fdata(data, "Unknown NBF Command#", data2); + data = smb_fdata(data, "Unknown NBF Command#", data2, 0); else - data = smb_fdata(data, "Unknown NBF Command\n", data2); + data = smb_fdata(data, "Unknown NBF Command\n", data2, 0); } else { if (vflag < 2) { printf("%s", nbf_strings[command].name); if (nbf_strings[command].nonverbose != NULL) - data = smb_fdata(data, nbf_strings[command].nonverbose, data2); + data = smb_fdata(data, nbf_strings[command].nonverbose, data2, 0); } else { printf("%s:\n", nbf_strings[command].name); if (nbf_strings[command].verbose != NULL) - data = smb_fdata(data, nbf_strings[command].verbose, data2); + data = smb_fdata(data, nbf_strings[command].verbose, data2, 0); else printf("\n"); } @@ -1410,7 +1420,7 @@ ipx_netbios_print(const u_char *data, u_int length) if (&data[i + 4] > maxbuf) break; if (memcmp(&data[i], "\377SMB", 4) == 0) { - smb_fdata(data, "\n>>> IPX transport ", &data[i]); + smb_fdata(data, "\n>>> IPX transport ", &data[i], 0); if (data != NULL) print_smb(&data[i], maxbuf); printf("\n"); @@ -1419,5 +1429,5 @@ ipx_netbios_print(const u_char *data, u_int length) } } if (i == 128) - smb_fdata(data, "\n>>> Unknown IPX ", maxbuf); + smb_fdata(data, "\n>>> Unknown IPX ", maxbuf, 0); } diff --git a/smb.h b/smb.h index eb25d14a..8eeb303f 100644 --- a/smb.h +++ b/smb.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/smb.h,v 1.8 2002-06-11 17:09:00 itojun Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/smb.h,v 1.9 2004-12-28 22:29:44 guy Exp $ (LBL) */ /* * Copyright (C) Andrew Tridgell 1995-1999 * @@ -119,4 +119,4 @@ #define PTR_DIFF(p1, p2) ((size_t)(((char *)(p1)) - (char *)(p2))) /* some protos */ -const u_char *smb_fdata(const u_char *, const char *, const u_char *); +const u_char *smb_fdata(const u_char *, const char *, const u_char *, int); diff --git a/smbutil.c b/smbutil.c index cb4c8b53..14e600a5 100644 --- a/smbutil.c +++ b/smbutil.c @@ -12,7 +12,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.31 2004-12-28 20:38:27 guy Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.32 2004-12-28 22:29:45 guy Exp $"; #endif #include @@ -329,26 +329,22 @@ write_bits(unsigned int val, const char *fmt) /* convert a UCS2 string into iso-8859-1 string */ static const char * -unistr(const u_char *s, int *len) +unistr(const u_char *s, int *len, int use_unicode) { static char buf[1000]; int l=0; - static int use_unicode = -1; - - if (use_unicode == -1) { - char *p = getenv("USE_UNICODE"); - if (p && (atoi(p) == 1)) - use_unicode = 1; - else - use_unicode = 0; - } - /* maybe it isn't unicode - a cheap trick */ - if (!use_unicode || (s[0] && s[1])) { + if (!use_unicode) { *len = strlen((const char *)s) + 1; return (const char *)s; } + /* + * Skip padding that puts the string on an even boundary. + */ + if (((s - startbuf) % 2) != 0) + s++; + *len = 0; if (s[0] == 0 && s[1] != 0) { @@ -368,7 +364,8 @@ unistr(const u_char *s, int *len) } static const u_char * -smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf) +smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) { int reverse = 0; const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|"; @@ -513,20 +510,23 @@ smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf) break; } case 'S': + case 'R': /* like 'S', but always ASCII */ { /*XXX unistr() */ - printf("%.*s", (int)PTR_DIFF(maxbuf, buf), unistr(buf, &len)); + printf("%.*s", (int)PTR_DIFF(maxbuf, buf), + unistr(buf, &len, (*fmt == 'R') ? 0 : unicodestr)); buf += len; fmt++; break; } case 'Z': + case 'Y': /* like 'Z', but always ASCII */ { if (*buf != 4 && *buf != 2) printf("Error! ASCIIZ buffer of type %u (safety=%lu)\n", *buf, (unsigned long)PTR_DIFF(maxbuf, buf)); printf("%.*s", (int)PTR_DIFF(maxbuf, buf + 1), - unistr(buf + 1, &len)); + unistr(buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr)); buf += len + 1; fmt++; break; @@ -644,7 +644,8 @@ trunc: } const u_char * -smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf) +smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) { static int depth = 0; char s[128]; @@ -657,7 +658,7 @@ smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf) while (buf < maxbuf) { const u_char *buf2; depth++; - buf2 = smb_fdata(buf, fmt, maxbuf); + buf2 = smb_fdata(buf, fmt, maxbuf, unicodestr); depth--; if (buf2 == NULL) return(NULL); @@ -696,7 +697,7 @@ smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf) strncpy(s, fmt, p - fmt); s[p - fmt] = '\0'; fmt = p + 1; - buf = smb_fdata1(buf, s, maxbuf); + buf = smb_fdata1(buf, s, maxbuf, unicodestr); if (buf == NULL) return(NULL); break;