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); } }
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; }
/* 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; }