]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Correctly handle Unicode strings - skip padding to put them on a 2-byte
authorguy <guy>
Tue, 28 Dec 2004 22:29:44 +0000 (22:29 +0000)
committerguy <guy>
Tue, 28 Dec 2004 22:29:44 +0000 (22:29 +0000)
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.

print-smb.c
smb.h
smbutil.c

index 95bd8d3b3e9333dca0463369feca5b0ba2790b55..c7f5f688af9b904b8eaaf69d6e1bdc06b889dae5 100644 (file)
@@ -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 <tcpdump-stdinc.h>
@@ -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("<GROUP> ");
@@ -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 eb25d14a36417f9ff79b66448002999636809525..8eeb303f91a0572183535d6e8301b3a45f993f3a 100644 (file)
--- 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
  *
 #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);
index cb4c8b53bb6c022e3d0f9da3f4babef67a05db06..14e600a56cd526d9e66d2317707b43b8d192c914 100644 (file)
--- 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 <tcpdump-stdinc.h>
@@ -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;