static void dissect_ipvs_syncd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_tree *tree; proto_item *item; int offset = 0; guint8 cnt = 0; int conn = 0; item = proto_tree_add_item(parent_tree, proto_ipvs_syncd, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_ipvs_syncd); col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPVS"); col_clear(pinfo->cinfo, COL_INFO); cnt = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_conn_count, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_syncid, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; for (conn = 0; conn < cnt; conn++) { proto_tree *ctree, *ti; proto_tree *ftree, *fi; guint16 flags; ti = proto_tree_add_text(tree, tvb, offset, 24, "Connection #%d", conn+1); ctree = proto_item_add_subtree(ti, ett_conn); proto_tree_add_item(ctree, hf_resv8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ctree, hf_proto, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ctree, hf_cport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_vport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_dport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_caddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_vaddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_daddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; flags = tvb_get_ntohs(tvb, offset); fi = proto_tree_add_item(ctree, hf_flags, tvb, offset, 2, ENC_BIG_ENDIAN); ftree = proto_item_add_subtree(fi, ett_flags); if ( (flags & 0x0F) == IP_VS_CONN_F_MASQ ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Masquerade"); } else if ( (flags & 0x0F) == IP_VS_CONN_F_LOCALNODE ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Local Node"); } else if ( (flags & 0x0F) == IP_VS_CONN_F_TUNNEL ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Tunnel"); } else if ( (flags & 0x0F) == IP_VS_CONN_F_DROUTE ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Direct Routing"); } else { proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Unknown (%d)", flags & IP_VS_CONN_F_FWD_MASK); } if ( flags & IP_VS_CONN_F_HASHED ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "Hashed Entry"); } if ( flags & IP_VS_CONN_F_NOOUTPUT ) { proto_tree_add_text(ftree, tvb, offset+1, 1, "No Output Packets"); } if ( flags & IP_VS_CONN_F_INACTIVE ) { proto_tree_add_text(ftree, tvb, offset, 1, "Connection Not Established"); } if ( flags & IP_VS_CONN_F_OUT_SEQ ) { proto_tree_add_text(ftree, tvb, offset, 1, "Adjust Output Sequence"); } if ( flags & IP_VS_CONN_F_IN_SEQ ) { proto_tree_add_text(ftree, tvb, offset, 1, "Adjust Input Sequence"); } if ( flags & IP_VS_CONN_F_NO_CPORT ) { proto_tree_add_text(ftree, tvb, offset, 1, "No Client Port Set"); } offset += 2; proto_tree_add_item(ctree, hf_state, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* we have full connection info */ if ( flags & IP_VS_CONN_F_SEQ_MASK ) { proto_tree_add_item(ctree, hf_in_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_in_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_in_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } }
static void dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint op; guint sub; guint rlen; proto_item *ti; proto_item *item; proto_tree *fip_tree; proto_tree *subtree; guint dtype; guint dlen; guint desc_offset; guint val; tvbuff_t *desc_tvb; const char *info; const char *text; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIP"); col_clear(pinfo->cinfo, COL_INFO); if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) { col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]"); if (tree) proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, -1, "FIP [packet too short]"); return; } op = tvb_get_ntohs(tvb, 2); sub = tvb_get_guint8(tvb, 5); switch (op) { case FIP_OP_DISC: info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x"); break; case FIP_OP_LS: info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x"); break; case FIP_OP_CTRL: info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x"); break; case FIP_OP_VLAN: info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x"); break; case FIP_OP_VN2VN: info = val_to_str(sub, fip_vn2vn_subcodes, "VN2VN 0x%x"); break; default: info = val_to_str(op, fip_opcodes, "Unknown op 0x%x"); break; } col_add_str(pinfo->cinfo, COL_INFO, info); rlen = tvb_get_ntohs(tvb, 6); ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, FIP_HEADER_LEN + rlen * FIP_BPW, "FIP %s", info); fip_tree = proto_item_add_subtree(ti, ett_fip); proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, ENC_BIG_ENDIAN); switch (op) { case FIP_OP_DISC: proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_LS: proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_CTRL: proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VLAN: proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VN2VN: proto_tree_add_item(fip_tree, hf_fip_vn2vn_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; default: proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; } proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, ENC_BIG_ENDIAN); proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags, ett_fip_flags, hf_fip_flags_fields, ENC_BIG_ENDIAN); desc_offset = FIP_HEADER_LEN; rlen *= FIP_BPW; proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors"); while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) { dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW; if (!dlen) { proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1); break; } if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) { break; } desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1); dtype = tvb_get_guint8(desc_tvb, 0); desc_offset += dlen; rlen -= dlen; switch (dtype) { case FIP_DT_PRI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item); proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb, 3, 1, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3)); break; case FIP_DT_MAC: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item); proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb, 2, 6, ENC_NA); proto_item_append_text(item, "%s", tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':')); break; case FIP_DT_MAP_OUI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item); text = tvb_fc_to_str(desc_tvb, 5); proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb, 5, 3, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_NAME: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item); text = tvb_fcwwn_to_str(desc_tvb, 4); proto_tree_add_string(subtree, hf_fip_desc_name, desc_tvb, 4, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FAB: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item); proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb, 2, 2, ENC_BIG_ENDIAN); text = tvb_fc_to_str(desc_tvb, 5); proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb, 5, 3, text); text = tvb_fcwwn_to_str(desc_tvb, 8); proto_tree_add_string(subtree, hf_fip_desc_fab_name, desc_tvb, 8, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FCOE_SIZE: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item); proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FLOGI: case FIP_DT_FDISC: case FIP_DT_LOGO: case FIP_DT_ELP: { tvbuff_t *ls_tvb; fc_data_t fc_data = {ETHERTYPE_FIP, 0}; subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item); ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1); call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data); proto_item_append_text(item, "%u bytes", dlen - 4); } break; case FIP_DT_VN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item); proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb, 2, 6, ENC_NA); proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb, 9, 3, ENC_BIG_ENDIAN); text = tvb_fcwwn_to_str(desc_tvb, 12); proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn, desc_tvb, 12, 8, text); proto_item_append_text(item, "MAC %s FC_ID %6.6x", tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'), tvb_get_ntoh24(desc_tvb, 9)); break; case FIP_DT_FKA: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item); val = tvb_get_ntohl(desc_tvb, 4); proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka, desc_tvb, 4, 4, val, "%u ms", val); proto_item_append_text(item, "%u ms", val); break; case FIP_DT_VEND: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item); proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb, 4, 8, ENC_NA); if (tvb_bytes_exist(desc_tvb, 9, -1)) { proto_tree_add_item(subtree, hf_fip_desc_vend_data, desc_tvb, 9, -1, ENC_NA); } break; case FIP_DT_VLAN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item); proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FC4F: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item); fip_desc_fc4f(desc_tvb, subtree, item); break; default: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item); proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb, 2, -1, ENC_NA); break; } } }
static void dissect_ipxwan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *ipxwan_tree = NULL; int offset = 0; guint8 packet_type; guint8 num_options; guint8 option_number; proto_tree *option_tree; guint16 option_data_len; guint16 wan_link_delay; guint32 delay; guint32 throughput; guint32 delta_time; guint8 compression_type; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX WAN"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_ipxwan, tvb, 0, -1, FALSE); ipxwan_tree = proto_item_add_subtree(ti, ett_ipxwan); } if (tree) { proto_tree_add_item(ipxwan_tree, hf_ipxwan_identifier, tvb, offset, 4, FALSE); } offset += 4; packet_type = tvb_get_guint8(tvb, offset); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, ipxwan_packet_type_vals, "Unknown packet type %u")); } if (tree) { proto_tree_add_uint(ipxwan_tree, hf_ipxwan_packet_type, tvb, offset, 1, packet_type); offset += 1; proto_tree_add_item(ipxwan_tree, hf_ipxwan_node_id, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ipxwan_tree, hf_ipxwan_sequence_number, tvb, offset, 1, FALSE); offset += 1; num_options = tvb_get_guint8(tvb, offset); proto_tree_add_uint(ipxwan_tree, hf_ipxwan_num_options, tvb, offset, 1, num_options); offset += 1; while (num_options != 0) { option_number = tvb_get_guint8(tvb, offset); ti = proto_tree_add_text(ipxwan_tree, tvb, offset, -1, "Option: %s", val_to_str(option_number, ipxwan_option_num_vals, "Unknown (%u)")); option_tree = proto_item_add_subtree(ti, ett_ipxwan_option); proto_tree_add_uint(option_tree, hf_ipxwan_option_num, tvb, offset, 1, option_number); offset += 1; proto_tree_add_item(option_tree, hf_ipxwan_accept_option, tvb, offset, 1, FALSE); offset += 1; option_data_len = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(option_tree, hf_ipxwan_option_data_len, tvb, offset, 2, option_data_len); offset += 2; proto_item_set_len(ti, option_data_len+4); switch (option_number) { case OPT_ROUTING_TYPE: if (option_data_len != 1) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 1", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_routing_type, tvb, offset, 1, FALSE); } break; case OPT_RIP_SAP_INFO_EXCHANGE: if (option_data_len != 54) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 54", option_data_len); } else { wan_link_delay = tvb_get_ntohs(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_wan_link_delay, tvb, offset, 2, wan_link_delay, "WAN Link Delay: %ums", wan_link_delay); proto_tree_add_item(option_tree, hf_ipxwan_common_network_number, tvb, offset+2, 4, FALSE); proto_tree_add_item(option_tree, hf_ipxwan_router_name, tvb, offset+6, 48, FALSE); } break; case OPT_NLSP_INFORMATION: if (option_data_len != 8) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 8", option_data_len); } else { delay = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_delay, tvb, offset, 4, delay, "Delay: %uus", delay); throughput = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_throughput, tvb, offset, 4, throughput, "Throughput: %uus", throughput); } break; case OPT_NLSP_RAW_THROUGHPUT_DATA: if (option_data_len != 8) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 8", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_request_size, tvb, offset, 4, FALSE); delta_time = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_delta_time, tvb, offset, 4, delta_time, "Delta Time: %uus", delta_time); } break; case OPT_EXTENDED_NODE_ID: if (option_data_len != 4) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 4", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_extended_node_id, tvb, offset, 4, FALSE); } break; case OPT_NODE_NUMBER: if (option_data_len != 6) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 6", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_node_number, tvb, offset, 6, FALSE); } break; case OPT_COMPRESSION: if (option_data_len < 1) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be >= 1", option_data_len); } else { compression_type = tvb_get_guint8(tvb, offset); proto_tree_add_uint(option_tree, hf_ipxwan_compression_type, tvb, offset, 1, compression_type); switch (compression_type) { case COMP_TYPE_TELEBIT: if (option_data_len < 3) { proto_tree_add_text(option_tree, tvb, offset+1, option_data_len-1, "Bogus length: %u, should be >= 3", option_data_len); } else { proto_tree_add_text( option_tree, tvb, offset+1, 1, "Compression options: 0x%02x", tvb_get_guint8(tvb, offset+1)); proto_tree_add_text( option_tree, tvb, offset+2, 1, "Number of compression slots: %u", tvb_get_guint8(tvb, offset+2)); } break; default: proto_tree_add_text(option_tree, tvb, offset+1, option_data_len-1, "Option parameters"); break; } } break; case OPT_PAD: proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Padding"); break; default: proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Option value"); break; } offset += option_data_len; num_options--; } } }
void xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet) { proto_item *xmpp_iq_item; proto_tree *xmpp_iq_tree; xmpp_attr_t *attr_id, *attr_type; xmpp_attr_info attrs_info[] = { {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL}, {"id", hf_xmpp_id, TRUE, TRUE, NULL, NULL}, {"type", hf_xmpp_type, TRUE, TRUE, NULL, NULL}, {"from", hf_xmpp_from, FALSE, TRUE, NULL, NULL}, {"to", hf_xmpp_to, FALSE, TRUE, NULL, NULL}, {"xml:lang", -1, FALSE, FALSE, NULL, NULL} }; conversation_t *conversation; xmpp_conv_info_t *xmpp_info; xmpp_transaction_t *reqresp_trans; xmpp_elem_info elems_info [] = { {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","http://jabber.org/protocol/disco#items"), xmpp_disco_items_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "jabber:iq:roster"), xmpp_roster_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/disco#info"), xmpp_disco_info_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/bytestreams"), xmpp_bytestreams_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#owner"), xmpp_muc_owner_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#admin"), xmpp_muc_admin_query, ONE}, {NAME, "bind", xmpp_iq_bind, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session"), xmpp_session, ONE}, {NAME, "vCard", xmpp_vcard, ONE}, {NAME, "jingle", xmpp_jingle, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("services", "xmlns", "http://jabber.org/protocol/jinglenodes"), xmpp_jinglenodes_services, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("channel", "xmlns", "http://jabber.org/protocol/jinglenodes#channel"), xmpp_jinglenodes_channel, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("open", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_open, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("close", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_close, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE}, {NAME, "si", xmpp_si, ONE}, {NAME, "error", xmpp_error, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "http://www.google.com/session"), xmpp_gtalk_session, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:jingleinfo"), xmpp_gtalk_jingleinfo_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("usersetting", "xmlns","google:setting"), xmpp_gtalk_usersetting, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:version"), xmpp_version_query, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:mail:notify"), xmpp_gtalk_mail_query, ONE}, {NAME, "mailbox", xmpp_gtalk_mail_mailbox, ONE}, {NAME, "new-mail", xmpp_gtalk_mail_new_mail, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:shared-status"), xmpp_gtalk_status_query, ONE}, {NAME, "conference-info", xmpp_conference_info, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("ping", "xmlns","urn:xmpp:ping"), xmpp_ping, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE}, }; attr_id = xmpp_get_attr(packet, "id"); attr_type = xmpp_get_attr(packet, "type"); conversation = find_or_create_conversation(pinfo); xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp); xmpp_iq_item = proto_tree_add_item(tree, hf_xmpp_iq, tvb, packet->offset, packet->length, ENC_LITTLE_ENDIAN); xmpp_iq_tree = proto_item_add_subtree(xmpp_iq_item,ett_xmpp_iq); xmpp_display_attrs(xmpp_iq_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info)); col_clear(pinfo->cinfo, COL_INFO); col_add_fstr(pinfo->cinfo, COL_INFO, "IQ(%s) ", attr_type?attr_type->value:""); xmpp_display_elems(xmpp_iq_tree, packet, pinfo, tvb, elems_info, array_length(elems_info)); /*displays generated info such as req/resp tracking, jingle sid * in each packet related to specified jingle session and IBB sid in packet related to it*/ if(xmpp_info && attr_id) { gchar *jingle_sid, *ibb_sid, *gtalk_sid; jingle_sid = (gchar *)se_tree_lookup_string(xmpp_info->jingle_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE); if (jingle_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_jingle_session, tvb, 0, 0, jingle_sid); PROTO_ITEM_SET_GENERATED(it); } ibb_sid = (gchar *)se_tree_lookup_string(xmpp_info->ibb_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE); if (ibb_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid); PROTO_ITEM_SET_GENERATED(it); } gtalk_sid = (gchar *)se_tree_lookup_string(xmpp_info->gtalk_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE); if (gtalk_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_gtalk, tvb, 0, 0, gtalk_sid); PROTO_ITEM_SET_GENERATED(it); } reqresp_trans = (xmpp_transaction_t *)se_tree_lookup_string(xmpp_info->req_resp, attr_id->value, EMEM_TREE_STRING_NOCASE); /*displays request/response field in each iq packet*/ if (reqresp_trans) { if (reqresp_trans->req_frame == pinfo->fd->num) { if (reqresp_trans->resp_frame) { proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_in, tvb, 0, 0, reqresp_trans->resp_frame); PROTO_ITEM_SET_GENERATED(it); } else { expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response"); } } else { if (reqresp_trans->req_frame) { proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_to, tvb, 0, 0, reqresp_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); } else { expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response"); } } } } }
static void dissect_nbd_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { guint32 magic, error, packet; guint32 handle[2]; guint64 from; int offset=0; proto_tree *tree=NULL; proto_item *item=NULL; conversation_t *conversation; nbd_conv_info_t *nbd_info; nbd_transaction_t *nbd_trans=NULL; emem_tree_key_t hkey[3]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBD"); col_clear(pinfo->cinfo, COL_INFO); item = proto_tree_add_item(parent_tree, proto_nbd, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_nbd); magic=tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_nbd_magic, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; /* grab what we need to do the request/response matching */ switch(magic){ case NBD_REQUEST_MAGIC: case NBD_RESPONSE_MAGIC: handle[0]=tvb_get_ntohl(tvb, offset+4); handle[1]=tvb_get_ntohl(tvb, offset+8); break; default: return; } conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ nbd_info = conversation_get_proto_data(conversation, proto_nbd); if (!nbd_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ nbd_info = se_alloc(sizeof(nbd_conv_info_t)); nbd_info->unacked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_unacked_pdus"); nbd_info->acked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_acked_pdus"); conversation_add_proto_data(conversation, proto_nbd, nbd_info); } if(!pinfo->fd->flags.visited){ if(magic==NBD_REQUEST_MAGIC){ /* This is a request */ nbd_trans=se_alloc(sizeof(nbd_transaction_t)); nbd_trans->req_frame=pinfo->fd->num; nbd_trans->rep_frame=0; nbd_trans->req_time=pinfo->fd->abs_ts; nbd_trans->type=tvb_get_ntohl(tvb, offset); nbd_trans->datalen=tvb_get_ntohl(tvb, offset+20); hkey[0].length=2; hkey[0].key=handle; hkey[1].length=0; se_tree_insert32_array(nbd_info->unacked_pdus, hkey, (void *)nbd_trans); } else if(magic==NBD_RESPONSE_MAGIC){ hkey[0].length=2; hkey[0].key=handle; hkey[1].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->unacked_pdus, hkey); if(nbd_trans){ nbd_trans->rep_frame=pinfo->fd->num; hkey[0].length=1; hkey[0].key=&nbd_trans->rep_frame; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans); hkey[0].length=1; hkey[0].key=&nbd_trans->req_frame; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans); } } } else { packet=pinfo->fd->num; hkey[0].length=1; hkey[0].key=&packet; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->acked_pdus, hkey); } /* The bloody handles are reused !!! eventhough they are 64 bits. * So we must verify we got the "correct" one */ if( (magic==NBD_RESPONSE_MAGIC) && (nbd_trans) && (pinfo->fd->num<nbd_trans->req_frame) ){ /* must have been the wrong one */ nbd_trans=NULL; } if(!nbd_trans){ /* create a "fake" nbd_trans structure */ nbd_trans=ep_alloc(sizeof(nbd_transaction_t)); nbd_trans->req_frame=0; nbd_trans->rep_frame=0; nbd_trans->req_time=pinfo->fd->abs_ts; nbd_trans->type=0xff; nbd_trans->datalen=0; } /* print state tracking in the tree */ if(magic==NBD_REQUEST_MAGIC){ /* This is a request */ if(nbd_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(tree, hf_nbd_response_in, tvb, 0, 0, nbd_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else if(magic==NBD_RESPONSE_MAGIC){ /* This is a reply */ if(nbd_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(tree, hf_nbd_response_to, tvb, 0, 0, nbd_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &nbd_trans->req_time); it=proto_tree_add_time(tree, hf_nbd_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } switch(magic){ case NBD_REQUEST_MAGIC: proto_tree_add_item(tree, hf_nbd_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; from=tvb_get_ntoh64(tvb, offset); proto_tree_add_item(tree, hf_nbd_from, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; proto_tree_add_item(tree, hf_nbd_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if(check_col(pinfo->cinfo, COL_INFO)){ switch(nbd_trans->type){ case NBD_CMD_WRITE: col_add_fstr(pinfo->cinfo, COL_INFO, "Write Request Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen); break; case NBD_CMD_READ: col_add_fstr(pinfo->cinfo, COL_INFO, "Read Request Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen); break; case NBD_CMD_DISC: col_set_str(pinfo->cinfo, COL_INFO, "Disconnect Request"); break; } } if(nbd_trans->type==NBD_CMD_WRITE){ proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA); } break; case NBD_RESPONSE_MAGIC: item=proto_tree_add_uint(tree, hf_nbd_type, tvb, 0, 0, nbd_trans->type); PROTO_ITEM_SET_GENERATED(item); error=tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_nbd_error, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; if(check_col(pinfo->cinfo, COL_INFO)){ col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response Error:%d", (nbd_trans->type==NBD_CMD_WRITE)?"Write":"Read", error); } if(nbd_trans->type==NBD_CMD_READ){ proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA); } break; } return; }
static void dissect_ax25_nol3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree ) { proto_item *ti; proto_tree *ax25_nol3_tree; char *info_buffer; int offset; tvbuff_t *next_tvb = NULL; guint8 dti = 0; gboolean dissected; info_buffer = (char *)wmem_alloc( wmem_packet_scope(), STRLEN ); info_buffer[0] = '\0'; col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25-NoL3"); col_clear( pinfo->cinfo, COL_INFO); offset = 0; g_snprintf( info_buffer, STRLEN, "Text" ); if ( gPREF_APRS ) { dti = tvb_get_guint8( tvb, offset ); if ( isaprs( dti ) ) g_snprintf( info_buffer, STRLEN, "APRS" ); } if ( gPREF_DX ) { if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' ) g_snprintf( info_buffer, STRLEN, "DX cluster" ); } col_add_str( pinfo->cinfo, COL_INFO, info_buffer ); /* Call sub-dissectors here */ if ( parent_tree ) { /* create display subtree for the protocol */ ti = proto_tree_add_protocol_format( parent_tree, proto_ax25_nol3, tvb, 0, -1, "AX.25 No Layer 3 - (%s)", info_buffer ); ax25_nol3_tree = proto_item_add_subtree( ti, ett_ax25_nol3 ); next_tvb = tvb_new_subset_remaining(tvb, offset); dissected = FALSE; if ( gPREF_APRS ) { if ( isaprs( dti ) ) { dissected = TRUE; call_dissector( aprs_handle , next_tvb, pinfo, ax25_nol3_tree ); } } if ( gPREF_DX ) { if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' ) { dissected = TRUE; dissect_dx( next_tvb, pinfo, ax25_nol3_tree ); } } if ( ! dissected ) call_dissector( default_handle , next_tvb, pinfo, ax25_nol3_tree ); } }
static void dissect_ipvs_syncd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { proto_tree *tree; proto_item *item; int offset = 0; guint8 cnt = 0; int conn = 0; item = proto_tree_add_item(parent_tree, proto_ipvs_syncd, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_ipvs_syncd); col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPVS"); col_clear(pinfo->cinfo, COL_INFO); cnt = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_conn_count, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_syncid, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; for (conn = 0; conn < cnt; conn++) { proto_tree *ctree, *ti; proto_tree *ftree, *fi; guint16 flags; ti = proto_tree_add_text(tree, tvb, offset, 24, "Connection #%d", conn+1); ctree = proto_item_add_subtree(ti, ett_conn); proto_tree_add_item(ctree, hf_resv8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ctree, hf_proto, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ctree, hf_cport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_vport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_dport, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_caddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_vaddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_daddr, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; flags = tvb_get_ntohs(tvb, offset); fi = proto_tree_add_item(ctree, hf_flags, tvb, offset, 2, ENC_BIG_ENDIAN); ftree = proto_item_add_subtree(fi, ett_flags); proto_tree_add_item(ftree, hf_flags_conn_type, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_hashed_entry, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_no_output_packets, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_conn_not_established, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_adjust_output_seq, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_adjust_input_seq, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ftree, hf_flags_no_client_port_set, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(ctree, hf_state, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* we have full connection info */ if ( flags & IP_VS_CONN_F_SEQ_MASK ) { proto_tree_add_item(ctree, hf_in_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_in_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_in_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ctree, hf_out_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } }
static void dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *sap_tree, *s_tree; proto_item *ti, *hidden_item; int cursor; struct sap_query query; guint16 server_type; gchar *server_name; guint16 server_port; guint16 intermediate_network; static const char *sap_type[4] = { "General Query", "General Response", "Nearest Query", "Nearest Response" }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX SAP"); col_clear(pinfo->cinfo, COL_INFO); query.query_type = tvb_get_ntohs(tvb, 0); query.server_type = tvb_get_ntohs(tvb, 2); if (check_col(pinfo->cinfo, COL_INFO)) { if (query.query_type >= 1 && query.query_type <= 4) { col_set_str(pinfo->cinfo, COL_INFO, sap_type[query.query_type - 1]); } else { col_set_str(pinfo->cinfo, COL_INFO, "Unknown Packet Type"); } } if (tree) { ti = proto_tree_add_item(tree, proto_sap, tvb, 0, -1, ENC_NA); sap_tree = proto_item_add_subtree(ti, ett_ipxsap); if (query.query_type >= 1 && query.query_type <= 4) { proto_tree_add_text(sap_tree, tvb, 0, 2, "%s", sap_type[query.query_type - 1]); if ((query.query_type - 1) % 2) { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_response, tvb, 0, 2, 1); } else { hidden_item = proto_tree_add_boolean(sap_tree, hf_sap_request, tvb, 0, 2, 1); } PROTO_ITEM_SET_HIDDEN(hidden_item); } else { proto_tree_add_text(sap_tree, tvb, 0, 2, "Unknown SAP Packet Type %d", query.query_type); } if (query.query_type == IPX_SAP_GENERAL_RESPONSE || query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */ int available_length = tvb_reported_length(tvb); for (cursor = 2; (cursor + 64) <= available_length; cursor += 64) { server_type = tvb_get_ntohs(tvb, cursor); server_name = tvb_format_stringzpad(tvb, cursor+2, 48); ti = proto_tree_add_text(sap_tree, tvb, cursor+2, 48, "Server Name: %s", server_name); s_tree = proto_item_add_subtree(ti, ett_ipxsap_server); proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(server_type, &novell_server_vals_ext, "Unknown"), server_type); proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s", ipxnet_to_string(tvb_get_ptr(tvb, cursor+50, 4))); proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s", tvb_ether_to_str(tvb, cursor+54)); server_port = tvb_get_ntohs(tvb, cursor+60); proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)", socket_text(server_port), server_port); intermediate_network = tvb_get_ntohs(tvb, cursor+62); proto_tree_add_text(s_tree, tvb, cursor+62, 2, "Intermediate Networks: %d", intermediate_network); } } else { /* queries */ proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)", val_to_str_ext_const(query.server_type, &novell_server_vals_ext, "Unknown"), query.server_type); } } }
static void dissect_ipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_tree *ipx_tree = NULL; proto_item *ti = NULL, *hidden_item; const guint8 *src_net_node, *dst_net_node; guint8 ipx_hops; char *str; guint16 first_socket, second_socket; guint32 ipx_snet, ipx_dnet; static ipxhdr_t ipxh_arr[4]; static int ipx_current=0; ipxhdr_t *ipxh; ipx_current++; if(ipx_current==4){ ipx_current=0; } ipxh=&ipxh_arr[ipx_current]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX"); col_clear(pinfo->cinfo, COL_INFO); /* Calculate here for use in pinfo and in tree */ ipxh->ipx_dsocket = tvb_get_ntohs(tvb, 16); ipxh->ipx_ssocket = tvb_get_ntohs(tvb, 28); ipxh->ipx_type = tvb_get_guint8(tvb, 5); ipxh->ipx_length = tvb_get_ntohs(tvb, 2); pinfo->ptype = PT_IPX; pinfo->srcport = ipxh->ipx_ssocket; pinfo->destport = ipxh->ipx_dsocket; /* Adjust the tvbuff length to include only the IPX datagram. */ set_actual_length(tvb, ipxh->ipx_length); src_net_node = tvb_get_ptr(tvb, 18, 10); dst_net_node = tvb_get_ptr(tvb, 6, 10); SET_ADDRESS(&pinfo->net_src, AT_IPX, 10, src_net_node); SET_ADDRESS(&pinfo->src, AT_IPX, 10, src_net_node); SET_ADDRESS(&ipxh->ipx_src, AT_IPX, 10, src_net_node); SET_ADDRESS(&pinfo->net_dst, AT_IPX, 10, dst_net_node); SET_ADDRESS(&pinfo->dst, AT_IPX, 10, dst_net_node); SET_ADDRESS(&ipxh->ipx_dst, AT_IPX, 10, dst_net_node); if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%04x)", socket_text(ipxh->ipx_dsocket), ipxh->ipx_dsocket); if (tree) { ti = proto_tree_add_item(tree, proto_ipx, tvb, 0, IPX_HEADER_LEN, ENC_NA); ipx_tree = proto_item_add_subtree(ti, ett_ipx); } str=ep_address_to_str(&pinfo->net_src); hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_src, tvb, 0, 0, str); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str); PROTO_ITEM_SET_HIDDEN(hidden_item); str=ep_address_to_str(&pinfo->net_dst); hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_dst, tvb, 0, 0, str); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_item(ipx_tree, hf_ipx_checksum, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_uint_format(ipx_tree, hf_ipx_len, tvb, 2, 2, ipxh->ipx_length, "Length: %d bytes", ipxh->ipx_length); ipx_hops = tvb_get_guint8(tvb, 4); proto_tree_add_uint_format(ipx_tree, hf_ipx_hops, tvb, 4, 1, ipx_hops, "Transport Control: %d hops", ipx_hops); proto_tree_add_uint(ipx_tree, hf_ipx_packet_type, tvb, 5, 1, ipxh->ipx_type); /* Destination */ ipx_dnet = tvb_get_ntohl(tvb, 6); proto_tree_add_ipxnet(ipx_tree, hf_ipx_dnet, tvb, 6, 4, ipx_dnet); hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 6, 4, ipx_dnet); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_item(ipx_tree, hf_ipx_dnode, tvb, 10, 6, ENC_NA); hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 10, 6, ENC_NA); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint(ipx_tree, hf_ipx_dsocket, tvb, 16, 2, ipxh->ipx_dsocket); hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 16, 2, ipxh->ipx_dsocket); PROTO_ITEM_SET_HIDDEN(hidden_item); /* Source */ ipx_snet = tvb_get_ntohl(tvb, 18); proto_tree_add_ipxnet(ipx_tree, hf_ipx_snet, tvb, 18, 4, ipx_snet); hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 18, 4, ipx_snet); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_item(ipx_tree, hf_ipx_snode, tvb, 22, 6, ENC_NA); hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 22, 6, ENC_NA); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint(ipx_tree, hf_ipx_ssocket, tvb, 28, 2, ipxh->ipx_ssocket); hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 28, 2, ipxh->ipx_ssocket); PROTO_ITEM_SET_HIDDEN(hidden_item); /* Make the next tvbuff */ next_tvb = tvb_new_subset_remaining(tvb, IPX_HEADER_LEN); /* * Let the subdissector know what type of IPX packet this is. */ pinfo->ipxptype = ipxh->ipx_type; /* * Check the socket numbers before we check the packet type; * we've seen non-NCP packets with a type of NCP and a * destination socket of IPX_SOCKET_IPX_MESSAGE, and SAP * packets with a type of NCP and a destination socket of * IPX_SOCKET_SAP. * * We've seen NCP packets with a type of NCP, a source socket of * IPX_SOCKET_NCP, and a destination socket of IPX_SOCKET_IPX_MESSAGE, * and we've seen NCP packets with a type of NCP, a source socket of * IPX_SOCKET_IPX_MESSAGE, and a destination socket of * IPX_SOCKET_NCP, so testing the destination socket first doesn't * always give the right answer. We've also seen SAP packets with * a source socket of IPX_SOCKET_SAP and a destination socket of * IPX_SOCKET_IPX_MESSAGE. * * Unfortunately, we've also seen packets with a source socket * of IPX_SOCKET_NWLINK_SMB_SERVER and a destination socket * of IPX_SOCKET_NWLINK_SMB_NAMEQUERY that were NMPI packets, * not SMB packets, so testing the lower-valued socket first * also doesn't always give the right answer. * * So we start out assuming we should test the lower-numbered * socket number first, but, if the higher-numbered socket is * IPX_SOCKET_NWLINK_SMB_NAMEQUERY, we assume that it's a * NMPI query, and test only that socket. */ if (ipxh->ipx_ssocket > ipxh->ipx_dsocket) { first_socket = ipxh->ipx_dsocket; second_socket = ipxh->ipx_ssocket; } else { first_socket = ipxh->ipx_ssocket; second_socket = ipxh->ipx_dsocket; } tap_queue_packet(ipx_tap, pinfo, ipxh); if (second_socket != IPX_SOCKET_NWLINK_SMB_NAMEQUERY) { if (dissector_try_uint(ipx_socket_dissector_table, first_socket, next_tvb, pinfo, tree)) return; } if (dissector_try_uint(ipx_socket_dissector_table, second_socket, next_tvb, pinfo, tree)) return; /* * Neither of them are known; try the packet type, which will * at least let us, for example, dissect SPX packets as SPX. */ if (dissector_try_uint(ipx_type_dissector_table, ipxh->ipx_type, next_tvb, pinfo, tree)) return; call_dissector(data_handle,next_tvb, pinfo, tree); }
static void dissect_sdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *sdlc_tree; proto_item *sdlc_ti; guint8 addr; guint16 control; int sdlc_header_len; gboolean is_response; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDLC"); col_clear(pinfo->cinfo, COL_INFO); addr = tvb_get_guint8(tvb, 0); sdlc_header_len = 1; /* address */ /* * XXX - is there something in the SDLC header that indicates * how to interpret "command vs. response" based on the * direction? */ if (pinfo->p2p_dir == P2P_DIR_SENT) { is_response = FALSE; col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE"); col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE"); } else { /* XXX - what if the direction is unknown? */ is_response = TRUE; col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE"); col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE"); } if (tree) { sdlc_ti = proto_tree_add_item(tree, proto_sdlc, tvb, 0, -1, ENC_NA); sdlc_tree = proto_item_add_subtree(sdlc_ti, ett_sdlc); proto_tree_add_uint(sdlc_tree, hf_sdlc_address, tvb, 0, 1, addr); } else { sdlc_ti = NULL; sdlc_tree = NULL; } /* * XXX - SDLC has a mod-128 mode as well as a mod-7 mode. * We can infer the mode from an SNRM/SRME frame, but if * we don't see one of them, we may have to have a preference * to control what to use. */ control = dissect_xdlc_control(tvb, 1, pinfo, sdlc_tree, hf_sdlc_control, ett_sdlc_control, &sdlc_cf_items, NULL, NULL, NULL, is_response, FALSE, FALSE); sdlc_header_len += XDLC_CONTROL_LEN(control, FALSE); if (tree) proto_item_set_len(sdlc_ti, sdlc_header_len); /* * XXX - is there an FCS at the end, at least in Sniffer * captures? (There doesn't appear to be.) */ next_tvb = tvb_new_subset_remaining(tvb, sdlc_header_len); if (XDLC_IS_INFORMATION(control)) { /* call the SNA dissector */ call_dissector(sna_handle, next_tvb, pinfo, tree); } else call_dissector(data_handle, next_tvb, pinfo, tree); }
/* * Dissect X518 PDUs inside a ROS PDUs */ static void dissect_dsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { int offset = 0; int old_offset; proto_item *item=NULL; proto_tree *tree=NULL; int (*dsp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL; const char *dsp_op_name; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* do we have operation information from the ROS dissector? */ if( !pinfo->private_data ){ if(parent_tree){ proto_tree_add_text(parent_tree, tvb, offset, -1, "Internal error: can't get operation information from ROS dissector."); } return ; } else { session = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) ); } if(parent_tree){ item = proto_tree_add_item(parent_tree, proto_dsp, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_dsp); } col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAP"); col_clear(pinfo->cinfo, COL_INFO); switch(session->ros_op & ROS_OP_MASK) { case (ROS_OP_BIND | ROS_OP_ARGUMENT): /* BindInvoke */ dsp_dissector = dissect_dsp_DSASystemBindArgument; dsp_op_name = "System-Bind-Argument"; break; case (ROS_OP_BIND | ROS_OP_RESULT): /* BindResult */ dsp_dissector = dissect_dsp_DSASystemBindResult; dsp_op_name = "System-Bind-Result"; break; case (ROS_OP_BIND | ROS_OP_ERROR): /* BindError */ dsp_dissector = dissect_dsp_DSASystemBindError; dsp_op_name = "System-Bind-Error"; break; case (ROS_OP_INVOKE | ROS_OP_ARGUMENT): /* Invoke Argument */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* read */ dsp_dissector = dissect_dsp_ChainedReadArgument; dsp_op_name = "Chained-Read-Argument"; break; case 2: /* compare */ dsp_dissector = dissect_dsp_ChainedCompareArgument; dsp_op_name = "Chained-Compare-Argument"; break; case 3: /* abandon */ dsp_dissector = dissect_dsp_ChainedAbandonArgument; dsp_op_name = "Chained-Abandon-Argument"; break; case 4: /* list */ dsp_dissector = dissect_dsp_ChainedListArgument; dsp_op_name = "Chained-List-Argument"; break; case 5: /* search */ dsp_dissector = dissect_dsp_ChainedSearchArgument; dsp_op_name = "Chained-Search-Argument"; break; case 6: /* addEntry */ dsp_dissector = dissect_dsp_ChainedAddEntryArgument; dsp_op_name = "Chained-Add-Entry-Argument"; break; case 7: /* removeEntry */ dsp_dissector = dissect_dsp_ChainedRemoveEntryArgument; dsp_op_name = "Chained-Remove-Entry-Argument"; break; case 8: /* modifyEntry */ dsp_dissector = dissect_dsp_ChainedModifyEntryArgument; dsp_op_name = "ChainedModify-Entry-Argument"; break; case 9: /* modifyDN */ dsp_dissector = dissect_dsp_ChainedModifyDNArgument; dsp_op_name = "ChainedModify-DN-Argument"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; case (ROS_OP_INVOKE | ROS_OP_RESULT): /* Return Result */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* read */ dsp_dissector = dissect_dsp_ChainedReadResult; dsp_op_name = "Chained-Read-Result"; break; case 2: /* compare */ dsp_dissector = dissect_dsp_ChainedCompareResult; dsp_op_name = "Chained-Compare-Result"; break; case 3: /* abandon */ dsp_dissector = dissect_dsp_ChainedAbandonResult; dsp_op_name = "Chained-Abandon-Result"; break; case 4: /* list */ dsp_dissector = dissect_dsp_ChainedListResult; dsp_op_name = "Chained-List-Result"; break; case 5: /* search */ dsp_dissector = dissect_dsp_ChainedSearchResult; dsp_op_name = "Chained-Search-Result"; break; case 6: /* addEntry */ dsp_dissector = dissect_dsp_ChainedAddEntryResult; dsp_op_name = "Chained-Add-Entry-Result"; break; case 7: /* removeEntry */ dsp_dissector = dissect_dsp_ChainedRemoveEntryResult; dsp_op_name = "Chained-Remove-Entry-Result"; break; case 8: /* modifyEntry */ dsp_dissector = dissect_dsp_ChainedModifyEntryResult; dsp_op_name = "Chained-Modify-Entry-Result"; break; case 9: /* modifyDN */ dsp_dissector = dissect_dsp_ChainedModifyDNResult; dsp_op_name = "ChainedModify-DN-Result"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP opcode"); break; } break; case (ROS_OP_INVOKE | ROS_OP_ERROR): /* Return Error */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 1: /* attributeError */ dsp_dissector = dissect_dap_AttributeError; dsp_op_name = "Attribute-Error"; break; case 2: /* nameError */ dsp_dissector = dissect_dap_NameError; dsp_op_name = "Name-Error"; break; case 3: /* serviceError */ dsp_dissector = dissect_dap_ServiceError; dsp_op_name = "Service-Error"; break; case 4: /* referral */ dsp_dissector = dissect_dap_Referral; dsp_op_name = "Referral"; break; case 5: /* abandoned */ dsp_dissector = dissect_dap_Abandoned; dsp_op_name = "Abandoned"; break; case 6: /* securityError */ dsp_dissector = dissect_dap_SecurityError; dsp_op_name = "Security-Error"; break; case 7: /* abandonFailed */ dsp_dissector = dissect_dap_AbandonFailedError; dsp_op_name = "Abandon-Failed-Error"; break; case 8: /* updateError */ dsp_dissector = dissect_dap_UpdateError; dsp_op_name = "Update-Error"; break; case 9: /* DSAReferral */ dsp_dissector = dissect_dsp_DSAReferral; dsp_op_name = "DSA-Referral"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP errcode"); break; } break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP PDU"); return; } if(dsp_dissector) { col_set_str(pinfo->cinfo, COL_INFO, dsp_op_name); while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=(*dsp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1); if(offset == old_offset){ proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DSP PDU"); break; } } } }
static void dissect_exec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *exec_tree=NULL; /* Variables for extracting and displaying data from the packet */ guchar *field_stringz; /* Temporary storage for each field we extract */ gint length; guint offset = 0; conversation_t *conversation; exec_hash_entry_t *hash_info; conversation = find_or_create_conversation(pinfo); /* Retrieve information from conversation * or add it if it isn't there yet */ hash_info = conversation_get_proto_data(conversation, proto_exec); if(!hash_info) { hash_info = se_alloc(sizeof(exec_hash_entry_t)); hash_info->first_packet_number = pinfo->fd->num; hash_info->second_packet_number = 0; hash_info->third_packet_number = 0; hash_info->fourth_packet_number = 0; hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */ /* Start with empty username and command strings */ hash_info->username=NULL; hash_info->command=NULL; /* These will be set on the first pass by the first * four packets of the conversation */ hash_info->first_packet_state = NONE; hash_info->second_packet_state = NONE; hash_info->third_packet_state = NONE; hash_info->fourth_packet_state = NONE; conversation_add_proto_data(conversation, proto_exec, hash_info); } /* Store the number of the first three packets of this conversation * as we reach them the first time */ if(!hash_info->second_packet_number && pinfo->fd->num > hash_info->first_packet_number) { /* We're on the second packet of the conversation */ hash_info->second_packet_number = pinfo->fd->num; } else if(hash_info->second_packet_number && !hash_info->third_packet_number && pinfo->fd->num > hash_info->second_packet_number) { /* We're on the third packet of the conversation */ hash_info->third_packet_number = pinfo->fd->num; } else if(hash_info->third_packet_number && !hash_info->fourth_packet_number && pinfo->fd->num > hash_info->third_packet_number) { /* We're on the fourth packet of the conversation */ hash_info->fourth_packet_number = pinfo->fd->num; } /* Save this packet's state so we can retrieve it if this packet * is selected again later. If the packet's state was already stored, * then retrieve it */ if(pinfo->fd->num == hash_info->first_packet_number) { if(hash_info->first_packet_state == NONE) { hash_info->first_packet_state = hash_info->state; } else { hash_info->state = hash_info->first_packet_state; } } if(pinfo->fd->num == hash_info->second_packet_number) { if(hash_info->second_packet_state == NONE) { hash_info->second_packet_state = hash_info->state; } else { hash_info->state = hash_info->second_packet_state; } } if(pinfo->fd->num == hash_info->third_packet_number) { if(hash_info->third_packet_state == NONE) { hash_info->third_packet_state = hash_info->state; } else { hash_info->state = hash_info->third_packet_state; } } if(pinfo->fd->num == hash_info->fourth_packet_number) { if(hash_info->fourth_packet_state == NONE) { hash_info->fourth_packet_state = hash_info->state; } else { hash_info->state = hash_info->fourth_packet_state; } } col_set_str(pinfo->cinfo, COL_PROTOCOL, "EXEC"); if(check_col(pinfo->cinfo, COL_INFO)) { /* First, clear the info column */ col_clear(pinfo->cinfo, COL_INFO); /*username */ if(hash_info->username && preference_info_show_username == TRUE) { col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username); } /* Command */ if(hash_info->command && preference_info_show_command == TRUE) { col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command); } } /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, ENC_NA); exec_tree = proto_item_add_subtree(ti, ett_exec); /* If this packet doesn't end with a null terminated string, * then it must be session data only and we can skip looking * for the other fields. */ if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1) { hash_info->state = WAIT_FOR_DATA; } if(hash_info->state == WAIT_FOR_STDERR_PORT && tvb_length_remaining(tvb, offset)) { field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the stderr_port field. * It is optional, so it may only be 1 character long * (the NULL) */ if(length == 1 || (isdigit_string(field_stringz) && length <= EXEC_STDERR_PORT_LEN)) { proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_USERNAME; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_USERNAME && tvb_length_remaining(tvb, offset)) { field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the username field */ if(length != 1 && length <= EXEC_USERNAME_LEN && isprint_string(field_stringz)) { proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz); /* Store the username so we can display it in the * info column of the entire conversation */ if(!hash_info->username) { hash_info->username=se_strdup((gchar*)field_stringz); } /* Next field we need */ hash_info->state = WAIT_FOR_PASSWORD; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; } if(hash_info->state == WAIT_FOR_PASSWORD && tvb_length_remaining(tvb, offset)) { field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the password field */ if(length != 1 && length <= EXEC_PASSWORD_LEN && isprint_string(field_stringz)) { proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz); /* Next field we need */ hash_info->state = WAIT_FOR_COMMAND; } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } /* Used if the next field is in the same packet */ offset += length; /* Next field we are looking for */ hash_info->state = WAIT_FOR_COMMAND; } if(hash_info->state == WAIT_FOR_COMMAND && tvb_length_remaining(tvb, offset)) { field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length); /* Check if this looks like the command field */ if(length != 1 && length <= EXEC_COMMAND_LEN && isprint_string(field_stringz)) { proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz); /* Store the command so we can display it in the * info column of the entire conversation */ if(!hash_info->command) { hash_info->command=se_strdup((gchar*)field_stringz); } } else { /* Since the data doesn't match this field, it must be data only */ hash_info->state = WAIT_FOR_DATA; } } if(hash_info->state == WAIT_FOR_DATA && tvb_length_remaining(tvb, offset)) { if(pinfo->destport == EXEC_PORT) { /* Packet going to the server */ /* offset = 0 since the whole packet is data */ proto_tree_add_text(exec_tree, tvb, 0, -1, "Client -> Server Data"); col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data"); } else { /* This packet must be going back to the client */ /* offset = 0 since the whole packet is data */ proto_tree_add_text(exec_tree, tvb, 0, -1, "Server -> Client Data"); col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data"); } } /* We haven't seen all of the fields yet */ if(hash_info->state < WAIT_FOR_DATA) { col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment"); } }
static void dissect_tzsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *tzsp_tree = NULL; proto_item *ti = NULL; int pos = 0; tvbuff_t *next_tvb; guint16 encapsulation = 0; int wtap_encap; dissector_handle_t encap_dissector; const char *encap_name; const char *info; guint8 type; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TZSP"); col_clear(pinfo->cinfo, COL_INFO); type = tvb_get_guint8(tvb, 1); /* Find the dissector. */ encapsulation = tvb_get_ntohs(tvb, 2); if (encapsulation != 0) { wtap_encap = tzsp_encap_to_wtap_encap(encapsulation); if ((wtap_encap != -1) && (encap_dissector = dissector_get_uint_handle(encap_dissector_table, wtap_encap))) { encap_name = dissector_handle_get_short_name(encap_dissector); } else { encap_name = "Unknown"; } info = encap_name; } else { wtap_encap = -1; encap_name = "Nothing"; info = val_to_str(type, tzsp_type, "Unknown (%u)"); } col_add_str(pinfo->cinfo, COL_INFO, info); if (tree) { /* Adding TZSP item and subtree */ ti = proto_tree_add_protocol_format(tree, proto_tzsp, tvb, 0, -1, "TZSP: %s: ", info); tzsp_tree = proto_item_add_subtree(ti, ett_tzsp); proto_tree_add_item (tzsp_tree, hf_tzsp_version, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_uint (tzsp_tree, hf_tzsp_type, tvb, 1, 1, type); proto_tree_add_uint_format (tzsp_tree, hf_tzsp_encap, tvb, 2, 2, encapsulation, "Encapsulates: %s (%d)", encap_name, encapsulation); } /* * XXX - what about TZSP_CONFIG frames? * * The MIB at * * http://web.archive.org/web/20021221195733/http://www.networkchemistry.com/support/appnotes/SENSOR-MIB * * seems to indicate that you can configure the probe using SNMP; * does TZSP_CONFIG also support that? An old version of Kismet * included code to control a Network Chemistry WSP100 sensor: * * https://www.kismetwireless.net/code-old/svn/tags/kismet-2004-02-R1/wsp100source.cc * * and it used SNMP to configure the probe. */ if ((type != TZSP_NULL) && (type != TZSP_PORT)) { pos = add_option_info(tvb, 4, tzsp_tree, ti); if (tree) proto_item_set_end(ti, tvb, pos); next_tvb = tvb_new_subset_remaining(tvb, pos); if ((encapsulation != 0) && ((wtap_encap == -1) || !dissector_try_uint(encap_dissector_table, wtap_encap, next_tvb, pinfo, tree))) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN"); col_add_fstr(pinfo->cinfo, COL_INFO, "TZSP_ENCAP = %u", encapsulation); call_dissector(data_handle, next_tvb, pinfo, tree); } } }
static void dissect_interlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_tree *il_tree = NULL; proto_tree *ilh_tree = NULL; proto_tree *ilb_tree = NULL; guint8 ilb_type; guint8 ilb_version; guint16 type_version = 0; dissector_handle_t handle; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "INTERLINK"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *il_item; il_item = proto_tree_add_item(tree, proto_interlink, tvb, 0, 16, FALSE); if (il_item) il_tree = proto_item_add_subtree(il_item, ett_interlink); } if (il_tree) { proto_item *ilh_item = NULL; ilh_item = proto_tree_add_text(il_tree, tvb, 0, 12, "Interlink Header"); if (ilh_item) ilh_tree = proto_item_add_subtree(ilh_item, ett_interlink_header); } if (ilh_tree) { proto_tree_add_item(ilh_tree, hf_interlink_id, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ilh_tree, hf_interlink_version, tvb, offset, 2, TRUE); offset += 2; proto_tree_add_item(ilh_tree, hf_interlink_cmd, tvb, offset, 2, TRUE); offset += 2; proto_tree_add_item(ilh_tree, hf_interlink_seq, tvb, offset, 2, TRUE); offset += 2; } else { offset += 10; } if (ilh_tree) { proto_item *flags_item; proto_tree *flags_tree = NULL; flags_item = proto_tree_add_item(ilh_tree, hf_interlink_flags, tvb, offset, 2, TRUE); if (flags_item) { flags_tree = proto_item_add_subtree(flags_item, ett_interlink_flags); } if (flags_tree) { guint16 il_flags; il_flags = tvb_get_letohs(tvb, offset); proto_tree_add_boolean(flags_tree, hf_interlink_flags_req_ack, tvb, offset, 2, il_flags); proto_tree_add_boolean(flags_tree, hf_interlink_flags_inc_ack_port, tvb, offset, 2, il_flags); } } offset += 2; if (tree) { proto_item *ilb_item; ilb_item = proto_tree_add_text(il_tree, tvb, offset, 4, "Block Header"); if (ilb_item) ilb_tree = proto_item_add_subtree(ilb_item, ett_interlink_block); } ilb_type = tvb_get_guint8(tvb, offset); ilb_version = tvb_get_guint8(tvb, offset + 1); type_version = ilb_type << 8 | ilb_version; col_append_fstr(pinfo->cinfo, COL_INFO, "Type: 0x%02x, Version: %d", ilb_type, ilb_version); if (ilb_tree) { proto_tree_add_item(ilb_tree, hf_interlink_block_type, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(ilb_tree, hf_interlink_block_version, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(ilb_tree, hf_interlink_block_length, tvb, offset, 2, TRUE); offset += 2; } else { offset += 4; } /* Generate a new tvb for the rest. */ next_tvb = tvb_new_subset_remaining(tvb, offset); /* Probably a sub-dissector exists for this type/version combination. */ handle = dissector_get_port_handle(subdissector_table, type_version); /* Without a proper sub-dissector, we use "data". */ if (handle == NULL) handle = data_handle; /* Call the sub-dissector. */ call_dissector(handle, next_tvb, pinfo, tree); }
static void dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *omapi_tree; ptvcursor_t* cursor; guint32 authlength; guint32 msglength; guint32 objlength; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OMAPI"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA); omapi_tree = proto_item_add_subtree(ti, ett_omapi); cursor = ptvcursor_new(omapi_tree, tvb, 0); if (tvb_reported_length_remaining(tvb, 0) < 8) { /* Payload too small for OMAPI */ DISSECTOR_ASSERT_NOT_REACHED(); } else if (tvb_reported_length_remaining(tvb, 0) < 24) { /* This is a startup message */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_set_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); return; } else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) ) { /* This is a startup message, and more */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_append_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); } ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN); authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); proto_item_append_text(ti, ", Opcode: %s", val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN); msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (msglength) { ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII|ENC_NA); msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN); if (msglength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (msglength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII|ENC_NA); } msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Message end tag"); ptvcursor_advance(cursor, 2); objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (objlength) { ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII|ENC_NA); objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN); if (objlength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (objlength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA); } objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Object end tag"); ptvcursor_advance(cursor, 2); if (authlength > 0) { ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA); } }
/* ================================================================= */ static void dissect_ipxrip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *rip_tree; proto_item *ti, *hidden_item; guint16 operation; ipx_rt_def_t route; int cursor; int available_length; static const char *rip_type[3] = { "Request", "Response", "Unknown" }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX RIP"); col_clear(pinfo->cinfo, COL_INFO); operation = tvb_get_ntohs(tvb, 0) - 1; if (check_col(pinfo->cinfo, COL_INFO)) { /* rip_types 0 and 1 are valid, anything else becomes 2 or "Unknown" */ col_set_str(pinfo->cinfo, COL_INFO, rip_type[MIN(operation, 2)]); } if (tree) { ti = proto_tree_add_item(tree, proto_ipxrip, tvb, 0, -1, ENC_NA); rip_tree = proto_item_add_subtree(ti, ett_ipxrip); if (operation < 2) { proto_tree_add_text(rip_tree, tvb, 0, 2, "RIP packet type: %s", rip_type[operation]); if (operation == 0) { hidden_item = proto_tree_add_boolean(rip_tree, hf_ipxrip_request, tvb, 0, 2, 1); } else { hidden_item = proto_tree_add_boolean(rip_tree, hf_ipxrip_response, tvb, 0, 2, 1); } PROTO_ITEM_SET_HIDDEN(hidden_item); } else { proto_tree_add_text(rip_tree, tvb, 0, 2, "Unknown RIP packet type"); } available_length = tvb_reported_length(tvb); for (cursor = 2; cursor < available_length; cursor += 8) { tvb_memcpy(tvb, (guint8 *)&route.network, cursor, 4); route.hops = tvb_get_ntohs(tvb, cursor+4); route.ticks = tvb_get_ntohs(tvb, cursor+6); if (operation == IPX_RIP_REQUEST - 1) { proto_tree_add_text(rip_tree, tvb, cursor, 8, "Route Vector: %s, %d hop%s, %d tick%s", ipxnet_to_string((guint8*)&route.network), route.hops, route.hops == 1 ? "" : "s", route.ticks, route.ticks == 1 ? "" : "s"); } else { proto_tree_add_text(rip_tree, tvb, cursor, 8, "Route Vector: %s, %d hop%s, %d tick%s (%d ms)", ipxnet_to_string((guint8*)&route.network), route.hops, route.hops == 1 ? "" : "s", route.ticks, route.ticks == 1 ? "" : "s", route.ticks * 1000 / 18); } } } }
static void dissect_lpd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *lpd_tree; proto_item *ti, *hidden_item; enum lpr_type lpr_packet_type; guint8 code; gint printer_len; /* This information comes from the LPRng HOWTO, which also describes RFC 1179. http://www.astart.com/lprng/LPRng-HOWTO.html */ static const value_string lpd_client_code[] = { { 1, "LPC: start print / jobcmd: abort" }, { 2, "LPR: transfer a printer job / jobcmd: receive control file" }, { 3, "LPQ: print short form of queue status / jobcmd: receive data file" }, { 4, "LPQ: print long form of queue status" }, { 5, "LPRM: remove jobs" }, { 6, "LPRng lpc: do control operation" }, { 7, "LPRng lpr: transfer a block format print job" }, { 8, "LPRng lpc: secure command transfer" }, { 9, "LPRng lpq: verbose status information" }, { 0, NULL } }; static const value_string lpd_server_code[] = { { 0, "Success: accepted, proceed" }, { 1, "Queue not accepting jobs" }, { 2, "Queue temporarily full, retry later" }, { 3, "Bad job format, do not retry" }, { 0, NULL } }; col_set_str(pinfo->cinfo, COL_PROTOCOL, "LPD"); col_clear(pinfo->cinfo, COL_INFO); /* rfc1179 states that all responses are 1 byte long */ code = tvb_get_guint8(tvb, 0); if (tvb_reported_length(tvb) == 1) { lpr_packet_type = response; } else if (code <= 9) { lpr_packet_type = request; } else { lpr_packet_type = unknown; } if (lpr_packet_type == request && code !=0) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(code, lpd_client_code, "Unknown client code: %u")); } else if (lpr_packet_type == response) { col_set_str(pinfo->cinfo, COL_INFO, "LPD response"); } else { col_set_str(pinfo->cinfo, COL_INFO, "LPD continuation"); } if (tree) { ti = proto_tree_add_item(tree, proto_lpd, tvb, 0, -1, ENC_NA); lpd_tree = proto_item_add_subtree(ti, ett_lpd); if (lpr_packet_type == response) { hidden_item = proto_tree_add_boolean(lpd_tree, hf_lpd_response, tvb, 0, 0, TRUE); } else { hidden_item = proto_tree_add_boolean(lpd_tree, hf_lpd_request, tvb, 0, 0, TRUE); } PROTO_ITEM_SET_HIDDEN(hidden_item); if (lpr_packet_type == request) { printer_len = find_printer_string(tvb, 1); if (code <= 9 && printer_len != -1) { proto_tree_add_text(lpd_tree, tvb, 0, 1, "%s", val_to_str(code, lpd_client_code, "Unknown client code: %u")); proto_tree_add_text(lpd_tree, tvb, 1, printer_len, "Printer/options: %s", tvb_format_text(tvb, 1, printer_len)); } else { call_dissector(data_handle,tvb, pinfo, lpd_tree); } } else if (lpr_packet_type == response) { if (code <= 3) { proto_tree_add_text(lpd_tree, tvb, 0, 1, "Response: %s", val_to_str(code, lpd_server_code, "Unknown server code: %u")); } else { call_dissector(data_handle,tvb, pinfo, lpd_tree); } } else { call_dissector(data_handle,tvb, pinfo, lpd_tree); } } }
/* * Dissect RTSE PDUs inside a PPDU. */ static int dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { int offset = 0; int old_offset; proto_item *item; proto_tree *tree; proto_tree *next_tree=NULL; tvbuff_t *next_tvb = NULL; tvbuff_t *data_tvb = NULL; fragment_head *frag_msg = NULL; guint32 fragment_length; guint32 rtse_id = 0; gboolean data_handled = FALSE; struct SESSION_DATA_STRUCTURE* session; conversation_t *conversation = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* save parent_tree so subdissectors can create new top nodes */ top_tree=parent_tree; /* do we have application context from the acse dissector? */ if( data == NULL ){ if(parent_tree){ proto_tree_add_text(parent_tree, tvb, offset, -1, "Internal error:can't get application context from ACSE dissector."); } return 0; } session = ( (struct SESSION_DATA_STRUCTURE*)data); asn1_ctx.private_data = session; col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE"); col_clear(pinfo->cinfo, COL_INFO); if (rtse_reassemble && ((session->spdu_type == SES_DATA_TRANSFER) || (session->spdu_type == SES_MAJOR_SYNC_POINT))) { /* Use conversation index as fragment id */ conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conversation != NULL) { rtse_id = conversation->index; } session->rtse_reassemble = TRUE; } if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) { frag_msg = fragment_end_seq_next (&rtse_reassembly_table, pinfo, rtse_id, NULL); next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE", frag_msg, &rtse_frag_items, NULL, parent_tree); } item = proto_tree_add_item(parent_tree, proto_rtse, next_tvb ? next_tvb : tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_rtse); if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) { /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */ dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hf_rtse_segment_data, &data_tvb); if (data_tvb) { fragment_length = tvb_length_remaining (data_tvb, 0); proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length, plurality(fragment_length, "", "s")); frag_msg = fragment_add_seq_next (&rtse_reassembly_table, data_tvb, 0, pinfo, rtse_id, NULL, fragment_length, TRUE); if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) { /* Add a "Reassembled in" link if not reassembled in this frame */ proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in), data_tvb, 0, 0, frag_msg->reassembled_in); } pinfo->fragmented = TRUE; data_handled = TRUE; } else { fragment_length = tvb_length_remaining (tvb, offset); } col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE fragment, %u byte%s]", fragment_length, plurality(fragment_length, "", "s")); } else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) { if (next_tvb) { /* ROS won't do this for us */ session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT); offset=dissect_ber_external_type(FALSE, tree, next_tvb, 0, &asn1_ctx, -1, call_rtse_external_type_callback); } else { offset = tvb_length (tvb); } pinfo->fragmented = FALSE; data_handled = TRUE; } if (!data_handled) { while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1); if(offset == old_offset){ item = proto_tree_add_text(tree, tvb, offset, -1, "Unknown RTSE PDU"); expert_add_info (pinfo, item, &ei_rtse_unknown_rtse_pdu); next_tree=proto_item_add_subtree(item, ett_rtse_unknown); dissect_unknown_ber(pinfo, tvb, offset, next_tree); break; } } } top_tree = NULL; return tvb_length(tvb); }
static void dissect_hdfs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; int success = 0; guint length = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDFS"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); if (tree) { proto_item *ti = NULL; proto_tree *hdfs_tree = NULL; ti = proto_tree_add_item(tree, proto_hdfs, tvb, 0, -1, ENC_NA); hdfs_tree = proto_item_add_subtree(ti, ett_hdfs); /* Response */ if (pinfo->srcport == tcp_port) { /* 4 bytes = sequence number */ proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* 4 bytes = status -> 0000 = success, 0001 = error, ffff = fatal */ success = tvb_get_ntohl(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_success, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (success != 0) { return; } if (!tvb_memeql(tvb, offset + 2, "long", 4)) { dissect_resp_long (tvb, hdfs_tree, offset); } else { /* name length = 2 B */ length = tvb_get_ntohs(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* length bytes = method name */ proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; /* get length that we just dissected */ length = tvb_get_ntohs(tvb, offset); /* 2 bytes = objects length */ proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* length bytes = object name */ proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; /* responses about block location info */ if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.LocatedBlocks", length)) { dissect_resp_locatedblocks (tvb, hdfs_tree, offset); /* responses about file statuses */ } else if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.HdfsFileStatus", length)) { dissect_resp_filestatus (tvb, hdfs_tree, offset); } else { /* get length */ length = tvb_get_ntohs(tvb, offset); /* 2 bytes = parameter value length */ proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* the value of the parameter */ proto_tree_add_item(hdfs_tree, hf_hdfs_paramval, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; } } /* Request to namenode */ } else { /* check the packet length */ guint auth = tvb_get_ntohl(tvb, offset); /* first setup packet starts with "hrpc" */ if (!tvb_memeql(tvb, offset, REQUEST_STR, sizeof(REQUEST_STR) - 1)) { proto_tree_add_item(hdfs_tree, hf_hdfs_sequenceno, tvb, offset, sizeof(REQUEST_STR) - 1, ENC_ASCII|ENC_NA); offset += sizeof(REQUEST_STR) - 1; proto_tree_add_item(hdfs_tree, hf_hdfs_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(hdfs_tree, hf_hdfs_flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { /* second authentication packet */ if (auth + 4 != tvb_reported_length(tvb)) { /* authentication length (read out of first 4 bytes) */ length = tvb_get_ntohl(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_authlen, tvb, offset, 4, ENC_ASCII|ENC_NA); offset += 4; /* authentication (length the number we just got) */ proto_tree_add_item(hdfs_tree, hf_hdfs_auth, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; } /* data packets */ /* 4 bytes = length */ proto_tree_add_item(hdfs_tree, hf_hdfs_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* 4 bytes = sequence number */ proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* dissect packet data */ dissect_data (tvb, hdfs_tree, offset); } } } }
static void dissect_drda(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *drda_tree = NULL; proto_tree *drdaroot_tree = NULL; proto_item *ti = NULL; gint offset = 0; static gint iPreviousFrameNumber = -1; guint16 iCommand; guint16 iLength; guint8 iFormatFlags; guint8 iDSSType; guint8 iDSSFlags; guint16 iParameterCP; proto_tree *drda_tree_sub; gint iLengthParam; col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDA"); if (check_col(pinfo->cinfo, COL_INFO)) { /* This is a trick to know whether this is the first PDU in this packet or not */ if (iPreviousFrameNumber != (gint) pinfo->fd->num) col_clear(pinfo->cinfo, COL_INFO); else col_append_str(pinfo->cinfo, COL_INFO, " | "); } iPreviousFrameNumber = pinfo->fd->num; if (tvb_length(tvb) >= 10) { iCommand = tvb_get_ntohs(tvb, offset + 8); iLength = tvb_get_ntohs(tvb, offset + 0); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, val_to_str(iCommand, drda_opcode_abbr, "Unknown (0x%02x)")); } if (tree) { ti = proto_tree_add_item(tree, proto_drda, tvb, offset, -1, FALSE); proto_item_append_text(ti, " (%s)", val_to_str(iCommand, drda_opcode_vals, "Unknown (0x%02x)")); drdaroot_tree = proto_item_add_subtree(ti, ett_drda); ti = proto_tree_add_text(drdaroot_tree, tvb, offset, 10, DRDA_TEXT_DDM); proto_item_append_text(ti, " (%s)", val_to_str(iCommand, drda_opcode_abbr, "Unknown (0x%02x)")); drda_tree = proto_item_add_subtree(ti, ett_drda_ddm); proto_tree_add_item(drda_tree, hf_drda_ddm_length, tvb, offset + 0, 2, FALSE); proto_tree_add_item(drda_tree, hf_drda_ddm_magic, tvb, offset + 2, 1, FALSE); { drda_tree_sub = NULL; iFormatFlags = tvb_get_guint8(tvb, offset + 3); iDSSType = iFormatFlags & 0x0F; iDSSFlags = iFormatFlags >> 4; ti = proto_tree_add_item(drda_tree, hf_drda_ddm_format, tvb, offset + 3, 1, FALSE); drda_tree_sub = proto_item_add_subtree(ti, ett_drda_ddm_format); proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_reserved, tvb, offset + 3, 1, iDSSFlags); proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_chained, tvb, offset + 3, 1, iDSSFlags); proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_errcont, tvb, offset + 3, 1, iDSSFlags); proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_samecorr, tvb, offset + 3, 1, iDSSFlags); proto_tree_add_uint(drda_tree_sub, hf_drda_ddm_fmt_dsstyp, tvb, offset + 3, 1, iDSSType); } proto_tree_add_item(drda_tree, hf_drda_ddm_rc, tvb, offset + 4, 2, FALSE); proto_tree_add_item(drda_tree, hf_drda_ddm_length2, tvb, offset + 6, 2, FALSE); proto_tree_add_item(drda_tree, hf_drda_ddm_codepoint, tvb, offset + 8, 2, FALSE); /* The number of attributes is variable */ for (offset = 10; offset <= iLength; ) { if (tvb_length_remaining(tvb, offset) >= 2) { iLengthParam = tvb_get_ntohs(tvb, offset + 0); if (iLengthParam == 0 || iLengthParam == 1) iLengthParam = iLength - 10; if (tvb_length_remaining(tvb, offset) >= iLengthParam) { drda_tree_sub = NULL; iParameterCP = tvb_get_ntohs(tvb, offset + 2); ti = proto_tree_add_text(drdaroot_tree, tvb, offset, iLengthParam, DRDA_TEXT_PARAM); proto_item_append_text(ti, " (%s)", val_to_str(iParameterCP, drda_opcode_vals, "Unknown (0x%02x)")); drda_tree_sub = proto_item_add_subtree(ti, ett_drda_param); proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, FALSE); proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, FALSE); proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, FALSE); proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, FALSE); if (iCommand == DRDA_CP_SQLSTT) { /* Extract SQL statement from packet */ tvbuff_t* next_tvb = NULL; next_tvb = tvb_new_subset(tvb, offset + 4, iLengthParam - 4, iLengthParam - 4); add_new_data_source(pinfo, next_tvb, "SQL statement"); proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement, next_tvb, 0, iLengthParam - 5, FALSE); proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement_ebcdic, next_tvb, 0, iLengthParam - 4, FALSE); } } offset += iLengthParam; } else { break; } } } }
void xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet) { proto_item *message_item; proto_tree *message_tree; const gchar *type_enums[] = {"chat", "error", "groupchat", "headline", "normal"}; xmpp_array_t *type_array = xmpp_ep_init_array_t(type_enums, array_length(type_enums)); xmpp_attr_info attrs_info[] = { {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL}, {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL}, {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL}, {"type", hf_xmpp_type, FALSE, TRUE, xmpp_val_enum_list, type_array}, {"xml:lang",-1, FALSE, FALSE, NULL,NULL}, {"chatstate", hf_xmpp_message_chatstate, FALSE, TRUE, NULL, NULL} }; xmpp_elem_info elems_info [] = { {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE}, {NAME, "thread", xmpp_message_thread, ONE}, {NAME, "body", xmpp_message_body, MANY}, {NAME, "subject", xmpp_message_subject, MANY}, {NAME, "delay", xmpp_delay, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","jabber:x:event"), xmpp_x_event, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE}, {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","google:nosave"), xmpp_gtalk_nosave_x, ONE}, {NAME, "error", xmpp_error, ONE} }; xmpp_element_t *chatstate; xmpp_attr_t *id; conversation_t *conversation; xmpp_conv_info_t *xmpp_info; col_clear(pinfo->cinfo, COL_INFO); col_append_fstr(pinfo->cinfo, COL_INFO, "MESSAGE "); id = xmpp_get_attr(packet, "id"); conversation = find_or_create_conversation(pinfo); xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp); message_item = proto_tree_add_item(tree, hf_xmpp_message, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN); message_tree = proto_item_add_subtree(message_item, ett_xmpp_message); if((chatstate = xmpp_steal_element_by_attr(packet, "xmlns", "http://jabber.org/protocol/chatstates"))!=NULL) { xmpp_attr_t *fake_chatstate_attr = xmpp_ep_init_attr_t(chatstate->name, chatstate->offset, chatstate->length); g_hash_table_insert(packet->attrs, (gpointer)"chatstate", fake_chatstate_attr); } xmpp_display_attrs(message_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info)); xmpp_display_elems(message_tree, packet, pinfo, tvb, elems_info, array_length(elems_info)); /*Displays data about IBB session*/ if(xmpp_info && id) { gchar *ibb_sid; ibb_sid = (gchar *)se_tree_lookup_string(xmpp_info->ibb_sessions, id->value, EMEM_TREE_STRING_NOCASE); if (ibb_sid) { proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid); PROTO_ITEM_SET_GENERATED(it); } } }
static void dissect_netrom_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *netrom_tree; int offset; const guint8 *src_addr; const guint8 *dst_addr; const guint8 *user_addr; const guint8 *node_addr; #if 0 guint8 src_ssid; guint8 dst_ssid; #endif guint8 op_code; guint8 cct_index; guint8 cct_id; void *saved_private_data; tvbuff_t *next_tvb = NULL; col_set_str( pinfo->cinfo, COL_PROTOCOL, "NET/ROM" ); col_clear( pinfo->cinfo, COL_INFO ); offset = 0; /* source */ src_addr = tvb_get_ptr( tvb, offset, AX25_ADDR_LEN ); SET_ADDRESS(&pinfo->dl_src, AT_AX25, AX25_ADDR_LEN, src_addr); SET_ADDRESS(&pinfo->src, AT_AX25, AX25_ADDR_LEN, src_addr); /* src_ssid = *(src_addr + 6); */ offset += AX25_ADDR_LEN; /* step over src addr */ /* destination */ dst_addr = tvb_get_ptr( tvb, offset, AX25_ADDR_LEN ); SET_ADDRESS(&pinfo->dl_dst, AT_AX25, AX25_ADDR_LEN, dst_addr); SET_ADDRESS(&pinfo->dst, AT_AX25, AX25_ADDR_LEN, dst_addr); /* dst_ssid = *(dst_addr + 6); */ offset += AX25_ADDR_LEN; /* step over dst addr */ offset += 1; /* step over ttl */ cct_index = tvb_get_guint8( tvb, offset ); offset += 1; /* step over cct index*/ cct_id = tvb_get_guint8( tvb, offset ); offset += 1; /* step over cct id */ offset += 1; /* step over n_s */ offset += 1; /* step over n_r */ /* frame type */ op_code = tvb_get_guint8( tvb, offset ) & 0x0f; offset += 1; /* step over op_code */ col_add_fstr( pinfo->cinfo, COL_INFO, "%s", val_to_str_const( op_code, op_code_vals_text, "Unknown" )); if ( tree ) { /* create display subtree for the protocol */ ti = proto_tree_add_protocol_format( tree, proto_netrom, tvb, 0, NETROM_HEADER_SIZE, "NET/ROM, Src: %s (%s), Dst: %s (%s)", get_ax25_name( src_addr ), ax25_to_str( src_addr ), get_ax25_name( dst_addr ), ax25_to_str( dst_addr ) ); netrom_tree = proto_item_add_subtree( ti, ett_netrom ); offset = 0; /* source */ proto_tree_add_ax25( netrom_tree, hf_netrom_src, tvb, offset, AX25_ADDR_LEN, src_addr ); offset += AX25_ADDR_LEN; /* destination */ proto_tree_add_ax25( netrom_tree, hf_netrom_dst, tvb, offset, AX25_ADDR_LEN, dst_addr ); offset += AX25_ADDR_LEN; /* ttl */ proto_tree_add_item( netrom_tree, hf_netrom_ttl, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; switch ( op_code ) { case NETROM_PROTOEXT : /* cct index */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* cct id */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* unused */ offset += 1; /* unused */ offset += 1; break; case NETROM_CONNREQ : /* cct index */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* cct id */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* unused */ offset += 1; /* unused */ offset += 1; break; case NETROM_CONNACK : /* your cct index */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* your cct id */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* my cct index */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* my cct id */ proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; break; case NETROM_DISCREQ : /* your cct index */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* your cct id */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* unused */ offset += 1; /* unused */ offset += 1; break; case NETROM_DISCACK : /* your cct index */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* your cct id */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* unused */ offset += 1; /* unused */ offset += 1; break; case NETROM_INFO : /* your cct index */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* your cct id */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* n_s */ proto_tree_add_item( netrom_tree, hf_netrom_n_s, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* n_r */ proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; break; case NETROM_INFOACK : /* your cct index */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* your cct id */ proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; /* unused */ offset += 1; /* n_r */ proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; break; default : offset += 1; offset += 1; offset += 1; offset += 1; break; } /* type */ dissect_netrom_type( tvb, offset, pinfo, netrom_tree, hf_netrom_type, ett_netrom_type, &netrom_type_items ); offset += 1; switch ( op_code ) { case NETROM_PROTOEXT : break; case NETROM_CONNREQ : /* proposed window size */ proto_tree_add_item( netrom_tree, hf_netrom_pwindow, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; user_addr = tvb_get_ptr( tvb, offset, AX25_ADDR_LEN ); proto_tree_add_ax25( netrom_tree, hf_netrom_user, tvb, offset, AX25_ADDR_LEN, user_addr ); offset += AX25_ADDR_LEN; node_addr = tvb_get_ptr( tvb, offset, AX25_ADDR_LEN ); proto_tree_add_ax25( netrom_tree, hf_netrom_node, tvb, offset, AX25_ADDR_LEN, node_addr ); offset += AX25_ADDR_LEN; break; case NETROM_CONNACK : /* accepted window size */ proto_tree_add_item( netrom_tree, hf_netrom_awindow, tvb, offset, 1, ENC_BIG_ENDIAN ); offset += 1; break; case NETROM_DISCREQ : break; case NETROM_DISCACK : break; case NETROM_INFO : break; case NETROM_INFOACK : break; default : break; } } /* Call sub-dissectors here */ saved_private_data = pinfo->private_data; next_tvb = tvb_new_subset_remaining(tvb, offset); switch ( op_code ) { case NETROM_PROTOEXT : if ( cct_index == NETROM_PROTO_IP && cct_id == NETROM_PROTO_IP ) call_dissector( ip_handle , next_tvb, pinfo, tree ); else call_dissector( default_handle , next_tvb, pinfo, tree ); break; case NETROM_INFO : default : call_dissector( default_handle , next_tvb, pinfo, tree ); break; } pinfo->private_data = saved_private_data; }
static void dissect_aarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 ar_hrd; guint16 ar_pro; guint8 ar_hln; guint8 ar_pln; guint16 ar_op; proto_tree *aarp_tree; proto_item *ti; const gchar *op_str; int sha_offset, spa_offset, tha_offset, tpa_offset; gchar *sha_str, *spa_str, /* *tha_str, */ *tpa_str; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AARP"); col_clear(pinfo->cinfo, COL_INFO); ar_hrd = tvb_get_ntohs(tvb, AR_HRD); ar_pro = tvb_get_ntohs(tvb, AR_PRO); ar_hln = tvb_get_guint8(tvb, AR_HLN); ar_pln = tvb_get_guint8(tvb, AR_PLN); ar_op = tvb_get_ntohs(tvb, AR_OP); /* Get the offsets of the addresses. */ sha_offset = MIN_AARP_HEADER_SIZE; spa_offset = sha_offset + ar_hln; tha_offset = spa_offset + ar_pln; tpa_offset = tha_offset + ar_hln; /* Extract the addresses. */ sha_str = tvb_aarphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd); spa_str = tvb_aarpproaddr_to_str(tvb, spa_offset, ar_pln, ar_pro); #if 0 /* TODO: tha_str is currently not shown nor parsed */ tha_str = tvb_aarphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd); #endif tpa_str = tvb_aarpproaddr_to_str(tvb, tpa_offset, ar_pln, ar_pro); switch (ar_op) { case AARP_REQUEST: case AARP_REQUEST_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s", tpa_str, spa_str); break; case AARP_REPLY: case AARP_REPLY_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s", spa_str, sha_str); break; case AARP_PROBE: case AARP_PROBE_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "Is there a %s", tpa_str); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown AARP opcode 0x%04x", ar_op); break; } if (tree) { if ((op_str = match_strval(ar_op, op_vals))) ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0, MIN_AARP_HEADER_SIZE + 2*ar_hln + 2*ar_pln, "AppleTalk Address Resolution Protocol (%s)", op_str); else ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0, MIN_AARP_HEADER_SIZE + 2*ar_hln + 2*ar_pln, "AppleTalk Address Resolution Protocol (opcode 0x%04x)", ar_op); aarp_tree = proto_item_add_subtree(ti, ett_aarp); proto_tree_add_uint(aarp_tree, hf_aarp_hard_type, tvb, AR_HRD, 2, ar_hrd); proto_tree_add_uint(aarp_tree, hf_aarp_proto_type, tvb, AR_PRO, 2, ar_pro); proto_tree_add_uint(aarp_tree, hf_aarp_hard_size, tvb, AR_HLN, 1, ar_hln); proto_tree_add_uint(aarp_tree, hf_aarp_proto_size, tvb, AR_PLN, 1, ar_pln); proto_tree_add_uint(aarp_tree, hf_aarp_opcode, tvb, AR_OP, 2, ar_op); if (ar_hln != 0) { proto_tree_add_item(aarp_tree, AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_src_hw_mac : hf_aarp_src_hw, tvb, sha_offset, ar_hln, ENC_NA); } if (ar_pln != 0) { if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto_id, tvb, spa_offset, ar_pln, NULL, "%s", spa_str); } else { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto, tvb, spa_offset, ar_pln, NULL, "%s", spa_str); } } if (ar_hln != 0) { proto_tree_add_item(aarp_tree, AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_dst_hw_mac : hf_aarp_dst_hw, tvb, tha_offset, ar_hln, ENC_NA); } if (ar_pln != 0) { if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto_id, tvb, tpa_offset, ar_pln, NULL, "%s", tpa_str); } else { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto, tvb, tpa_offset, ar_pln, NULL, "%s", tpa_str); } } } }
static void dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *qllc_tree = NULL; proto_item *qllc_ti = NULL; gboolean *q_bit_set = (gboolean *)pinfo->private_data; guint8 addr, ctrl; gboolean command = FALSE; /* * If the Q bit isn't set, this is just SNA data. */ if (!(*q_bit_set)) { call_dissector(sna_handle, tvb, pinfo, tree); return; } /* Summary information */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "QLLC"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { qllc_ti = proto_tree_add_item(tree, proto_qllc, tvb, 0, -1, ENC_NA); qllc_tree = proto_item_add_subtree(qllc_ti, ett_qllc); } /* Get the address; we need it to determine if this is a * COMMAND or a RESPONSE */ addr = tvb_get_guint8(tvb, 0); if (tree) { proto_tree_add_item(qllc_tree, hf_qllc_address, tvb, 0, 1, ENC_BIG_ENDIAN); } /* The address field equals X'FF' in commands (except QRR) * and anything in responses. */ ctrl = tvb_get_guint8(tvb, 1); if (ctrl != QRR && addr == 0xff) { command = TRUE; } /* Disambiguate QRD_QDISC_VALUE, based on whether this packet is * a COMMAND or RESPONSE. */ if (ctrl == QRD_QDISC_VALUE) { if (command) { col_set_str(pinfo->cinfo, COL_INFO, QDISC_TEXT); if (tree) { proto_tree_add_text(qllc_tree, tvb, 1, 1, "Control Field: %s (0x%02x)", QDISC_TEXT, ctrl); } } else { col_set_str(pinfo->cinfo, COL_INFO, QRD_TEXT); if (tree) { proto_tree_add_text(qllc_tree, tvb, 1, 1, "Control Field: %s (0x%02x)", QRD_TEXT, ctrl); } } /* Add the field for filtering purposes */ if (tree) { proto_item *hidden_item; hidden_item = proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb, 1, 1, ctrl); PROTO_ITEM_SET_HIDDEN(hidden_item); } } else { /* Non-ambiguous control field value */ col_add_str(pinfo->cinfo, COL_INFO, val_to_str(ctrl, qllc_control_vals, "Control Field: 0x%02x (unknown)")); proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb, 1, 1, ctrl); } /* Do we have an I field ? */ /* XXX - I field exists for QUI too, but only for subarea nodes. * Need to test for this. */ if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) { /* yes */ } }
static void dissect_pw_cesopsn( tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = PWC_PACKET_PROPERTIES_T_INITIALIZER; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC5086: * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN * packet (defined as the size of the CESoPSN header + the payload size) * if it is less than 64 bytes, and MUST be set to zero otherwise. * Note: If fixed RTP header is used in the encapsulation, it is * considered part of the CESoPSN header.] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC5086's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } { guint8 cw_lm; cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/; if (NULL == try_val_to_str(cw_lm, vals_cw_lm)) { properties |= PWC_CW_SUSPECT_LM; } { guint8 l_bit, m_bits; l_bit = (cw_lm & 0x08) >> 3; m_bits = (cw_lm & 0x03) >> 0; if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/ ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ ) { if ((payload_size == 0) || ((payload_size % 8) != 0)) { properties |= PWC_PAY_SIZE_BAD; } } else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/ { /*allow any size of payload*/ } else /*reserved combinations*/ { /*allow any size of payload*/ } } } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } else if (properties & PWC_ANYOF_CW_SUSPECT) { col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, "); } col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } item3 = proto_tree_add_item(tree3, hf_cw_lm, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_SUSPECT_LM) { expert_add_info(pinfo, item3, &ei_cw_lm); } proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be 0 if CESoPSN packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (payload_size == 0) { if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error, "CESoPSN payload: none found. Size of payload must be <> 0"); } else { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded, "CESoPSN payload: omitted to conserve bandwidth"); } } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error, "CESoPSN packet payload size must be multiple of 8"); } tree2 = proto_item_add_subtree(item2, ett); call_data_dissector(tvb, pinfo, tree2); item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
static void dissect_sap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; int sap_version, is_ipv6, is_del, is_enc, is_comp, addr_len; guint8 vers_flags; guint8 auth_len; guint8 auth_flags; tvbuff_t *next_tvb; proto_item *si, *sif; proto_tree *sap_tree = NULL, *sap_flags_tree; col_set_str(pinfo->cinfo, COL_PROTOCOL, "SAP"); col_clear(pinfo->cinfo, COL_INFO); vers_flags = tvb_get_guint8(tvb, offset); is_ipv6 = vers_flags&MCAST_SAP_BIT_A; is_del = vers_flags&MCAST_SAP_BIT_T; is_enc = vers_flags&MCAST_SAP_BIT_E; is_comp = vers_flags&MCAST_SAP_BIT_C; sap_version = (vers_flags&MCAST_SAP_VERSION_MASK)>>MCAST_SAP_VERSION_SHIFT; addr_len = (is_ipv6) ? (int)sizeof(struct e_in6_addr) : 4; col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%u)", (is_del) ? "Deletion" : "Announcement", sap_version); if (tree) { si = proto_tree_add_item(tree, proto_sap, tvb, offset, -1, ENC_NA); sap_tree = proto_item_add_subtree(si, ett_sap); sif = proto_tree_add_item(sap_tree, hf_sap_flags, tvb, offset, 1, ENC_NA); sap_flags_tree = proto_item_add_subtree(sif, ett_sap_flags); proto_tree_add_item(sap_flags_tree, hf_sap_flags_v, tvb, offset, 1, ENC_NA); proto_tree_add_item(sap_flags_tree, hf_sap_flags_a, tvb, offset, 1, ENC_NA); proto_tree_add_item(sap_flags_tree, hf_sap_flags_r, tvb, offset, 1, ENC_NA); proto_tree_add_item(sap_flags_tree, hf_sap_flags_t, tvb, offset, 1, ENC_NA); proto_tree_add_item(sap_flags_tree, hf_sap_flags_e, tvb, offset, 1, ENC_NA); proto_tree_add_item(sap_flags_tree, hf_sap_flags_c, tvb, offset, 1, ENC_NA); } offset++; auth_len = tvb_get_guint8(tvb, offset); proto_tree_add_item(sap_tree, hf_sap_auth_len, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(sap_tree, hf_sap_message_identifier_hash, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2; if (is_ipv6) proto_tree_add_item(sap_tree, hf_sap_originating_source_ipv6, tvb, offset, addr_len, ENC_NA); else proto_tree_add_item(sap_tree, hf_sap_originating_source_ipv4, tvb, offset, addr_len, ENC_BIG_ENDIAN); offset += addr_len; /* Authentication data lives in its own subtree */ if (auth_len > 0) { guint32 auth_data_len; proto_item *sdi, *sai; proto_tree *sa_tree, *saf_tree; int has_pad; guint8 pad_len = 0; auth_data_len = (guint32)(auth_len * sizeof(guint32)); sdi = proto_tree_add_item(sap_tree, hf_auth_data, tvb, offset, auth_data_len, ENC_NA); sa_tree = proto_item_add_subtree(sdi, ett_sap_auth); auth_flags = tvb_get_guint8(tvb, offset); sai = proto_tree_add_item(sa_tree, hf_auth_flags, tvb, offset, 1, ENC_NA); saf_tree = proto_item_add_subtree(sai, ett_sap_authf); proto_tree_add_item(saf_tree, hf_auth_flags_v, tvb, offset, 1, ENC_NA); proto_tree_add_item(saf_tree, hf_auth_flags_p, tvb, offset, 1, ENC_NA); proto_tree_add_item(saf_tree, hf_auth_flags_t, tvb, offset, 1, ENC_NA); has_pad = auth_flags&MCAST_SAP_AUTH_BIT_P; if (has_pad) { pad_len = tvb_get_guint8(tvb, offset+auth_data_len-1); } if ((int) auth_data_len - pad_len - 1 < 0) { expert_add_info_format(pinfo, sai, &ei_sap_bogus_authentication_or_pad_length, "Bogus authentication length (%d) or pad length (%d)", auth_len, pad_len); return; } proto_tree_add_item(sa_tree, hf_sap_auth_subheader, tvb, offset+1, auth_data_len-pad_len-1, ENC_NA); if (has_pad) { proto_tree_add_item(sa_tree, hf_sap_auth_data_padding_len, tvb, offset+auth_data_len-1, 1, ENC_NA); proto_tree_add_item(sa_tree, hf_sap_auth_data_padding, tvb, offset+auth_data_len-pad_len, pad_len, ENC_NA); } offset += auth_data_len; } if (is_enc || is_comp) { expert_field *mangle; if (is_enc && is_comp) mangle = &ei_sap_compressed_and_encrypted; else if (is_enc) mangle = &ei_sap_encrypted; else mangle = &ei_sap_compressed; proto_tree_add_expert(sap_tree, pinfo, mangle, tvb, offset, -1); return; } if (tree) { /* Do we have the optional payload type aka. MIME content specifier */ if (tvb_strneql(tvb, offset, "v=", strlen("v="))) { gint remaining_len; guint32 pt_len; int pt_string_len; guint8* pt_str; remaining_len = tvb_captured_length_remaining(tvb, offset); if (remaining_len == 0) { /* * "tvb_strneql()" failed because there was no * data left in the packet. * * Set the remaining length to 1, so that * we throw the appropriate exception in * "tvb_get_ptr()", rather than displaying * the payload type. */ remaining_len = 1; } pt_string_len = tvb_strnlen(tvb, offset, remaining_len); if (pt_string_len == -1) { /* * We didn't find a terminating '\0'; run to the * end of the buffer. */ pt_string_len = remaining_len; pt_len = pt_string_len; } else { /* * Include the '\0' in the total item length. */ pt_len = pt_string_len + 1; } pt_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, pt_string_len, ENC_ASCII); proto_tree_add_string_format_value(sap_tree, hf_sap_payload_type, tvb, offset, pt_len, pt_str, "%.*s", pt_string_len, pt_str); offset += pt_len; } } /* Done with SAP */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(sdp_handle, next_tvb, pinfo, tree); }
// content format static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { // your variable definitions go here int bitoffset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors"); // Clear out stuff in the info column col_clear(pinfo->cinfo,COL_INFO); if (tree) { // in case that someone wants to know some details of our protocol // spawn a subtree and cut the sequence in readable parts proto_item *pi = NULL; proto_item *ti = NULL; proto_tree *mysensors_tree = NULL; tvbuff_t* tvb_next; guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack; MySensors_Command commandType; gchar* info; ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA); mysensors_tree = proto_item_add_subtree(ti, ett_mysensors); proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding); last = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding); sender = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding); dest = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding); payloadLen = tvb_get_bits8(tvb, bitoffset, 5); bitoffset += 5; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding); bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding); dataType = tvb_get_bits8(tvb, bitoffset, 3); // Type of payload bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding); isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding); reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding); commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3); bitoffset += 3; type = tvb_get_guint8(tvb, bitoffset>>3); proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding); sensor = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; // Create tvb for the payload. tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen); info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next ); col_add_str(pinfo->cinfo, COL_INFO, info); proto_item_append_text(ti, " - %s", info); col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender); col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest); // Pass payload to generic data dissector call_dissector(data_handle, tvb_next, pinfo, mysensors_tree); } }
/* * Dissect DOP PDUs inside a ROS PDUs */ static int dissect_dop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { int offset = 0; int old_offset; proto_item *item; proto_tree *tree; struct SESSION_DATA_STRUCTURE* session; int (*dop_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL; const char *dop_op_name; asn1_ctx_t asn1_ctx; /* do we have operation information from the ROS dissector? */ if (data == NULL) return 0; session = (struct SESSION_DATA_STRUCTURE*)data; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); item = proto_tree_add_item(parent_tree, proto_dop, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_dop); col_set_str(pinfo->cinfo, COL_PROTOCOL, "DOP"); col_clear(pinfo->cinfo, COL_INFO); asn1_ctx.private_data = session; switch(session->ros_op & ROS_OP_MASK) { case (ROS_OP_BIND | ROS_OP_ARGUMENT): /* BindInvoke */ dop_dissector = dissect_dop_DSAOperationalManagementBindArgument; dop_op_name = "DSA-Operational-Bind-Argument"; break; case (ROS_OP_BIND | ROS_OP_RESULT): /* BindResult */ dop_dissector = dissect_dop_DSAOperationalManagementBindResult; dop_op_name = "DSA-Operational-Bind-Result"; break; case (ROS_OP_BIND | ROS_OP_ERROR): /* BindError */ dop_dissector = dissect_dop_DSAOperationalManagementBindError; dop_op_name = "DSA-Operational-Management-Bind-Error"; break; case (ROS_OP_INVOKE | ROS_OP_ARGUMENT): /* Invoke Argument */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 100: /* establish */ dop_dissector = dissect_dop_EstablishOperationalBindingArgument; dop_op_name = "Establish-Operational-Binding-Argument"; break; case 101: /* terminate */ dop_dissector = dissect_dop_TerminateOperationalBindingArgument; dop_op_name = "Terminate-Operational-Binding-Argument"; break; case 102: /* modify */ dop_dissector = dissect_dop_ModifyOperationalBindingArgument; dop_op_name = "Modify-Operational-Binding-Argument"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Argument opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; case (ROS_OP_INVOKE | ROS_OP_RESULT): /* Return Result */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 100: /* establish */ dop_dissector = dissect_dop_EstablishOperationalBindingResult; dop_op_name = "Establish-Operational-Binding-Result"; break; case 101: /* terminate */ dop_dissector = dissect_dop_TerminateOperationalBindingResult; dop_op_name = "Terminate-Operational-Binding-Result"; break; case 102: /* modify */ dop_dissector = dissect_dop_ModifyOperationalBindingResult; dop_op_name = "Modify-Operational-Binding-Result"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Result opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; case (ROS_OP_INVOKE | ROS_OP_ERROR): /* Return Error */ switch(session->ros_op & ROS_OP_OPCODE_MASK) { case 100: /* operational-binding */ dop_dissector = dissect_dop_OpBindingErrorParam; dop_op_name = "Operational-Binding-Error"; break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Error opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK); break; } break; default: proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP PDU"); return tvb_length(tvb); } if(dop_dissector) { col_set_str(pinfo->cinfo, COL_INFO, dop_op_name); while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=(*dop_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1); if(offset == old_offset){ proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DOP PDU"); break; } } } return tvb_length(tvb); }
/* Code to actually dissect the packets */ static gboolean dissect_epl_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 epl_v1_service, epl_v1_dest, epl_v1_src, epl_v1_ainv_ch, epl_v1_asnd_ch; gint offset; proto_item *ti=NULL; proto_tree *epl_v1_tree=NULL; if(tvb_length(tvb) < 3){ /* Not enough data for an EPL_V1 header; don't try to interpret it */ return FALSE; } offset = 0; /* make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "EPL_V1"); col_clear(pinfo->cinfo, COL_INFO); /* get service type */ epl_v1_service = tvb_get_guint8(tvb, EPL_V1_SERVICE_OFFSET) & 0x7F; /* get destination */ epl_v1_dest = tvb_get_guint8(tvb, EPL_V1_DEST_OFFSET); /* get source */ epl_v1_src = tvb_get_guint8(tvb, EPL_V1_SRC_OFFSET); /* choose the right string for "Info" column */ switch(epl_v1_service){ case EPL_V1_SOC: col_add_fstr(pinfo->cinfo, COL_INFO, "SoC dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); break; case EPL_V1_EOC: col_add_fstr(pinfo->cinfo, COL_INFO, "EoC dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); break; case EPL_V1_PREQ: col_add_fstr(pinfo->cinfo, COL_INFO, "PReq dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); break; case EPL_V1_PRES: col_add_fstr(pinfo->cinfo, COL_INFO, "PRes dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); break; case EPL_V1_AINV: /* get AInv channel */ epl_v1_ainv_ch = tvb_get_guint8(tvb, EPL_V1_AINV_CHANNEL_OFFSET); col_add_fstr(pinfo->cinfo, COL_INFO, "AInv dest = %3d src = %3d channel = %s ", epl_v1_dest, epl_v1_src, val_to_str(epl_v1_ainv_ch, ainv_channel_number_vals, "unknown Channel (%d)")); break; case EPL_V1_ASND: /* get ASnd channel */ epl_v1_asnd_ch = tvb_get_guint8(tvb, EPL_V1_ASND_CHANNEL_OFFSET); col_add_fstr(pinfo->cinfo, COL_INFO, "ASnd dest = %3d src = %3d channel = %s ", epl_v1_dest, epl_v1_src, val_to_str(epl_v1_asnd_ch, asnd_channel_number_vals, "unknown Channel (%d)")); break; default: /* no valid EPL packet */ return FALSE; } if(tree){ /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_epl_v1, tvb, 0, -1, TRUE); epl_v1_tree = proto_item_add_subtree(ti, ett_epl_v1); } proto_tree_add_item(epl_v1_tree, hf_epl_v1_service, tvb, offset, 1, TRUE); offset += 1; proto_tree_add_item(epl_v1_tree, hf_epl_v1_dest, tvb, offset, 1, TRUE); offset += 1; proto_tree_add_item(epl_v1_tree, hf_epl_v1_src, tvb, offset, 1, TRUE); offset += 1; /* The rest of the epl_v1 dissector depends on the message type */ switch(epl_v1_service){ case EPL_V1_SOC: offset = dissect_epl_v1_soc(epl_v1_tree, tvb, offset); break; case EPL_V1_EOC: offset = dissect_epl_v1_eoc(epl_v1_tree, tvb, offset); break; case EPL_V1_PREQ: offset = dissect_epl_v1_preq(epl_v1_tree, tvb, offset); break; case EPL_V1_PRES: offset = dissect_epl_v1_pres(epl_v1_tree, tvb, offset); break; case EPL_V1_AINV: offset = dissect_epl_v1_ainv(epl_v1_tree, tvb, offset); break; case EPL_V1_ASND: offset = dissect_epl_v1_asnd(epl_v1_tree, tvb, offset); break; default: /* not a valid MessageType - can't dissect any further. */ return FALSE; } return TRUE; }
/* Code to actually dissect the packets */ static void dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_udp) { gint remaining; gint header_length = 3; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPA"); col_clear(pinfo->cinfo, COL_INFO); while ((remaining = tvb_reported_length_remaining(tvb, offset)) > 0) { proto_item *ti; proto_tree *ipa_tree = NULL; guint16 len, msg_type; tvbuff_t *next_tvb; len = tvb_get_ntohs(tvb, offset); msg_type = tvb_get_guint8(tvb, offset+2); col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(msg_type, ipa_protocol_vals, "unknown 0x%02x")); /* * The IPA header is different depending on the transport protocol. * With UDP there seems to be a fourth byte for the IPA header. * We attempt to detect this by checking if the length from the * header + four bytes of the IPA header equals the remaining size. */ if (is_udp && (len + 4 == remaining)) { header_length++; } if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ipa, tvb, offset, len+header_length, "IPA protocol ip.access, type: %s", val_to_str(msg_type, ipa_protocol_vals, "unknown 0x%02x")); ipa_tree = proto_item_add_subtree(ti, ett_ipa); proto_tree_add_item(ipa_tree, hf_ipa_data_len, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ipa_tree, hf_ipa_protocol, tvb, offset+2, 1, ENC_BIG_ENDIAN); } next_tvb = tvb_new_subset_length(tvb, offset+header_length, len); switch (msg_type) { case ABISIP_OML: /* hand this off to the standard A-bis OML dissector */ if (sub_handles[SUB_OML]) call_dissector(sub_handles[SUB_OML], next_tvb, pinfo, tree); break; case ABISIP_IPACCESS: dissect_ipaccess(next_tvb, pinfo, tree); break; case AIP_SCCP: /* hand this off to the standard SCCP dissector */ call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree); break; case IPA_MGCP: /* hand this off to the standard MGCP dissector */ call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree); break; case OSMO_EXT: dissect_osmo(next_tvb, pinfo, ipa_tree, tree); break; case HSL_DEBUG: if (tree) { proto_tree_add_item(ipa_tree, hf_ipa_hsl_debug, next_tvb, 0, len, ENC_ASCII|ENC_NA); if (global_ipa_in_root == TRUE) proto_tree_add_item(tree, hf_ipa_hsl_debug, next_tvb, 0, len, ENC_ASCII|ENC_NA); } if (global_ipa_in_info == TRUE) col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", tvb_get_stringz_enc(wmem_packet_scope(), next_tvb, 0, NULL, ENC_ASCII)); break; default: if (msg_type < ABISIP_RSL_MAX) { /* hand this off to the standard A-bis RSL dissector */ call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree); } break; } offset += len + header_length; } }