void proto_register_nflog(void) { #ifndef HAVE_HFI_SECTION_INIT static header_field_info *hfi[] = { /* Header */ &hfi_nflog_family, &hfi_nflog_version, &hfi_nflog_resid, /* TLV */ &hfi_nflog_tlv, &hfi_nflog_tlv_length, &hfi_nflog_tlv_type, /* TLV values */ &hfi_nflog_tlv_prefix, &hfi_nflog_tlv_uid, &hfi_nflog_tlv_gid, &hfi_nflog_tlv_timestamp, &hfi_nflog_tlv_unknown, }; #endif static gint *ett[] = { &ett_nflog, &ett_nflog_tlv }; module_t *pref; int proto_nflog; proto_nflog = proto_register_protocol("Linux Netfilter NFLOG", "NFLOG", "nflog"); hfi_nflog = proto_registrar_get_nth(proto_nflog); pref = prefs_register_protocol(proto_nflog, NULL); prefs_register_enum_preference(pref, "byte_order_type", "Byte Order", "Byte Order", &nflog_byte_order, byte_order_types, FALSE); register_dissector("nflog", dissect_nflog, proto_nflog); proto_register_fields(proto_nflog, hfi, array_length(hfi)); proto_register_subtree_array(ett, array_length(ett)); }
void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset,guint uPrm,guint uVal,int hfindex) { header_field_info *hfinfo; guint8 *pVal; pVal=dissect_mqpcf_parm_getintval(uPrm,uVal); hfinfo=proto_registrar_get_nth(hfindex); if (pVal) { proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%d-%s", hfinfo->name, uVal, pVal); } else { proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%8x-%d", hfinfo->name, uVal, uVal); } }
extern gboolean add_hfid(mate_config* mc, header_field_info* hfi, gchar* how, GHashTable* where) { header_field_info* first_hfi = NULL; gboolean exists = FALSE; gchar* as; gchar* h; int* ip; while(hfi) { first_hfi = hfi; hfi = (hfi->same_name_prev_id != -1) ? proto_registrar_get_nth(hfi->same_name_prev_id) : NULL; } hfi = first_hfi; while (hfi) { exists = TRUE; ip = (int *)g_malloc(sizeof(int)); *ip = hfi->id; if (( as = (gchar *)g_hash_table_lookup(where,ip) )) { g_free(ip); if (! g_str_equal(as,how)) { report_error(mc, "MATE Error: add field to Pdu: attempt to add %s(%i) as %s" " failed: field already added as '%s'",hfi->abbrev,hfi->id,how,as); return FALSE; } } else { h = g_strdup(how); g_hash_table_insert(where,ip,h); } hfi = hfi->same_name_next; } if (! exists) { report_error(mc, "MATE Error: cannot find field for attribute %s",how); } return exists; }
proto_item *add_tlv_subtree(tlv_info_t *self, proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, const guint encoding) { header_field_info *hf; proto_tree *tlv_tree; proto_item *tlv_item; gint tlv_value_length, tlv_val_offset; guint8 size_of_tlv_length_field; guint8 tlv_type; /* Make sure we're dealing with a valid TLV here */ if (get_tlv_type(self) < 0) return tree; /* Retrieve the necessary TLV information */ tlv_val_offset = get_tlv_value_offset(self); tlv_value_length = get_tlv_length(self); size_of_tlv_length_field = get_tlv_size_of_length(self); tlv_type = get_tlv_type(self); hf = proto_registrar_get_nth(hfindex); tlv_item = proto_tree_add_text(tree, tvb, start, tlv_value_length+tlv_val_offset, "%s", hf->name); tlv_tree = proto_item_add_subtree(tlv_item, ett_tlv[tlv_type]); proto_tree_add_uint(tlv_tree, hf_tlv_type, tvb, start, 1, tlv_type); if (size_of_tlv_length_field > 0) /* It is */ { /* display the length of the length field TLV */ proto_tree_add_uint(tlv_tree, hf_tlv_length_size, tvb, start+1, 1, size_of_tlv_length_field); /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+2, size_of_tlv_length_field, tlv_value_length); } else { /* It is not */ /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+1, 1, tlv_value_length); } tlv_item = proto_tree_add_item(tlv_tree, hfindex, tvb, start+tlv_val_offset, tlv_value_length, encoding); /* Return a pointer to the value level */ return tlv_item; }
void proto_register_rip(void) { #ifndef HAVE_HFI_SECTION_INIT static header_field_info *hfi[] = { &hfi_rip_command, &hfi_rip_version, &hfi_rip_family, &hfi_rip_routing_domain, &hfi_rip_ip, &hfi_rip_netmask, &hfi_rip_next_hop, &hfi_rip_metric, &hfi_rip_auth, &hfi_rip_auth_passwd, &hfi_rip_route_tag, }; #endif /* HAVE_HFI_SECTION_INIT */ static gint *ett[] = { &ett_rip, &ett_rip_vec, &ett_auth_vec, }; module_t *rip_module; int proto_rip; proto_rip = proto_register_protocol("Routing Information Protocol", "RIP", "rip"); hfi_rip = proto_registrar_get_nth(proto_rip); proto_register_fields(proto_rip, hfi, array_length(hfi)); proto_register_subtree_array(ett, array_length(ett)); rip_module = prefs_register_protocol(proto_rip, proto_reg_handoff_rip); prefs_register_bool_preference(rip_module, "display_routing_domain", "Display Routing Domain field", "Display the third and forth bytes of the RIPv2 header as the Routing Domain field (introduced in RFC 1388 [January 1993] and obsolete as of RFC 1723 [November 1994])", &pref_display_routing_domain); rip_handle = create_dissector_handle(dissect_rip, proto_rip); }
void proto_register_daytime(void) { static header_field_info *hfi[] = { &hfi_daytime_string, }; static gint *ett[] = { &ett_daytime, }; int proto_daytime; proto_daytime = proto_register_protocol("Daytime Protocol", "DAYTIME", "daytime"); hfi_daytime = proto_registrar_get_nth(proto_daytime); proto_register_fields(proto_daytime, hfi, array_length(hfi)); proto_register_subtree_array(ett, array_length(ett)); daytime_handle = create_dissector_handle(dissect_daytime, proto_daytime); }
static void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset, guint uPrm, guint uVal, int hfindex, guint iCnt, guint iMaxCnt, guint iDigit, gboolean bParse) { header_field_info *hfinfo; const guint8 *pVal = NULL; if (bParse) pVal = dissect_mqpcf_parm_getintval(uPrm, uVal); hfinfo = proto_registrar_get_nth(hfindex); if (iMaxCnt > 1) { if (pVal) { proto_tree_add_int_format(tree, hfindex, tvb, offset, 4, uVal, "%s[%*d]: %8x-(%9d)-%s", hfinfo->name, iDigit, iCnt, uVal, uVal, pVal); } else { proto_tree_add_int_format(tree, hfindex, tvb, offset, 4, uVal, "%s[%*d]: %8x-(%9d)", hfinfo->name, iDigit, iCnt, uVal, uVal); } } else { if (pVal) { proto_tree_add_int_format_value(tree, hfindex, tvb, offset, 4, uVal, "%8x-(%9d)-%s", uVal, uVal, pVal); } else { proto_tree_add_int_format_value(tree, hfindex, tvb, offset, 4, uVal, "%8x-(%9d)", uVal, uVal); } } }
void proto_register_redback(void) { #ifndef HAVE_HFI_SECTION_INIT static header_field_info *hfi[] = { &hfi_redback_context, &hfi_redback_flags, &hfi_redback_circuit, &hfi_redback_length, &hfi_redback_protocol, &hfi_redback_l3offset, &hfi_redback_dataoffset, &hfi_redback_padding, &hfi_redback_unknown, }; #endif static gint *ett[] = { &ett_redback }; static ei_register_info ei[] = { { &ei_redback_protocol, { "redback.protocol.unknown", PI_PROTOCOL, PI_WARN, "Unknown Protocol Data", EXPFILL }}, }; expert_module_t* expert_redback; int proto_redback; proto_redback = proto_register_protocol("Redback", "Redback", "redback"); hfi_redback = proto_registrar_get_nth(proto_redback); proto_register_fields(proto_redback, hfi, array_length(hfi)); proto_register_subtree_array(ett, array_length(ett)); expert_redback = expert_register_protocol(proto_redback); expert_register_field_array(expert_redback, ei, array_length(ei)); redback_handle = create_dissector_handle(dissect_redback, proto_redback); }
static int add_session_id(proto_tree *tree, int hf, int hf_str, tvbuff_t *tvb, int offset) { guint count; guint i; guint64 session_id; header_field_info *hfinfo; count = tvb_get_guint8(tvb, offset); if (count == 0) proto_tree_add_string (tree, hf_str, tvb, offset, count+1, "NULL"); else if (count <= 8) { session_id = 0; for (i = 0; i < count; i++) session_id = (session_id << 8) | tvb_get_guint8(tvb, offset + i); proto_tree_add_uint64 (tree, hf, tvb, offset, count+1, session_id); } else { hfinfo = proto_registrar_get_nth(hf); proto_tree_add_text (tree, tvb, offset, count+1, "%s: %s", hfinfo->name, tvb_bytes_to_str(tvb, offset+1, count)); } return offset+1+count; }
static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset) { /* Set up structures needed to add the param subtree and manage it */ proto_item *param_item; proto_tree *param_tree; gint offset; guint dcs; guint dcs_cg; /* coding group */ guint dcs_cf; /* compressed flag */ guint dcs_mcm; /* message class meaning flag */ guint dcs_chs; /* character set */ guint dcs_mc; /* message class */ guint dcs_is; /* indication sense */ guint dcs_it; /* indication type */ gchar* bigbuf = (gchar*)ep_alloc(1024); param_item = proto_tree_add_text(tree, tvb, startOffset + 1, endOffset - (startOffset + 1), "%s", cimd_vals_PC[pindex].strptr ); param_tree = proto_item_add_subtree(param_item, (*vals_hdr_PC[pindex].ett_p)); proto_tree_add_string(param_tree, hf_cimd_pcode_indicator, tvb, startOffset + 1, CIMD_PC_LENGTH, tvb_format_text(tvb, startOffset + 1, CIMD_PC_LENGTH) ); offset = startOffset + 1 + CIMD_PC_LENGTH + 1; dcs = decimal_int_value(tvb, offset, endOffset - offset); proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, offset, endOffset - offset, dcs); dcs_cg = (dcs & 0xF0) >> 4; other_decode_bitfield_value(bigbuf, dcs, (dcs_cg <= 0x07 ? 0xC0 : 0xF0), 8); proto_tree_add_uint_format(param_tree, hf_cimd_dcs_coding_group_indicator, tvb, offset, 1, dcs_cg, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_coding_group_indicator)->name, val_to_str(dcs_cg, cimd_dcs_coding_groups, "Unknown (%d)"), dcs_cg ); if (dcs_cg <= 0x07) { dcs_cf = (dcs & 0x20) >> 5; other_decode_bitfield_value(bigbuf, dcs, 0x20, 8); proto_tree_add_uint_format(param_tree, hf_cimd_dcs_compressed_indicator, tvb, offset, 1, dcs_cf, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_compressed_indicator)->name, val_to_str(dcs_cf, cimd_dcs_compressed, "Unknown (%d)"), dcs_cf ); dcs_mcm = (dcs & 0x10) >> 4; other_decode_bitfield_value(bigbuf, dcs, 0x10, 8); proto_tree_add_uint_format(param_tree, hf_cimd_dcs_message_class_meaning_indicator, tvb, offset, 1, dcs_mcm, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_message_class_meaning_indicator)->name, val_to_str(dcs_mcm, cimd_dcs_message_class_meaning, "Unknown (%d)"), dcs_mcm ); dcs_chs = (dcs & 0x0C) >> 2; other_decode_bitfield_value(bigbuf, dcs, 0x0C, 8); proto_tree_add_uint_format(param_tree, hf_cimd_dcs_character_set_indicator, tvb, offset, 1, dcs_chs, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_character_set_indicator)->name, val_to_str(dcs_chs, cimd_dcs_character_set, "Unknown (%d)"), dcs_chs ); if (dcs_mcm) { dcs_mc = (dcs & 0x03); other_decode_bitfield_value(bigbuf, dcs, 0x03, 8); proto_tree_add_uint_format(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1, dcs_mc, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_message_class_indicator)->name, val_to_str(dcs_mc, cimd_dcs_message_class, "Unknown (%d)"), dcs_mc ); } }
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); } }
static gboolean proto_hier_tree_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n) { ProtoHierTreeModel *model; gint proto_id; void *cookie; g_return_val_if_fail(PROTOHIER_IS_TREE(tree_model), FALSE); model = (ProtoHierTreeModel *) tree_model; if (parent) { header_field_info *hfinfo; g_return_val_if_fail(parent->stamp == model->stamp, FALSE); /* no child of field */ if (parent->user_data2 != NULL) return FALSE; proto_id = proto_get_data_protocol(parent->user_data); /* get n-th field of protocol */ hfinfo = proto_get_first_protocol_field(proto_id, &cookie); while (hfinfo) { if (hfinfo->same_name_prev_id == -1) { if (!n) break; n--; } hfinfo = proto_get_next_protocol_field(&cookie); } /* not found? */ if (!hfinfo) return FALSE; iter->stamp = model->stamp; iter->user_data = parent->user_data; iter->user_data2 = cookie; iter->user_data3 = hfinfo; return TRUE; } /* get n-th enabled protocol */ proto_id = proto_get_first_protocol(&cookie); while (proto_id != -1) { protocol_t *p = find_protocol_by_id(proto_id); if (proto_is_protocol_enabled(p)) { if (!n) break; n--; } proto_id = proto_get_next_protocol(&cookie); } /* not found? */ if (proto_id == -1) return FALSE; iter->stamp = model->stamp; iter->user_data = cookie; iter->user_data2 = NULL; iter->user_data3 = proto_registrar_get_nth(proto_id); return TRUE; }
/* note that even if ajp13_tree is null on the first pass, we still * need to dissect the packet in order to determine if there is a * content-length, and thus if there is a subsequent automatic * request-body transmitted in the next request packet. if there is a * content-length, we record the fact in the conversation context. * ref the top of this file for comments explaining the multi-pass * thing. */ static void display_req_forward(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd) { int pos = 0; guint8 meth; guint8 cod; const gchar *ver; guint16 ver_len; const gchar *uri; guint16 uri_len; const gchar *raddr; guint16 raddr_len; const gchar *rhost; guint16 rhost_len; const gchar *srv; guint16 srv_len; guint nhdr; guint i; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA); pos+=2; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; /* PACKET CODE */ cod = tvb_get_guint8(tvb, 4); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN); pos+=1; if ( cod == MTYPE_CPING ) { col_append_str(pinfo->cinfo, COL_INFO, "CPING" ); return; } /* HTTP METHOD (ENCODED AS INTEGER) */ meth = tvb_get_guint8(tvb, pos); col_append_str(pinfo->cinfo, COL_INFO, val_to_str(meth, http_method_codes, "Unknown method %u")); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_method, tvb, pos, 1, ENC_BIG_ENDIAN); pos+=1; /* HTTP VERSION STRING */ ver = ajp13_get_nstring(tvb, pos, &ver_len); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_ver, tvb, pos, ver_len+2, ver); pos=pos+ver_len+2; /* skip over size + chars + trailing null */ /* URI */ uri = ajp13_get_nstring(tvb, pos, &uri_len); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_uri, tvb, pos, uri_len+2, uri); pos=pos+uri_len+2; /* skip over size + chars + trailing null */ col_append_fstr(pinfo->cinfo, COL_INFO, " %s %s", uri, ver); /* REMOTE ADDRESS */ raddr = ajp13_get_nstring(tvb, pos, &raddr_len); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_raddr, tvb, pos, raddr_len+2, raddr); pos=pos+raddr_len+2; /* skip over size + chars + trailing null */ /* REMOTE HOST */ rhost = ajp13_get_nstring(tvb, pos, &rhost_len); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_rhost, tvb, pos, rhost_len+2, rhost); pos=pos+rhost_len+2; /* skip over size + chars + trailing null */ /* SERVER NAME */ srv = ajp13_get_nstring(tvb, pos, &srv_len); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_srv, tvb, pos, srv_len+2, srv); pos=pos+srv_len+2; /* skip over size + chars + trailing null */ /* SERVER PORT */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_port, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; /* IS SSL? */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_sslp, tvb, pos, 1, ENC_NA); pos+=1; /* NUM HEADERS */ nhdr = tvb_get_ntohs(tvb, pos); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; cd->content_length = 0; /* HEADERS */ for(i=0; i<nhdr; i++) { guint8 hcd; guint8 hid; const gchar* hname = NULL; header_field_info *hfinfo; int hpos = pos; int cl = 0; const gchar *hval; guint16 hval_len, hname_len; /* HEADER CODE/NAME */ hcd = tvb_get_guint8(tvb, pos); if (hcd == 0xA0) { pos+=1; hid = tvb_get_guint8(tvb, pos); pos+=1; if (hid >= array_length(req_headers)) hid = 0; hval = ajp13_get_nstring(tvb, pos, &hval_len); if (ajp13_tree) { hfinfo = proto_registrar_get_nth(*req_headers[hid]); proto_tree_add_string_format(ajp13_tree, *req_headers[hid], tvb, hpos, 2+hval_len+2, hval, "%s: %s", hfinfo->name, hval); } pos+=hval_len+2; if (hid == 0x08) cl = 1; } else { hname = ajp13_get_nstring(tvb, pos, &hname_len); pos+=hname_len+2; hval = ajp13_get_nstring(tvb, pos, &hval_len); if (ajp13_tree) { proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header, tvb, hpos, hname_len+2+hval_len+2, ep_strdup_printf("%s: %s", hname, hval), "%s: %s", hname, hval); } pos+=hval_len+2; } if (cl) { cl = atoi(hval); cd->content_length = cl; } } /* ATTRIBUTES */ while(tvb_reported_length_remaining(tvb, pos) > 0) { guint8 aid; const gchar* aname = NULL; const gchar* aval; guint16 aval_len, aname_len; header_field_info *hfinfo; int apos = pos; /* ATTRIBUTE CODE/NAME */ aid = tvb_get_guint8(tvb, pos); pos+=1; if (aid == 0xFF) { /* request terminator */ break; } if (aid == 0x0A) { /* req_attribute - name and value follow */ aname = ajp13_get_nstring(tvb, pos, &aname_len); pos+=aname_len+2; aval = ajp13_get_nstring(tvb, pos, &aval_len); pos+=aval_len+2; if (ajp13_tree) { proto_tree_add_string_format(ajp13_tree, hf_ajp13_req_attribute, tvb, apos, 1+aname_len+2+aval_len+2, ep_strdup_printf("%s: %s", aname, aval), "%s: %s", aname, aval); } } else if (aid == 0x0B ) { /* ssl_key_length */ if (ajp13_tree) { proto_tree_add_uint(ajp13_tree, hf_ajp13_ssl_key_size, tvb, apos, 1+2, tvb_get_ntohs(tvb, pos)); } pos+=2; } else { if (aid >= array_length(req_attributes)) aid = 0; hfinfo = proto_registrar_get_nth(*req_attributes[aid]); aval = ajp13_get_nstring(tvb, pos, &aval_len); pos+=aval_len+2; if (ajp13_tree) { proto_tree_add_string_format(ajp13_tree, *req_attributes[aid], tvb, apos, 1+aval_len+2, aval, "%s: %s", hfinfo->name, aval); } } } }
/* dissect a response. more work to do here. */ static void display_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd) { int pos = 0; guint8 mcode = 0; int i; /* MAGIC */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA); pos+=2; /* PDU LENGTH */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; /* MESSAGE TYPE CODE */ mcode = tvb_get_guint8(tvb, pos); col_append_str(pinfo->cinfo, COL_INFO, val_to_str(mcode, mtype_codes, "Unknown message code %u")); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN); pos+=1; switch (mcode) { case MTYPE_END_RESPONSE: if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_reusep, tvb, pos, 1, ENC_BIG_ENDIAN); /*pos+=1;*/ break; case MTYPE_SEND_HEADERS: { const gchar *rsmsg; guint16 rsmsg_len; guint16 nhdr; guint16 rcode_num; /* HTTP RESPONSE STATUS CODE */ rcode_num = tvb_get_ntohs(tvb, pos); col_append_fstr(pinfo->cinfo, COL_INFO, ":%d", rcode_num); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rstatus, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; /* HTTP RESPONSE STATUS MESSAGE */ rsmsg = ajp13_get_nstring(tvb, pos, &rsmsg_len); col_append_fstr(pinfo->cinfo, COL_INFO, " %s", rsmsg); if (ajp13_tree) proto_tree_add_string(ajp13_tree, hf_ajp13_rsmsg, tvb, pos, rsmsg_len+2, rsmsg); pos+=rsmsg_len+2; /* NUMBER OF HEADERS */ nhdr = tvb_get_ntohs(tvb, pos); if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN); pos+=2; /* HEADERS */ for(i=0; i<nhdr; i++) { guint8 hcd; guint8 hid; const gchar *hval; guint16 hval_len, hname_len; const gchar* hname = NULL; header_field_info *hfinfo; int hpos = pos; /* int cl = 0; TODO: Content-Length header (encoded by 0x08) is special */ /* HEADER CODE/NAME */ hcd = tvb_get_guint8(tvb, pos); if (hcd == 0xA0) { pos+=1; hid = tvb_get_guint8(tvb, pos); pos+=1; if (hid >= array_length(rsp_headers)) hid = 0; hval = ajp13_get_nstring(tvb, pos, &hval_len); if (ajp13_tree) { hfinfo = proto_registrar_get_nth(*rsp_headers[hid]); proto_tree_add_string_format(ajp13_tree, *rsp_headers[hid], tvb, hpos, 2+hval_len+2, hval, "%s: %s", hfinfo->name, hval); } pos+=hval_len+2; #if 0 /* TODO: Content-Length header (encoded by 0x08) is special */ if (hid == 0x08) cl = 1; #endif } else { hname = ajp13_get_nstring(tvb, pos, &hname_len); pos+=hname_len+2; hval = ajp13_get_nstring(tvb, pos, &hval_len); if (ajp13_tree) { proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header, tvb, hpos, hname_len+2+hval_len+2, ep_strdup_printf("%s: %s", hname, hval), "%s: %s", hname, hval); } pos+=hval_len+2; } } break; } case MTYPE_GET_BODY_CHUNK: { guint16 rlen; rlen = tvb_get_ntohs(tvb, pos); cd->content_length = rlen; if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_rlen, tvb, pos, 2, ENC_BIG_ENDIAN); /*pos+=2;*/ break; } case MTYPE_CPONG: break; default: /* MESSAGE DATA (COPOUT) */ if (ajp13_tree) proto_tree_add_item(ajp13_tree, hf_ajp13_data, tvb, pos+2, -1, ENC_UTF_8|ENC_NA); break; } }
/* If the LHS of a relation test is a FIELD, run some checks * and possibly some modifications of syntax tree nodes. */ static void check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, FtypeCanFunc can_func, gboolean allow_partial_value, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2) { stnode_t *new_st; sttype_id_t type2; header_field_info *hfinfo1, *hfinfo2; df_func_def_t *funcdef; ftenum_t ftype1, ftype2; fvalue_t *fvalue; char *s; type2 = stnode_type_id(st_arg2); hfinfo1 = (header_field_info*)stnode_data(st_arg1); ftype1 = hfinfo1->type; if (stnode_type_id(st_node) == STTYPE_TEST) { DebugLog((" 5 check_relation_LHS_FIELD(%s)\n", relation_string)); } else { DebugLog((" 6 check_relation_LHS_FIELD(%s)\n", relation_string)); } if (!can_func(ftype1)) { dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.", hfinfo1->abbrev, ftype_pretty_name(ftype1), relation_string); THROW(TypeError); } if (type2 == STTYPE_FIELD) { hfinfo2 = (header_field_info*)stnode_data(st_arg2); ftype2 = hfinfo2->type; if (!compatible_ftypes(ftype1, ftype2)) { dfilter_fail(dfw, "%s and %s are not of compatible types.", hfinfo1->abbrev, hfinfo2->abbrev); THROW(TypeError); } /* Do this check even though you'd think that if * they're compatible, then can_func() would pass. */ if (!can_func(ftype2)) { dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.", hfinfo2->abbrev, ftype_pretty_name(ftype2)); THROW(TypeError); } } else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { s = (char *)stnode_data(st_arg2); if (strcmp(relation_string, "matches") == 0) { /* Convert to a FT_PCRE */ if (type2 == STTYPE_STRING) fvalue = dfilter_fvalue_from_string(dfw, FT_PCRE, s); else fvalue = dfilter_fvalue_from_unparsed(dfw, FT_PCRE, s, FALSE); } else { /* Skip incompatible fields */ while (hfinfo1->same_name_prev_id != -1 && ((type2 == STTYPE_STRING && ftype1 != FT_STRING && ftype1!= FT_STRINGZ) || (type2 != STTYPE_STRING && (ftype1 == FT_STRING || ftype1== FT_STRINGZ)))) { hfinfo1 = proto_registrar_get_nth(hfinfo1->same_name_prev_id); ftype1 = hfinfo1->type; } if (type2 == STTYPE_STRING) fvalue = dfilter_fvalue_from_string(dfw, ftype1, s); else fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value); if (!fvalue) { /* check value_string */ fvalue = mk_fvalue_from_val_string(dfw, hfinfo1, s); } } if (!fvalue) { THROW(TypeError); } new_st = stnode_new(STTYPE_FVALUE, fvalue); if (stnode_type_id(st_node) == STTYPE_TEST) { sttype_test_set2_args(st_node, st_arg1, new_st); } else { sttype_set_replace_element(st_node, st_arg2, new_st); } stnode_free(st_arg2); } else if (type2 == STTYPE_RANGE) { check_drange_sanity(dfw, st_arg2); if (!is_bytes_type(ftype1)) { if (!ftype_can_slice(ftype1)) { dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.", hfinfo1->abbrev, ftype_pretty_name(ftype1)); THROW(TypeError); } /* Convert entire field to bytes */ new_st = convert_to_bytes(st_arg1); sttype_test_set2_args(st_node, new_st, st_arg2); } } else if (type2 == STTYPE_FUNCTION) { funcdef = sttype_function_funcdef(st_arg2); ftype2 = funcdef->retval_ftype; if (!compatible_ftypes(ftype1, ftype2)) { dfilter_fail(dfw, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.", hfinfo1->abbrev, ftype_pretty_name(ftype1), funcdef->name, ftype_pretty_name(ftype2)); THROW(TypeError); } if (!can_func(ftype2)) { dfilter_fail(dfw, "return value of %s() (type=%s) cannot participate in specified comparison.", funcdef->name, ftype_pretty_name(ftype2)); THROW(TypeError); } check_function(dfw, st_arg2); } else if (type2 == STTYPE_SET) { GSList *nodelist; /* A set should only ever appear on RHS of 'in' operation */ if (strcmp(relation_string, "in") != 0) { g_assert_not_reached(); } /* Attempt to interpret one element of the set at a time */ nodelist = (GSList*)stnode_data(st_arg2); while (nodelist) { stnode_t *node = (stnode_t*)nodelist->data; /* Don't let a range on the RHS affect the LHS field. */ if (stnode_type_id(node) == STTYPE_RANGE) { dfilter_fail(dfw, "A range may not appear inside a set."); THROW(TypeError); break; } check_relation_LHS_FIELD(dfw, "==", can_func, allow_partial_value, st_arg2, st_arg1, node); nodelist = g_slist_next(nodelist); } } else { g_assert_not_reached(); } }
void proto_register_udp(void) { module_t *udp_module; module_t *udplite_module; expert_module_t* expert_udp; #ifndef HAVE_HFI_SECTION_INIT static header_field_info *hfi[] = { &hfi_udp_srcport, &hfi_udp_dstport, &hfi_udp_port, &hfi_udp_stream, &hfi_udp_length, &hfi_udp_checksum, &hfi_udp_checksum_calculated, &hfi_udp_checksum_good, &hfi_udp_checksum_bad, &hfi_udp_proc_src_uid, &hfi_udp_proc_src_pid, &hfi_udp_proc_src_uname, &hfi_udp_proc_src_cmd, &hfi_udp_proc_dst_uid, &hfi_udp_proc_dst_pid, &hfi_udp_proc_dst_uname, &hfi_udp_proc_dst_cmd, }; static header_field_info *hfi_lite[] = { &hfi_udplite_checksum_coverage_bad, &hfi_udplite_checksum_coverage, }; #endif static gint *ett[] = { &ett_udp, &ett_udp_checksum, &ett_udp_process_info }; static ei_register_info ei[] = { { &ei_udp_possible_traceroute, { "udp.possible_traceroute", PI_SEQUENCE, PI_CHAT, "Possible traceroute", EXPFILL }}, { &ei_udp_length, { "udp.length.bad", PI_MALFORMED, PI_ERROR, "Bad length value", EXPFILL }}, { &ei_udplite_checksum_coverage, { "udp.checksum_coverage.expert", PI_MALFORMED, PI_ERROR, "Bad checksum coverage length value", EXPFILL }}, { &ei_udp_checksum_zero, { "udp.checksum.zero", PI_CHECKSUM, PI_ERROR, "Illegal Checksum value (0)", EXPFILL }}, { &ei_udp_checksum_bad, { "udp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }}, }; static build_valid_func udp_da_src_values[1] = {udp_src_value}; static build_valid_func udp_da_dst_values[1] = {udp_dst_value}; static build_valid_func udp_da_both_values[2] = {udp_src_value, udp_dst_value}; static decode_as_value_t udp_da_values[3] = {{udp_src_prompt, 1, udp_da_src_values}, {udp_dst_prompt, 1, udp_da_dst_values}, {udp_both_prompt, 2, udp_da_both_values}}; static decode_as_t udp_da = {"udp", "Transport", "udp.port", 3, 2, udp_da_values, "UDP", "port(s) as", decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL}; int proto_udp, proto_udplite; proto_udp = proto_register_protocol("User Datagram Protocol", "UDP", "udp"); hfi_udp = proto_registrar_get_nth(proto_udp); udp_handle = register_dissector("udp", dissect_udp, proto_udp); expert_udp = expert_register_protocol(proto_udp); proto_register_fields(proto_udp, hfi, array_length(hfi)); proto_udplite = proto_register_protocol("Lightweight User Datagram Protocol", "UDPlite", "udplite"); udplite_handle = create_dissector_handle(dissect_udplite, proto_udplite); hfi_udplite = proto_registrar_get_nth(proto_udplite); proto_register_fields(proto_udplite, hfi_lite, array_length(hfi_lite)); proto_register_subtree_array(ett, array_length(ett)); expert_register_field_array(expert_udp, ei, array_length(ei)); /* subdissector code */ udp_dissector_table = register_dissector_table("udp.port", "UDP port", FT_UINT16, BASE_DEC); register_heur_dissector_list("udp", &heur_subdissector_list); register_heur_dissector_list("udplite", &heur_subdissector_list); /* Register configuration preferences */ udp_module = prefs_register_protocol(proto_udp, NULL); prefs_register_bool_preference(udp_module, "summary_in_tree", "Show UDP summary in protocol tree", "Whether the UDP summary line should be shown in the protocol tree", &udp_summary_in_tree); prefs_register_bool_preference(udp_module, "try_heuristic_first", "Try heuristic sub-dissectors first", "Try to decode a packet using an heuristic sub-dissector" " before using a sub-dissector registered to a specific port", &try_heuristic_first); prefs_register_bool_preference(udp_module, "check_checksum", "Validate the UDP checksum if possible", "Whether to validate the UDP checksum", &udp_check_checksum); prefs_register_bool_preference(udp_module, "process_info", "Collect process flow information", "Collect process flow information from IPFIX", &udp_process_info); udplite_module = prefs_register_protocol(proto_udplite, NULL); prefs_register_bool_preference(udplite_module, "ignore_checksum_coverage", "Ignore UDPlite checksum coverage", "Ignore an invalid checksum coverage field and continue dissection", &udplite_ignore_checksum_coverage); prefs_register_bool_preference(udplite_module, "check_checksum", "Validate the UDPlite checksum if possible", "Whether to validate the UDPlite checksum", &udplite_check_checksum); register_decode_as(&udp_da); register_init_routine(udp_init); }
static void gen_test(dfwork_t *dfw, stnode_t *st_node) { test_op_t st_op; stnode_t *st_arg1, *st_arg2; dfvm_value_t *val1; dfvm_insn_t *insn; header_field_info *hfinfo; sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2); switch (st_op) { case TEST_OP_UNINITIALIZED: g_assert_not_reached(); break; case TEST_OP_EXISTS: val1 = dfvm_value_new(HFINFO); hfinfo = (header_field_info*)stnode_data(st_arg1); /* Rewind to find the first field of this name. */ while (hfinfo->same_name_prev_id != -1) { hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id); } val1->value.hfinfo = hfinfo; insn = dfvm_insn_new(CHECK_EXISTS); insn->arg1 = val1; dfw_append_insn(dfw, insn); /* Record the FIELD_ID in hash of interesting fields. */ while (hfinfo) { g_hash_table_insert(dfw->interesting_fields, GINT_TO_POINTER(hfinfo->id), GUINT_TO_POINTER(TRUE)); hfinfo = hfinfo->same_name_next; } break; case TEST_OP_NOT: gencode(dfw, st_arg1); insn = dfvm_insn_new(NOT); dfw_append_insn(dfw, insn); break; case TEST_OP_AND: gencode(dfw, st_arg1); insn = dfvm_insn_new(IF_FALSE_GOTO); val1 = dfvm_value_new(INSN_NUMBER); insn->arg1 = val1; dfw_append_insn(dfw, insn); gencode(dfw, st_arg2); val1->value.numeric = dfw->next_insn_id; break; case TEST_OP_OR: gencode(dfw, st_arg1); insn = dfvm_insn_new(IF_TRUE_GOTO); val1 = dfvm_value_new(INSN_NUMBER); insn->arg1 = val1; dfw_append_insn(dfw, insn); gencode(dfw, st_arg2); val1->value.numeric = dfw->next_insn_id; break; case TEST_OP_EQ: gen_relation(dfw, ANY_EQ, st_arg1, st_arg2); break; case TEST_OP_NE: gen_relation(dfw, ANY_NE, st_arg1, st_arg2); break; case TEST_OP_GT: gen_relation(dfw, ANY_GT, st_arg1, st_arg2); break; case TEST_OP_GE: gen_relation(dfw, ANY_GE, st_arg1, st_arg2); break; case TEST_OP_LT: gen_relation(dfw, ANY_LT, st_arg1, st_arg2); break; case TEST_OP_LE: gen_relation(dfw, ANY_LE, st_arg1, st_arg2); break; case TEST_OP_BITWISE_AND: gen_relation(dfw, ANY_BITWISE_AND, st_arg1, st_arg2); break; case TEST_OP_CONTAINS: gen_relation(dfw, ANY_CONTAINS, st_arg1, st_arg2); break; case TEST_OP_MATCHES: gen_relation(dfw, ANY_MATCHES, st_arg1, st_arg2); break; } }
/* If the LHS of a relation test is a FIELD, run some checks * and possibly some modifications of syntax tree nodes. */ static void check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func, gboolean allow_partial_value, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2) { stnode_t *new_st; sttype_id_t type2; header_field_info *hfinfo1, *hfinfo2; df_func_def_t *funcdef; ftenum_t ftype1, ftype2; fvalue_t *fvalue; char *s; type2 = stnode_type_id(st_arg2); hfinfo1 = (header_field_info*)stnode_data(st_arg1); ftype1 = hfinfo1->type; DebugLog((" 5 check_relation_LHS_FIELD(%s)\n", relation_string)); if (!can_func(ftype1)) { dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.", hfinfo1->abbrev, ftype_pretty_name(ftype1), relation_string); THROW(TypeError); } if (type2 == STTYPE_FIELD) { hfinfo2 = (header_field_info*)stnode_data(st_arg2); ftype2 = hfinfo2->type; if (!compatible_ftypes(ftype1, ftype2)) { dfilter_fail("%s and %s are not of compatible types.", hfinfo1->abbrev, hfinfo2->abbrev); THROW(TypeError); } /* Do this check even though you'd think that if * they're compatible, then can_func() would pass. */ if (!can_func(ftype2)) { dfilter_fail("%s (type=%s) cannot participate in specified comparison.", hfinfo2->abbrev, ftype_pretty_name(ftype2)); THROW(TypeError); } } else if (type2 == STTYPE_STRING) { s = (char *)stnode_data(st_arg2); if (strcmp(relation_string, "matches") == 0) { /* Convert to a FT_PCRE */ fvalue = fvalue_from_string(FT_PCRE, s, dfilter_fail); } else { fvalue = fvalue_from_string(ftype1, s, dfilter_fail); if (!fvalue) { /* check value_string */ fvalue = mk_fvalue_from_val_string(hfinfo1, s); } } if (!fvalue) { THROW(TypeError); } new_st = stnode_new(STTYPE_FVALUE, fvalue); sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } else if (type2 == STTYPE_UNPARSED) { s = (char *)stnode_data(st_arg2); if (strcmp(relation_string, "matches") == 0) { /* Convert to a FT_PCRE */ fvalue = fvalue_from_unparsed(FT_PCRE, s, FALSE, dfilter_fail); } else { do { fvalue = fvalue_from_unparsed(ftype1, s, allow_partial_value, dfilter_fail); if (!fvalue) { /* check value_string */ fvalue = mk_fvalue_from_val_string(hfinfo1, s); } if (!fvalue) { /* Try another field with the same name */ if (hfinfo1->same_name_prev_id != -1) { hfinfo1 = proto_registrar_get_nth(hfinfo1->same_name_prev_id); ftype1 = hfinfo1->type; } else { break; } } } while (!fvalue); } if (!fvalue) { THROW(TypeError); } new_st = stnode_new(STTYPE_FVALUE, fvalue); sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } else if (type2 == STTYPE_RANGE) { check_drange_sanity(st_arg2); if (!is_bytes_type(ftype1)) { if (!ftype_can_slice(ftype1)) { dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.", hfinfo1->abbrev, ftype_pretty_name(ftype1)); THROW(TypeError); } /* Convert entire field to bytes */ new_st = convert_to_bytes(st_arg1); sttype_test_set2_args(st_node, new_st, st_arg2); } } else if (type2 == STTYPE_FUNCTION) { funcdef = sttype_function_funcdef(st_arg2); ftype2 = funcdef->retval_ftype; if (!compatible_ftypes(ftype1, ftype2)) { dfilter_fail("%s (type=%s) and return value of %s() (type=%s) are not of compatible types.", hfinfo1->abbrev, ftype_pretty_name(ftype1), funcdef->name, ftype_pretty_name(ftype2)); THROW(TypeError); } if (!can_func(ftype2)) { dfilter_fail("return value of %s() (type=%s) cannot participate in specified comparison.", funcdef->name, ftype_pretty_name(ftype2)); THROW(TypeError); } check_function(st_arg2); } else { g_assert_not_reached(); } }