Exemple #1
0
static guint64
tvb_get_guintX(tvbuff_t *tvb, const gint offset, const gint size, const guint encoding) {
    switch (size) {
        case 1:
            return tvb_get_guint8(tvb, offset);
        case 2:
            return tvb_get_guint16(tvb, offset, encoding);
        case 3:
            return tvb_get_guint24(tvb, offset, encoding);
        case 4:
            return tvb_get_guint32(tvb, offset, encoding);
        case 5:
            return tvb_get_guint40(tvb, offset, encoding);
        case 6:
            return tvb_get_guint48(tvb, offset, encoding);
        case 7:
            return tvb_get_guint56(tvb, offset, encoding);
        case 8:
            return tvb_get_guint64(tvb, offset, encoding);
    }

    return 0;
}
static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, mq_parm_t* p_mq_parm)
{
    gint offset = 0;
    gboolean bLittleEndian;

    bLittleEndian = ((p_mq_parm->mq_cur_ccsid.encod & MQ_MQENC_INTEGER_MASK) == MQ_MQENC_INTEGER_REVERSED) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;

    if (tvb_reported_length(tvb) >= 36)
    {
        gint iSizeMQCFH = 36;
        guint32 iCommand = tvb_get_guint32(tvb, offset + 12, bLittleEndian);

        if (tree)
        {
            proto_item *ti;
            proto_tree *mq_tree;
            proto_tree *mqroot_tree;
            char        sTmp[256];
            guint32     uCnt;
            guint32     uTyp;
            guint32     uCmd;
            guint32     uCC;
            guint32     uRC;

            uTyp = tvb_get_guint32(tvb, offset     , bLittleEndian);
            uCmd = tvb_get_guint32(tvb, offset + 12, bLittleEndian);
            uCC  = tvb_get_guint32(tvb, offset + 24, bLittleEndian);
            uRC  = tvb_get_guint32(tvb, offset + 28, bLittleEndian);
            uCnt = tvb_get_guint32(tvb, offset + 32, bLittleEndian);

            if (uCC || uRC)
            {
                g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d) CC(%d-%s) RC(%d-%s)",
                    MQ_TEXT_CFH,
                    uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"),
                    uCmd, val_to_str_ext_const(uCmd, GET_VALS_EXTP(mqcmd), "Unknown"),
                    uCnt,
                    uCC, val_to_str_const(uCC, GET_VALSV(mqcc), "Unknown"),
                    uRC, val_to_str_ext_const(uRC, GET_VALS_EXTP(mqrc), "Unknown"));
            }
            else
            {
                g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d)",
                    MQ_TEXT_CFH,
                    uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"),
                    uCmd, val_to_str_ext_const(uCmd, GET_VALS_EXTP(mqcmd), "Unknown"),
                    uCnt);
            }

            ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, ENC_NA);

            proto_item_append_text(ti, " (%s)", val_to_str_ext_const(iCommand, GET_VALS_EXTP(mqcmd), "Unknown (0x%02x)"));
            mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);

            mq_tree = proto_tree_add_subtree(mqroot_tree, tvb, offset, iSizeMQCFH, ett_mqpcf_cfh, NULL, sTmp);

            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type     , tvb, offset +  0, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length   , tvb, offset +  4, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version  , tvb, offset +  8, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command  , tvb, offset + 12, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control  , tvb, offset + 20, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason   , tvb, offset + 28, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian);
            dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian, TRUE);
        }
    }
}
void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree,
                        guint offset, guint32 uCount, guint bLittleEndian, gboolean bParse)
{
    guint32 u    = 0;
    guint32 tOfs = 0;
    guint32 uLenF;
    char    strPrm[256];
    guint32 uTyp;
    guint32 uLen = 0;
    guint32 uPrm;
    guint32 uCnt;
    guint32 uCCS;
    guint32 uSLn;
    guint32 uVal;
    guint64 uVal64;
    guint32 uDig;

    const char sMaxLst[] = " Max # of List reached. DECODE interrupted   (actual %u of %u)";
    const char sPrmLn0[] = " MQPrm[%3u] has a zero length. DECODE Failed (MQPrm Count: %u)";
    const char sMaxPrm[] = " Max # of Parm reached. DECODE interrupted   (actual %u of %u)";
    const char sPrmCnt[] = " Cnt=-1 and Length(%u) < 16. DECODE interrupted for elem %u";

    proto_item *ti   = NULL;
    proto_tree *tree = NULL;

    if (uCount == (guint32)-1)
    {
        guint32 xOfs = offset;

        uCnt = 0;
        while (tvb_reported_length_remaining(tvb, xOfs) >= 16)
        {
            uLen = tvb_get_guint32(tvb, xOfs + 4, bLittleEndian);
            if (uLen < 16)
            {
                proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_PrmCnt, tvb, xOfs, 16, sPrmCnt, uLen, uCnt);
                break;
            }
            uCnt++;
            xOfs += uLen;
        }
        uCount = uCnt;
    }

    uDig = dissect_mqpcf_getDigits(uCount);

    for (u = 0; u < uCount && u < mq_pcf_maxprm; u++)
    {
        tOfs = offset;
        uTyp = tvb_get_guint32(tvb, offset    , bLittleEndian);
        uLen = tvb_get_guint32(tvb, offset + 4, bLittleEndian);
        if (uLen == 0)
        {
            proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_prmln0, tvb, offset, 12, sPrmLn0, u+1, uCount);
            u = uCount;
            break;
        }
        uPrm = tvb_get_guint32(tvb, offset + 8, bLittleEndian);
        uLenF = 12;

        if (bParse)
            g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d-%-30.30s",
                "MQPrm", uDig, u+1,
                uTyp, val_to_str_ext_const(uTyp, GET_VALS_EXTP(PrmTyp), "      Unknown") + 6,
                uPrm, uPrm, val_to_str_ext_const(uPrm, GET_VALS_EXTP(PrmId), "Unknown"));
        else
            g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d",
                "XtraD", uDig, u+1,
                uTyp, val_to_str_ext_const(uTyp, GET_VALS_EXTP(PrmTyp), "      Unknown") + 6,
                uPrm, uPrm);

        switch (uTyp)
        {
        case MQ_MQCFT_NONE:
            break;
        case MQ_MQCFT_COMMAND:
            break;
        case MQ_MQCFT_RESPONSE:
            break;
        case MQ_MQCFT_INTEGER:
            {
                const guint8 *pVal = NULL;
                uVal = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                if (bParse)
                    pVal = dissect_mqpcf_parm_getintval(uPrm, uVal);

                if (pVal)
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                             "%s %8x-(%9d) %s", strPrm, uVal, uVal, pVal);
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                             "%s %8x-(%9d)", strPrm, uVal, uVal);
                }

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp, tvb, offset    , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen, tvb, offset + 4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian);

                dissect_mqpcf_parm_int(tvb, tree, offset+uLenF, uPrm, uVal, hf_mq_pcf_int, 0, 0, 0, bParse);
            }
            break;
        case MQ_MQCFT_STRING:
            {
                guint8 *sStr;

                uCCS = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8,
                    uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
                if (*sStr)
                    strip_trailing_blanks(sStr, uSLn);
                if (*sStr)
                    format_text_chr(sStr, strlen((const char *)sStr), '.');

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s", strPrm, sStr);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
            }
            break;
        case MQ_MQCFT_INTEGER_LIST:
            {
                guint32 u2;
                guint32 uDigit = 0;

                uCnt = tvb_get_guint32(tvb, offset+uLenF, bLittleEndian);
                uDigit = dissect_mqpcf_getDigits(uCnt);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, &ti, "%s Cnt(%d)", strPrm, uCnt);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp  , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen  , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);

                offset += uLenF+4;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    uVal = tvb_get_guint32(tvb, offset, bLittleEndian);
                    dissect_mqpcf_parm_int(tvb, tree, offset, uPrm, uVal, hf_mq_pcf_intlist, u2+1, uCnt, uDigit, bParse);
                    offset += 4;
                }
                if (u2 != uCnt)
                {
                    proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxInt, tvb, offset, (uCnt- u2) * 4, sMaxLst, u2, uCnt);
                }
            }
            break;
        case MQ_MQCFT_STRING_LIST:
            {
                guint32  u2;
                guint32  uDigit;
                guint8  *sStr;
                header_field_info *hfinfo;

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist);

                uCCS = tvb_get_guint32(tvb, offset + uLenF    , bLittleEndian);
                uCnt = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, uCnt);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount , tvb, offset + 16, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);

                uDigit = dissect_mqpcf_getDigits(uCnt);

                offset += uLenF+12;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
                        uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
                    if (*sStr)
                        strip_trailing_blanks(sStr, uSLn);
                    if (*sStr)
                        format_text_chr(sStr, strlen((const char *)sStr),  '.');

                    proto_tree_add_string_format(tree, hf_mq_pcf_stringlist, tvb, offset, uSLn, (const char *)sStr,
                        "%s[%*d]: %s", hfinfo->name, uDigit, u2+1, sStr);
                    offset += uSLn;
                }
                if (u2 != uCnt)
                {
                    proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxStr, tvb, offset,(uCnt - u2) * uSLn, sMaxLst, u2, uCnt);
                }
            }
            break;
        case MQ_MQCFT_EVENT:
            break;
        case MQ_MQCFT_USER:
            {
                tree = proto_tree_add_subtree(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, strPrm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + 8, uLen - 8, bLittleEndian);
            }
            break;
        case MQ_MQCFT_BYTE_STRING:
            {
                uSLn = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.');
                    guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.');
                    if (uSLn > 35)
                    {
                        tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                        "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE);
                    }
                    else
                    {
                        tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                        "%s A(%s) E(%s)", strPrm, sStrA, sStrE);
                    }
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s <MISSING>", strPrm);
                }

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 4 , uSLn, bLittleEndian);
            }
            break;
        case MQ_MQCFT_TRACE_ROUTE:
            break;
        case MQ_MQCFT_REPORT:
            break;
        case MQ_MQCFT_INTEGER_FILTER:
            {
                guint32 uOpe;

                uOpe = tvb_get_guint32(tvb, offset + uLenF    , bLittleEndian);
                uVal = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s %8x-(%9d)",
                    strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, uVal, uVal);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_int, tvb, offset + uLenF + 4, 4, bLittleEndian);
            }
            break;
        case MQ_MQCFT_STRING_FILTER:
            {
                guint8 *sStr;
                guint32 uOpe;

                uOpe = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                uCCS = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian);
                sStr = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC), uSLn, '.');
                strip_trailing_blanks(sStr, uSLn);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s %s",
                    strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, sStr);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 16, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
            }
            break;
        case MQ_MQCFT_BYTE_STRING_FILTER:
            {
                guint32 uOpe;
                uOpe = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_ASCII), uSLn, '.');
                    guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_EBCDIC), uSLn, '.');
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s A(%s) E(%s)",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, sStrA, sStrE);
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s <MISSING>",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7);
                }

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 8 , uSLn, bLittleEndian);
            }
            break;
        case MQ_MQCFT_COMMAND_XR:
            break;
        case MQ_MQCFT_XR_MSG:
            break;
        case MQ_MQCFT_XR_ITEM:
            break;
        case MQ_MQCFT_XR_SUMMARY:
            break;
        case MQ_MQCFT_GROUP:
            break;
        case MQ_MQCFT_STATISTICS:
            break;
        case MQ_MQCFT_ACCOUNTING:
            break;
        case MQ_MQCFT_INTEGER64:
            {
                uVal64 = tvb_get_guint64(tvb, offset + uLenF + 4, bLittleEndian);
                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                    "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)", strPrm, uVal64, uVal64);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmunused, tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_int64, tvb, offset + uLenF + 4, 8, bLittleEndian);
            }
            break;
        case MQ_MQCFT_INTEGER64_LIST:
            {
                guint32 u2;
                guint32 uDigit;
                header_field_info *hfinfo;

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list);

                uCnt = tvb_get_guint32(tvb, offset + uLenF, bLittleEndian);
                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, uCnt);
                uDigit = dissect_mqpcf_getDigits(uCnt);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp  , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen  , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);

                offset += uLenF + 4;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    uVal64 = tvb_get_guint64(tvb, offset, bLittleEndian);
                    proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64,
                        "%s[%*d]: %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)",
                        hfinfo->name, uDigit, u2+1, uVal64, uVal64);
                    offset += 8;
                }
                if (u2 != uCnt)
                {
                    proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxI64, tvb, offset, (uCnt - u2) * 8, sMaxLst, u2, uCnt);
                }
            }
            break;
        }
        offset = tOfs+uLen;
    }
    if (u != uCount)
    {
        proto_tree_add_expert_format(mq_tree, pinfo, &ei_mq_pcf_MaxPrm, tvb, offset, tvb_reported_length_remaining(tvb, offset), sMaxPrm, u, uCount);
    }
}
Exemple #4
0
void dissect_nvme_cmd_sgl(tvbuff_t *cmd_tvb, proto_tree *cmd_tree,
                          int field_index, struct nvme_cmd_ctx *cmd_ctx)
{
    proto_item *ti, *sgl_tree, *type_item, *sub_type_item;
    guint8 sgl_identifier, desc_type, desc_sub_type;
    int offset = 24;

    ti = proto_tree_add_item(cmd_tree, field_index, cmd_tvb, offset,
                             16, ENC_NA);
    sgl_tree = proto_item_add_subtree(ti, ett_data);

    sgl_identifier = tvb_get_guint8(cmd_tvb, offset + 15);
    desc_type = (sgl_identifier & 0xff) >> 4;
    desc_sub_type = sgl_identifier & 0x0f;

    type_item = proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_type,
                                    cmd_tvb, offset + 15, 1, ENC_LITTLE_ENDIAN);
    proto_item_append_text(type_item, " %s",
                           val_to_str(desc_type, sgl_type_tbl, "Reserved"));

    sub_type_item = proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_sub_type,
                                        cmd_tvb,
                                        offset + 15, 1, ENC_LITTLE_ENDIAN);
    proto_item_append_text(sub_type_item, " %s",
                           val_to_str(desc_sub_type, sgl_sub_type_tbl, "Reserved"));

    switch (desc_type) {
    case NVME_CMD_SGL_DATA_DESC:
    case NVME_CMD_SGL_LAST_SEGMENT_DESC:
    case NVME_CMD_SGL_SEGMENT_DESC:
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_addr, cmd_tvb,
                            offset, 8, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_len, cmd_tvb,
                            offset + 8, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_rsvd, cmd_tvb,
                            offset + 12, 3, ENC_NA);
        break;
    case NVME_CMD_SGL_BIT_BUCKET_DESC:
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_addr_rsvd, cmd_tvb,
                            offset, 8, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_len, cmd_tvb,
                            offset + 8, 4, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_rsvd, cmd_tvb,
                            offset + 12, 3, ENC_NA);
        break;
    case NVME_CMD_SGL_KEYED_DATA_DESC:
        if (cmd_ctx)
            cmd_ctx->remote_key = tvb_get_guint32(cmd_tvb, offset + 11,
                                                  ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_addr, cmd_tvb,
                            offset, 8, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_len, cmd_tvb,
                            offset + 8, 3, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(sgl_tree, hf_nvme_cmd_sgl_desc_key, cmd_tvb,
                            offset + 11, 4, ENC_LITTLE_ENDIAN);
        break;
    case NVME_CMD_SGL_VENDOR_DESC:
    default:
        break;
    }
}
static int
dissect_pcap_pktdata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    gint         offset = 0;
    guint32     *link_type;
    guint32      length = 0;
    tvbuff_t    *next_tvb;
    proto_item  *pseudoheader_item;
    proto_tree  *pseudoheader_tree = NULL;
    proto_item  *packet_item;
    proto_tree  *packet_tree;

    DISSECTOR_ASSERT(data);

    link_type = (guint32 *) data;
    pinfo->phdr->pkt_encap = wtap_pcap_encap_to_wtap_encap(*link_type);

    switch (*link_type) {
    case 139:
/* TODO no description for pseudoheader at http://www.tcpdump.org/linktypes.html */
        break;
    case 196:
        length = 5;
        break;
    case 197:
/* TODO no description for pseudoheader at http://www.tcpdump.org/linktypes.html */
        break;
    case 201:
        length = 4;
        break;
    case 204:
        length = 1;
        break;
    case 205:
        length = 1;
        break;
    case 206:
        length = 1;
        break;
    case 209:
        length = 6;
        break;
    case 226:
        length = 24;
        break;
    case 227:
/* TODO no description for pseudoheader at http://www.tcpdump.org/linktypes.html */
        break;
    case 240:
    case 241:
        length = 4;
        break;
    case 244:
        length = 20;
        break;
    case 245:
        length = 20;
        break;
    }

    if (length > 0) {
        pseudoheader_item = proto_tree_add_item(tree, hf_pcap_pktdata_pseudoheader, tvb, offset, length, ENC_NA);
        pseudoheader_tree = proto_item_add_subtree(pseudoheader_item, ett_pcap_pktdata_pseudoheader);
    }

    switch (*link_type) {
    case 201:
        proto_tree_add_item(pseudoheader_tree, hf_pcap_pktdata_pseudoheader_bluetooth_direction, tvb, offset, 4, ENC_BIG_ENDIAN);
        if (tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN) == 0)
            pinfo->p2p_dir = P2P_DIR_SENT;
        else if (tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN) == 1)
            pinfo->p2p_dir = P2P_DIR_RECV;
        else
            pinfo->p2p_dir = P2P_DIR_UNKNOWN;
        offset += 4;
        break;
    default:
        offset += length;
    }

    next_tvb = tvb_new_subset_remaining(tvb, offset);

    packet_item = proto_tree_add_item(tree, hf_pcap_pktdata_data, tvb, offset, tvb_reported_length(next_tvb), ENC_NA);
    packet_tree = proto_item_add_subtree(packet_item, ett_pcap_pktdata_data);

    offset = dissector_try_uint_new(wtap_encap_table, pinfo->phdr->pkt_encap, next_tvb, pinfo, packet_tree, TRUE, NULL);

    return offset;
}
Exemple #6
0
/* Process an APP1 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static int
process_app1_segment(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 len,
        guint16 marker, const char *marker_name, gboolean show_first_identifier_not_jfif)
{
    proto_item *ti;
    proto_tree *subtree;
    char *str;
    gint str_size;
    int offset = 0;
    int tiff_start;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    proto_tree_add_item(subtree, hf_len, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    str = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &str_size, ENC_ASCII);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, offset, str_size, ENC_ASCII|ENC_NA);
    offset += str_size;

    if (show_first_identifier_not_jfif && strcmp(str, "JFIF") != 0) {
        expert_add_info(pinfo, ti, &ei_file_jpeg_first_identifier_not_jfif);
    }

    if (strcmp(str, "Exif") == 0) {
        /*
         * Endianness
         */
        int encoding;
        guint16 val_16;
        guint32 val_32, num_fields;
        proto_item* tiff_item;

        offset++; /* Skip a byte supposed to be 0x00 */

        tiff_start = offset;
        val_16 = tvb_get_ntohs(tvb, offset);
        if (val_16 == 0x4949) {
            encoding = ENC_LITTLE_ENDIAN;
            proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16, "little endian");
        } else if (val_16 == 0x4D4D) {
            encoding = ENC_BIG_ENDIAN;
            proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16, "big endian");
        } else {
            /* Error: invalid endianness encoding */
            proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16,
                    "Incorrect encoding 0x%04x- skipping the remainder of this application marker", val_16);
            return offset;
        }
        offset += 2;
        /*
         * Fixed value 42 = 0x002a
         */
        offset += 2;
        /*
         * Offset to IFD
         */
        val_32 = tvb_get_guint32(tvb, offset, encoding);
        tiff_item = proto_tree_add_uint_format_value(subtree, hf_start_ifd_offset, tvb, offset, 4, val_32, "%u bytes",
            val_32);
        offset += 4;
        /*
         * Check for a bogus val_32 value.
         * XXX - bogus value message should also deal with a
         * value that's too large and causes an overflow.
         * Or should it just check against the segment length,
         * which is 16 bits?
         */
        if (val_32 + tiff_start < (guint32)offset) {
            expert_add_info_format(pinfo, tiff_item, &ei_start_ifd_offset, " (bogus, should be >= %u)",
                offset- tiff_start);
            return offset;
        }
        /*
         * Skip the following portion
         */
        if (val_32 + tiff_start > (guint32)offset) {
            proto_tree_add_bytes_format_value(subtree, hf_skipped_tiff_data, tvb, offset, val_32 + tiff_start - offset, NULL, "%u bytes",
                val_32 + tiff_start - offset);
        }
        for (;;) {
            offset = val_32 + tiff_start;
            /*
             * Process the IFD
             */
            proto_tree_add_item_ret_uint(subtree, hf_ifd_num_fields, tvb, offset, 2, encoding, &num_fields);
            offset += 2;
            while (num_fields-- > 0) {
                proto_tree_add_item(subtree, hf_idf_tag, tvb, offset, 2, encoding);
                offset += 2;
                proto_tree_add_item(subtree, hf_idf_type, tvb, offset, 2, encoding);
                offset += 2;
                proto_tree_add_item(subtree, hf_idf_count, tvb, offset, 4, encoding);
                offset += 4;
                proto_tree_add_item(subtree, hf_idf_offset, tvb, offset, 4, encoding);
                offset += 4;
            }
            /*
             * Offset to the next IFD
             */
            val_32 = tvb_get_guint32(tvb, offset, encoding);
            tiff_item = proto_tree_add_uint_format_value(subtree, hf_next_ifd_offset, tvb, offset, 4, val_32, "%u bytes",
                val_32);
            offset += 4;
            if (val_32 != 0 &&
                val_32 + tiff_start < (guint32)offset) {
                expert_add_info_format(pinfo, tiff_item, &ei_next_ifd_offset, " (bogus, should be >= %u)", offset + tiff_start);
                return offset;
            }
            if (val_32 == 0)
                break;
        }
    } else {
        proto_tree_add_bytes_format_value(subtree, hf_remain_seg_data, tvb, offset, -1, NULL, "%u bytes", len - 2 - str_size);
        proto_item_append_text(ti, " (Unknown identifier)");
    }
    return offset;
}