static int dissect_proxy_v2_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *proxy_tree, int offset) { while ( tvb_reported_length_remaining(tvb, offset) > 0) { guint32 type, length; proto_item *ti_tlv; proto_tree *tlv_tree; ti_tlv = proto_tree_add_item(proxy_tree, hf_proxy2_tlv, tvb, offset, 3, ENC_NA); tlv_tree = proto_item_add_subtree(ti_tlv, ett_proxy2_tlv); proto_tree_add_item_ret_uint(tlv_tree, hf_proxy2_tlv_type, tvb, offset, 1, ENC_NA, &type); offset += 1; proto_tree_add_item_ret_uint(tlv_tree, hf_proxy2_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length); offset += 2; proto_item_append_text(ti_tlv, ": (t=%u,l=%d) %s", type, length, val_to_str(type, proxy2_tlv_vals ,"Unknown type") ); proto_item_set_len(ti_tlv, 1 + 2 + length); proto_tree_add_item(tlv_tree, hf_proxy2_tlv_value, tvb, offset, length, ENC_NA); switch (type) { case PP2_TYPE_SSL: /* SSL */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_client, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_verify, tvb, offset, 4, ENC_NA); offset += 4; offset = dissect_proxy_v2_tlv(tvb, pinfo, tlv_tree, offset); break; case PP2_SUBTYPE_SSL_VERSION: /* SSL Version */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_version, tvb, offset, length, ENC_ASCII|ENC_NA); proto_item_append_text(ti_tlv, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_ASCII)); offset += length; break; case PP2_SUBTYPE_SSL_CN: /* SSL CommonName */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_cn, tvb, offset, length, ENC_ASCII|ENC_NA); proto_item_append_text(ti_tlv, ": %s", tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_ASCII)); offset += length; break; case PP2_SUBTYPE_SSL_CIPHER: /* SSL Cipher */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_cipher, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; break; case PP2_SUBTYPE_SSL_SIG_ALG: /* SSL Signature Algorithm */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_sig_alg, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; break; case PP2_SUBTYPE_SSL_KEY_ALG: /* SSL Key Algorithm */ proto_tree_add_item(tlv_tree, hf_proxy2_tlv_ssl_key_alg, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; break; default: offset += length; break; } } return offset; }
/** *ZigBee Device Profile dissector for the unbind request. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_req_unbind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { proto_item *ti; guint sizeof_cluster = (version >= ZBEE_VERSION_2007)?(int)sizeof(guint16):(int)sizeof(guint8); guint offset = 0; guint64 src64; /*guint8 src_ep;*/ guint32 cluster, dst_mode, dst = 0; guint64 dst64 = 0; /*guint8 dst_ep;*/ src64 = zbee_parse_eui64(tree, hf_zbee_zdp_bind_src64, tvb, &offset, (int)sizeof(guint64), NULL); proto_tree_add_item(tree, hf_zbee_zdp_bind_src_ep, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; ti = proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_cluster, tvb, offset, sizeof_cluster, ENC_LITTLE_ENDIAN, &cluster); offset += sizeof_cluster; proto_item_append_text(ti, " (%s)", rval_to_str(cluster, zbee_aps_cid_names, "Unknown Cluster")); if (version >= ZBEE_VERSION_2007) { proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_addr_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN, &dst_mode); offset += 1; } else { /* ZigBee 2003 & earlier does not have a address mode, and is unicast only. */ dst_mode = ZBEE_ZDP_ADDR_MODE_UNICAST; } if (dst_mode == ZBEE_ZDP_ADDR_MODE_GROUP) { proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_bind_dst, tvb, offset, 2, ENC_LITTLE_ENDIAN, &dst); offset += 2; } else if (dst_mode == ZBEE_ZDP_ADDR_MODE_UNICAST) { dst64 = zbee_parse_eui64(tree, hf_zbee_zdp_bind_dst64, tvb, &offset, (int)sizeof(guint64), NULL); proto_tree_add_item(tree, hf_zbee_zdp_bind_dst_ep, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; } zbee_append_info(tree, pinfo, ", %s (Cluster ID: 0x%04x)", rval_to_str(cluster, zbee_aps_cid_names, "Unknown Cluster"), cluster); if (version >= ZBEE_VERSION_2007) { zbee_append_info(tree, pinfo, " Src: %s", eui64_to_display(wmem_packet_scope(), src64)); } if (dst_mode == ZBEE_ZDP_ADDR_MODE_GROUP) { zbee_append_info(tree, pinfo, ", Dst: 0x%04x", dst); } else { zbee_append_info(tree, pinfo, ", Dst: %s", eui64_to_display(wmem_packet_scope(), dst64)); } /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_unbind */
/** *ZigBee Device Profile dissector for the end device bind * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_req_end_device_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { guint sizeof_cluster = (version >= ZBEE_VERSION_2007)?(int)sizeof(guint16):(int)sizeof(guint8); guint i; proto_tree *field_tree = NULL; guint offset = 0; guint32 target, in_count, out_count; guint64 ext_addr = 0; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_target, tvb, offset, 2, ENC_LITTLE_ENDIAN, &target); offset += 2; if (version >= ZBEE_VERSION_2007) { /* Extended address present on ZigBee 2006 & later. */ ext_addr = zbee_parse_eui64(tree, hf_zbee_zdp_ext_addr, tvb, &offset, (guint)sizeof(guint64), NULL); } proto_tree_add_item(tree, hf_zbee_zdp_endpoint, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(tree, hf_zbee_zdp_profile, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_in_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &in_count); offset += 1; if ((tree) && (in_count)) { field_tree = proto_tree_add_subtree(tree, tvb, offset, (int)(in_count*sizeof_cluster), ett_zbee_zdp_bind_end_in, NULL, "Input Cluster List"); } for (i=0; i<in_count; i++) { proto_tree_add_item(field_tree, hf_zbee_zdp_in_cluster, tvb, offset, sizeof_cluster, ENC_LITTLE_ENDIAN); offset += sizeof_cluster; } proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_out_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &out_count); offset += 1; if ((tree) && (out_count)) { field_tree = proto_tree_add_subtree(tree, tvb, offset, (int)(out_count*sizeof_cluster), ett_zbee_zdp_bind_end_out, NULL, "Output Cluster List"); } for (i=0; i<out_count; i++) { proto_tree_add_item(field_tree, hf_zbee_zdp_out_cluster, tvb, offset, sizeof_cluster, ENC_LITTLE_ENDIAN); offset += sizeof_cluster; } if (version >= ZBEE_VERSION_2007) { zbee_append_info(tree, pinfo, " Src: %s", eui64_to_display(wmem_packet_scope(), ext_addr)); } zbee_append_info(tree, pinfo, ", Target: 0x%04x", target); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_end_device_bind */
/** *ZigBee Device Profile dissector for the recover binding * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_rsp_recover_bind_table(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { proto_tree *field_tree = NULL; guint offset = 0; guint8 status; guint32 i, table_count; status = zdp_parse_status(tree, tvb, &offset); proto_tree_add_item(tree, hf_zbee_zdp_table_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_table_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &table_count); offset += 2; if (tree && table_count) { field_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_zbee_zdp_bind, NULL, "Binding Table"); } for (i=0; i<table_count; i++) { zdp_parse_bind_table_entry(field_tree, tvb, &offset, version); } /* for */ zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_recover_bind_table */
/** *ZigBee Device Profile dissector for the recover source binding * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_rsp_recover_source_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *field_tree = NULL; guint offset = 0; guint8 status; guint32 i, table_count; status = zdp_parse_status(tree, tvb, &offset); proto_tree_add_item(tree, hf_zbee_zdp_table_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_table_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &table_count); offset += 2; if (tree && table_count) { field_tree = proto_tree_add_subtree(tree, tvb, offset, table_count * (int)sizeof(guint64), ett_zbee_zdp_bind_source, NULL, "Source Table"); } for (i=0; i<table_count; i++) { (void)zbee_parse_eui64(field_tree, hf_zbee_zdp_bind_src64, tvb, &offset, (int)sizeof(guint64), NULL); } /* for */ zbee_append_info(tree, pinfo, ", Status: %s", zdp_status_name(status)); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_rsp_recover_source_bind */
static void dissect_operation_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint length_count) { proto_item *ti; proto_tree *oper_tree; guint type, length; while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH) { oper_tree = proto_tree_add_subtree(tree, tvb, offset, length_count, ett_forces_lfbselect_tlv_type_operation, &ti, "Operation TLV"); type = tvb_get_ntohs(tvb,offset); ti = proto_tree_add_item(oper_tree, hf_forces_lfbselect_tlv_type_operation_type, tvb, offset, 2, ENC_BIG_ENDIAN); if (try_val_to_str(type, operation_type_vals) == NULL) expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_type, "Bogus: ForCES Operation TLV (Type:0x%04x) is not supported", type); proto_tree_add_item_ret_uint(oper_tree, hf_forces_lfbselect_tlv_type_operation_length, tvb, offset+2, 2, ENC_BIG_ENDIAN, &length); dissect_path_data_tlv(tvb, pinfo, oper_tree, offset+TLV_TL_LENGTH); if (length == 0) break; offset += length; } }
static void dissect_failure_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree, proto_item *parent_ti) { guint base_offs = offset; guint count = 0; /* iterate over list items, each with its own discriminator */ while (offset - base_offs < len) { proto_tree *elem_tree; proto_item *ti; guint remain_len, cause; int rc; guint8 discr = tvb_get_guint8(tvb, offset) & 0x0f; elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2, ett_cbsp_fail_list, &ti, "Failure List Item"); proto_tree_add_item(elem_tree, hf_cbsp_cell_id_disc, tvb, offset++, 1, ENC_NA); remain_len = len - (offset - base_offs); rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); if (rc <= 0) break; offset += rc; proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cause, tvb, offset++, 1, ENC_NA, &cause); proto_item_append_text(ti, ": Cause %s", val_to_str_const(cause, cbsp_cause_vals, "Undefined")); count++; } proto_item_append_text(parent_ti, ": %u items", count); }
static proto_tree * dissect_pcli_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int* offset) { guint32 cccid; proto_tree *pcli_tree; proto_item *pcli_item; /* Set the protocol column */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCLI"); /* *If we have a non-null tree (ie we are building the proto_tree * instead of just filling out the columns ), then add a PLCI * tree node and put a CCCID header element under it. */ pcli_item = proto_tree_add_item(tree, proto_pcli, tvb, *offset, 4, ENC_NA); pcli_tree = proto_item_add_subtree(pcli_item, ett_pcli); proto_tree_add_item_ret_uint(pcli_tree, hf_pcli_cccid, tvb, *offset, 4, ENC_BIG_ENDIAN, &cccid); (*offset) += 4; if (pcli_summary_in_tree) { proto_item_append_text(pcli_item, ", CCCID: %u", cccid); } /* Set the info column */ col_add_fstr(pinfo->cinfo, COL_INFO, "CCCID: %u", cccid); return pcli_tree; }
static void dissect_cell_id_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree, proto_item *parent_ti) { guint base_offs = offset; guint32 discr; guint count = 0; /* list-global discriminator */ proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr); discr &= 0x0f; offset++; /* iterate over list items */ while (offset - base_offs < len) { proto_tree *elem_tree; proto_item *ti; int rc; guint remain_len = len - (offset - base_offs); elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr), ett_cbsp_cell_list, &ti, "Cell List Item"); rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); if (rc <= 0) break; offset += rc; count++; } proto_item_append_text(parent_ti, " (%s): %u items", val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count); }
static void dissect_bc_compl_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree, proto_item *parent_ti) { guint base_offs = offset; guint32 discr; guint count = 0; /* list-global discriminator */ proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr); discr &= 0x0f; offset++; /* iterate over list items */ while (offset - base_offs < len) { proto_tree *elem_tree; proto_item *ti; guint32 num_bc, num_bi; int rc; guint remain_len = len - (offset - base_offs); elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+3, ett_cbsp_num_bcast_compl_list, &ti, "Number of Broadcasts completed"); rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); if (rc <= 0) break; offset += rc; proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_compl, tvb, offset, 2, ENC_NA, &num_bc); offset += 2; proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_info, tvb, offset++, 1, ENC_NA, &num_bi); proto_item_append_text(ti, ": NumBC=%u (%s)", num_bc, val_to_str_const(num_bi, cbsp_num_bcast_shortinfo_vals, "")); count++; } proto_item_append_text(parent_ti, " (%s): %u items", val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count); }
static int dissect_device_list_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) { proto_item *ti_intf; proto_item *ti_dev; proto_tree *intf_tree = NULL; proto_tree *dev_tree = NULL; guint32 num_of_devs; guint32 i; guint8 num_of_intf; guint8 j; col_set_str(pinfo->cinfo, COL_INFO, "Device List Response"); proto_tree_add_item_ret_uint(tree, hf_usbip_number_devices, tvb, offset, 4, ENC_BIG_ENDIAN, &num_of_devs); offset += 4; for (i = 0; i < num_of_devs; i++) { num_of_intf = tvb_get_guint8(tvb, offset + 0x137); ti_dev = proto_tree_add_uint(tree, hf_usbip_device, tvb, offset, 0x138 + 4 * num_of_intf, i + 1); PROTO_ITEM_SET_GENERATED(ti_dev); dev_tree = proto_item_add_subtree(ti_dev, ett_usbip_dev); offset = dissect_device(dev_tree, tvb, offset); for (j = 0; j < num_of_intf; j++) { ti_intf = proto_tree_add_uint(dev_tree, hf_usbip_interface, tvb, offset, 3, j + 1); intf_tree = proto_item_add_subtree(ti_intf, ett_usbip_intf); proto_tree_add_item(intf_tree, hf_usbip_bInterfaceClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(intf_tree, hf_usbip_bInterfaceSubClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(intf_tree, hf_usbip_bInterfaceProtocol, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(intf_tree, hf_usbip_padding, tvb, offset, 1, ENC_NA); offset += 1; } } return offset; }
static int dissect_vxlan_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int is_gpe) { proto_tree *vxlan_tree; proto_item *ti; tvbuff_t *next_tvb; int offset = 0; guint32 vxlan_next_proto; col_set_str(pinfo->cinfo, COL_PROTOCOL, "VxLAN"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_vxlan, tvb, offset, 8, ENC_NA); vxlan_tree = proto_item_add_subtree(ti, ett_vxlan); if(is_gpe) { proto_tree_add_bitmask(vxlan_tree, tvb, offset, hf_vxlan_gpe_flags, ett_vxlan_flags, gpe_flags_fields, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(vxlan_tree, hf_vxlan_gpe_reserved_16, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(vxlan_tree, hf_vxlan_next_proto, tvb, offset, 1, ENC_BIG_ENDIAN, &vxlan_next_proto); offset += 1; } else { proto_tree_add_bitmask(vxlan_tree, tvb, offset, hf_vxlan_flags, ett_vxlan_flags, flags_fields, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(vxlan_tree, hf_vxlan_gbp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } proto_tree_add_item(vxlan_tree, hf_vxlan_vni, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(vxlan_tree, hf_vxlan_reserved_8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; next_tvb = tvb_new_subset_remaining(tvb, offset); if(is_gpe){ if(!dissector_try_uint(vxlan_dissector_table, vxlan_next_proto, next_tvb, pinfo, tree)) { call_data_dissector(next_tvb, pinfo, vxlan_tree); } } else { call_dissector(eth_handle, next_tvb, pinfo, tree); } return tvb_captured_length(tvb); }
/** *ZigBee Device Profile dissector for the remove backup binding * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_req_remove_bak_bind_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { proto_item *ti; guint sizeof_cluster = (version >= ZBEE_VERSION_2007)?(int)sizeof(guint16):(int)sizeof(guint8); guint offset = 0; guint64 src64; guint32 src_ep, cluster, dst_mode; src64 = zbee_parse_eui64(tree, hf_zbee_zdp_bind_src64, tvb, &offset, (int)sizeof(guint64), NULL); proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_bind_src_ep, tvb, offset, 1, ENC_LITTLE_ENDIAN, &src_ep); offset += 1; ti = proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_cluster, tvb, offset, sizeof_cluster, ENC_LITTLE_ENDIAN, &cluster); offset += sizeof_cluster; proto_item_append_text(ti, " (%s)", val_to_str(cluster, zbee_zdp_cluster_names, "Unknown Device Profile Cluster")); proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_addr_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN, &dst_mode); offset += 1; if (dst_mode == ZBEE_ZDP_ADDR_MODE_GROUP) { proto_tree_add_item(tree, hf_zbee_zdp_bind_dst, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; } else if (dst_mode == ZBEE_ZDP_ADDR_MODE_UNICAST) { /*guint64 dst64;*/ /*guint8 dst_ep;*/ /*dst64 =*/ zbee_parse_eui64(tree, hf_zbee_zdp_bind_dst64, tvb, &offset, (int)sizeof(guint64), NULL); proto_tree_add_item(tree, hf_zbee_zdp_bind_dst_ep, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; } zbee_append_info(tree, pinfo, ", %s (Cluster ID: 0x%04x)", val_to_str(cluster, zbee_zdp_cluster_names, "Unknown Device Profile Cluster"), cluster); zbee_append_info(tree, pinfo, ", Src: %s", eui64_to_display(wmem_packet_scope(), src64)); zbee_append_info(tree, pinfo, ", Src Endpoint: %d", src_ep); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_remove_bak_bind_entry */
/* Dissect a P-GSL ACess Burst Message */ static void dissect_pgsl_access_burst(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, RlcMacPrivateData_t *rlcmac_data) { proto_item *ti; proto_tree *pacch_tree; tvbuff_t *data_tvb; guint rxlev, abtype, abi; guint16 acc_delay; ti = proto_tree_add_item(tree, hf_pgsl_pacch, tvb, offset, 5, ENC_NA); pacch_tree = proto_item_add_subtree(ti, ett_pacch); proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_rxlev, tvb, offset++, 1, ENC_NA, &rxlev); /* Access Delay is encoded as 10-bit field with the lowest 8 * bits in the first octet, with the two highest bits in the * lowest bits of the second octet */ acc_delay = tvb_get_guint8(tvb, offset); acc_delay |= tvb_get_bits8(tvb, (offset+1)*8+6, 2) << 8; proto_tree_add_uint(pacch_tree, hf_pgsl_ab_acc_delay, tvb, offset, 2, acc_delay); /* ABI and AB Type are in the same octet as the acc_dely msb's */ offset++; proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_abi, tvb, offset, 1, ENC_NA, &abi); proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_ab_type, tvb, offset, 1, ENC_NA, &abtype); offset++; /* Update the 'master' item */ if (abi) { proto_item_append_text(ti, " Valid, RxLev %u, Delay %u bits, Type %s", rxlev, acc_delay, val_to_str(abtype, pgsl_ab_type_vals, "0x%x")); /* decode actual access burst */ data_tvb = tvb_new_subset_length(tvb, offset, 2); call_dissector_with_data(sub_handles[SUB_RLCMAC_UL], data_tvb, pinfo, pacch_tree, (void *) rlcmac_data); } else proto_item_append_text(ti, " Invalid, RxLev %u", rxlev); }
static int usbip_dissect_op(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, int offset) { proto_item *ti = NULL; guint32 operation; gint32 status; proto_tree_add_item(tree, hf_usbip_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_usbip_operation, tvb, offset, 2, ENC_BIG_ENDIAN, &operation); offset += 2; proto_tree_add_item_ret_int(tree, hf_usbip_status, tvb, offset, 4, ENC_BIG_ENDIAN, &status); offset += 4; switch (operation) { case OP_REQ_IMPORT: offset = dissect_import_request(pinfo, tree, tvb, offset); break; case OP_REP_IMPORT: offset = dissect_import_response(pinfo, tree, tvb, offset, status); break; case OP_REQ_DEVLIST: offset = dissect_device_list_request(pinfo); break; case OP_REP_DEVLIST: offset = dissect_device_list_response(pinfo, tree, tvb, offset); break; default: proto_tree_add_item(tree, hf_usbip_urb_data, tvb, offset, -1, ENC_NA); offset = tvb_reported_length_remaining(tvb, offset); expert_add_info_format( pinfo, ti, &ei_usbip, "Dissector for USBIP Operation" " (%x) code not implemented, Contact" " Wireshark developers if you want this supported", operation); proto_item_append_text(ti, ": Undecoded"); break; } return offset; }
/* Section 8.2.6 Cell List */ static gint dissect_cell_id_elem(guint8 discr, tvbuff_t *tvb, packet_info *pinfo, guint offset, gint len _U_, proto_tree *tree, proto_item *ti) { guint base_offs = offset; gchar *mcc_mnc; guint32 lac, ci; switch (discr) { case CBSP_CIDD_WHOLE_CGI: mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, TRUE); offset += 3; proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac); offset += 2; proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci); offset += 2; proto_item_append_text(ti, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc, lac, ci); break; case CBSP_CIDD_LAC_CI: proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac); offset += 2; proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci); offset += 2; proto_item_append_text(ti, ": LAC 0%04x, CI 0x%04x", lac, ci); break; case CBSP_CIDD_CI: proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci); offset += 2; proto_item_append_text(ti, ": CI 0x%04x", ci); break; case CBSP_CIDD_LAI: mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, TRUE); offset += 3; proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac); offset += 2; proto_item_append_text(ti, ": %s, LAC 0x%04x", mcc_mnc, lac); break; case CBSP_CIDD_LAC: proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac); offset += 2; proto_item_append_text(ti, ": LAC 0x%04x", lac); break; case CBSP_CIDD_ALL_IN_BSC: break; default: return -1; } return offset - base_offs; }
static void dissect_wcp_con_req(tvbuff_t *tvb, int offset, proto_tree *tree) { /* WCP connector request message */ guint32 alg_cnt; proto_tree_add_item(tree, hf_wcp_tid, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wcp_rev, tvb, offset + 2, 1, ENC_NA); proto_tree_add_item(tree, hf_wcp_init, tvb, offset + 3, 1, ENC_NA); proto_tree_add_item(tree, hf_wcp_seq_size, tvb, offset + 4, 1, ENC_NA); proto_tree_add_item_ret_uint(tree, hf_wcp_alg_cnt, tvb, offset + 5, 1, ENC_NA, &alg_cnt); proto_tree_add_item(tree, hf_wcp_alg_a, tvb, offset + 6, 1, ENC_NA); if ( alg_cnt > 1) proto_tree_add_item(tree, hf_wcp_alg_b, tvb, offset + 7, 1, ENC_NA); if ( alg_cnt > 2) proto_tree_add_item(tree, hf_wcp_alg_c, tvb, offset + 8, 1, ENC_NA); if ( alg_cnt > 3) proto_tree_add_item(tree, hf_wcp_alg_d, tvb, offset + 9, 1, ENC_NA); }
/** *ZigBee Device Profile dissector for the backup source binding * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_req_backup_source_bind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *field_tree; guint offset = 0; guint32 i, table_count; proto_tree_add_item(tree, hf_zbee_zdp_table_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_table_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &table_count); offset += 2; field_tree = proto_tree_add_subtree(tree, tvb, offset, table_count*(int)sizeof(guint64), ett_zbee_zdp_bind_source, NULL, "Source Table"); for (i=0; i<table_count; i++) zbee_parse_eui64(field_tree, hf_zbee_zdp_bind_src64, tvb, &offset, (int)sizeof(guint64), NULL); /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_backup_source_bind */
static int dissect_cmd_unlink(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, usbip_conv_info_t *usbip_info, usbip_transaction_t *trans) { usbip_transaction_t *victim; guint32 seqnum; col_set_str(pinfo->cinfo, COL_INFO, "URB Unlink"); proto_tree_add_item_ret_uint(tree, hf_usbip_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &seqnum); trans->unlink_seqnum = seqnum; offset += 4; victim = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum); if (victim) { proto_item *ti; ti = proto_tree_add_uint(tree, hf_usbip_vic_frame, NULL, 0, 0, victim->cmd_frame); PROTO_ITEM_SET_GENERATED(ti); } return offset; }
/** *ZigBee Device Profile dissector for the backup binding * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ void dissect_zbee_zdp_req_backup_bind_table(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 version) { proto_tree *field_tree; guint offset = 0; guint32 i, table_count; proto_tree_add_item(tree, hf_zbee_zdp_table_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_zbee_zdp_index, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item_ret_uint(tree, hf_zbee_zdp_table_count, tvb, offset, 2, ENC_LITTLE_ENDIAN, &table_count); offset += 2; field_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_zbee_zdp_bind, NULL, "Binding Table"); for (i=0; i<table_count; i++) { zdp_parse_bind_table_entry(field_tree, tvb, &offset, version); } /* for */ /* Dump any leftover bytes. */ zdp_dump_excess(tvb, offset, pinfo, tree); } /* dissect_zbee_zdp_req_backup_bind_table */
static int usbip_dissect_urb(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, proto_tree *orig, int offset, usbip_conv_info_t *usbip_info) { proto_item *ti = NULL; usbip_transaction_t *usbip_trans; guint32 command; guint32 devid; guint32 seqnum; guint32 dir; guint32 ep; struct usbip_header header; proto_tree_add_item_ret_uint(tree, hf_usbip_command, tvb, offset, 4, ENC_BIG_ENDIAN, &command); offset += 4; proto_tree_add_item_ret_uint(tree, hf_usbip_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &seqnum); offset += 4; dir = tvb_get_ntohl(tvb, offset + 4); ep = tvb_get_ntohl(tvb, offset + 8); devid = tvb_get_ntohl(tvb, offset); if (!PINFO_FD_VISITED(pinfo)) { if (command == OP_CMD_SUBMIT || command == OP_CMD_UNLINK) { usbip_trans = wmem_new(wmem_file_scope(), usbip_transaction_t); usbip_trans->devid = devid; usbip_trans->dir = dir; usbip_trans->ep = ep; usbip_trans->seqnum = seqnum; usbip_trans->cmd_frame = pinfo->num; usbip_trans->ret_frame = 0; usbip_trans->unlink_seqnum = 0; wmem_tree_insert32(usbip_info->pdus, seqnum, (void *) usbip_trans); } else { usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum); if (usbip_trans) usbip_trans->ret_frame = pinfo->num; } } else { usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum); } if (!usbip_trans) { usbip_trans = wmem_new(wmem_packet_scope(), usbip_transaction_t); usbip_trans->cmd_frame = 0; usbip_trans->ret_frame = 0; usbip_trans->devid = 0; usbip_trans->unlink_seqnum = 0; usbip_trans->seqnum = seqnum; } /* only the OP_CMD_SUBMIT has a valid devid - in all other case we have to restore it from the transaction */ if (command == OP_RET_SUBMIT || command == OP_RET_UNLINK) { devid = usbip_trans->devid; ep = usbip_trans->ep; dir = usbip_trans->dir; } ti = proto_tree_add_uint(tree, hf_usbip_cmd_frame, NULL, 0, 0, usbip_trans->cmd_frame); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_ret_frame, NULL, 0, 0, usbip_trans->ret_frame); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_devid, NULL, 0, 0, devid); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_direction, NULL, 0, 0, dir); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_ep, NULL, 0, 0, ep); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(tree, hf_usbip_devid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_usbip_direction, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_usbip_ep, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; header.ep = ep; header.dir = dir; header.devid = devid & 0x00ff; header.busid = devid >> 16; switch (command) { case OP_CMD_SUBMIT: offset = dissect_cmd_submit(pinfo, tree, tvb, offset); dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header); break; case OP_CMD_UNLINK: offset = dissect_cmd_unlink(pinfo, tree, tvb, offset, usbip_info, usbip_trans); break; case OP_RET_SUBMIT: { guint32 status; status = tvb_get_ntohl(tvb, offset); offset = dissect_ret_submit(pinfo, tree, tvb, offset); if (status == 0) dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header); break; } case OP_RET_UNLINK: offset = dissect_ret_unlink(pinfo, tree, tvb, offset, usbip_info, usbip_trans->unlink_seqnum); break; default: proto_tree_add_item(tree, hf_usbip_urb_data, tvb, offset, -1, ENC_NA); offset = tvb_reported_length_remaining(tvb, offset); expert_add_info_format( pinfo, ti, &ei_usbip, "Dissector for USBIP Command" " (%x) code not implemented, Contact" " Wireshark developers if you want this supported", command); proto_item_append_text(ti, ": Undecoded"); break; } return offset; }
/* Process an APP1 block. * * XXX - This code only works on US-ASCII systems!!! */ static int process_app1_segment(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 len, guint16 marker, const char *marker_name, gboolean show_first_identifier_not_jfif) { proto_item *ti; proto_tree *subtree; char *str; gint str_size; int offset = 0; int tiff_start; ti = proto_tree_add_item(tree, hf_marker_segment, tvb, 0, -1, ENC_NA); subtree = proto_item_add_subtree(ti, ett_marker_segment); proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker); proto_tree_add_item(subtree, hf_marker, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(subtree, hf_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; str = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &str_size, ENC_ASCII); ti = proto_tree_add_item(subtree, hf_identifier, tvb, offset, str_size, ENC_ASCII|ENC_NA); offset += str_size; if (show_first_identifier_not_jfif && strcmp(str, "JFIF") != 0) { expert_add_info(pinfo, ti, &ei_file_jpeg_first_identifier_not_jfif); } if (strcmp(str, "Exif") == 0) { /* * Endianness */ int encoding; guint16 val_16; guint32 val_32, num_fields; proto_item* tiff_item; offset++; /* Skip a byte supposed to be 0x00 */ tiff_start = offset; val_16 = tvb_get_ntohs(tvb, offset); if (val_16 == 0x4949) { encoding = ENC_LITTLE_ENDIAN; proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16, "little endian"); } else if (val_16 == 0x4D4D) { encoding = ENC_BIG_ENDIAN; proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16, "big endian"); } else { /* Error: invalid endianness encoding */ proto_tree_add_uint_format_value(subtree, hf_endianness, tvb, offset, 2, val_16, "Incorrect encoding 0x%04x- skipping the remainder of this application marker", val_16); return offset; } offset += 2; /* * Fixed value 42 = 0x002a */ offset += 2; /* * Offset to IFD */ val_32 = tvb_get_guint32(tvb, offset, encoding); tiff_item = proto_tree_add_uint_format_value(subtree, hf_start_ifd_offset, tvb, offset, 4, val_32, "%u bytes", val_32); offset += 4; /* * Check for a bogus val_32 value. * XXX - bogus value message should also deal with a * value that's too large and causes an overflow. * Or should it just check against the segment length, * which is 16 bits? */ if (val_32 + tiff_start < (guint32)offset) { expert_add_info_format(pinfo, tiff_item, &ei_start_ifd_offset, " (bogus, should be >= %u)", offset- tiff_start); return offset; } /* * Skip the following portion */ if (val_32 + tiff_start > (guint32)offset) { proto_tree_add_bytes_format_value(subtree, hf_skipped_tiff_data, tvb, offset, val_32 + tiff_start - offset, NULL, "%u bytes", val_32 + tiff_start - offset); } for (;;) { offset = val_32 + tiff_start; /* * Process the IFD */ proto_tree_add_item_ret_uint(subtree, hf_ifd_num_fields, tvb, offset, 2, encoding, &num_fields); offset += 2; while (num_fields-- > 0) { proto_tree_add_item(subtree, hf_idf_tag, tvb, offset, 2, encoding); offset += 2; proto_tree_add_item(subtree, hf_idf_type, tvb, offset, 2, encoding); offset += 2; proto_tree_add_item(subtree, hf_idf_count, tvb, offset, 4, encoding); offset += 4; proto_tree_add_item(subtree, hf_idf_offset, tvb, offset, 4, encoding); offset += 4; } /* * Offset to the next IFD */ val_32 = tvb_get_guint32(tvb, offset, encoding); tiff_item = proto_tree_add_uint_format_value(subtree, hf_next_ifd_offset, tvb, offset, 4, val_32, "%u bytes", val_32); offset += 4; if (val_32 != 0 && val_32 + tiff_start < (guint32)offset) { expert_add_info_format(pinfo, tiff_item, &ei_next_ifd_offset, " (bogus, should be >= %u)", offset + tiff_start); return offset; } if (val_32 == 0) break; } } else { proto_tree_add_bytes_format_value(subtree, hf_remain_seg_data, tvb, offset, -1, NULL, "%u bytes", len - 2 - str_size); proto_item_append_text(ti, " (Unknown identifier)"); } return offset; }
static void _dissect_uasip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, e_ua_direction direction) { proto_item *uasip_item, *tlv_item, *tlv_len_item; proto_tree *uasip_tree, *connect_tree; guint8 opcode; guint32 type, length; gint offset = 0; if (noesip_enabled) { col_append_str(pinfo->cinfo, COL_PROTOCOL, "/NOE"); } else { col_append_str(pinfo->cinfo, COL_PROTOCOL, "/DL"); } opcode = tvb_get_guint8(tvb, offset); offset++; ua_tap_info.opcode = opcode; ua_tap_info.expseq = 0; ua_tap_info.sntseq = 0; col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); uasip_item = proto_tree_add_protocol_format(tree, proto_uasip, tvb, 0, 5, "SIP/NOE Protocol, %s", val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)")); uasip_tree = proto_item_add_subtree(uasip_item, ett_uasip); proto_tree_add_uint(uasip_tree, hf_uasip_opcode, tvb, 0, 1, opcode); switch(opcode) { case UAUDP_CONNECT: { while(tvb_reported_length_remaining(tvb, offset) > 0) { type = tvb_get_guint8(tvb, offset+0); connect_tree = proto_tree_add_subtree(uasip_tree, tvb, offset, 0, ett_uasip_tlv, &tlv_item, val_to_str_ext(type, &uaudp_connect_vals_ext, "Unknown %d")); proto_tree_add_uint(connect_tree, hf_uasip_type, tvb, offset, 1, type); offset++; tlv_len_item = proto_tree_add_item_ret_uint(connect_tree, hf_uasip_length, tvb, offset, 1, ENC_NA, &length); proto_item_set_len(tlv_item, length+2); offset++; switch(type) { case UAUDP_CONNECT_VERSION: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_version, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_WINDOW_SIZE: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_window_size, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_MTU: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_mtu, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_UDP_LOST: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_udp_lost, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_UDP_LOST_REINIT: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_udp_lost_reinit, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_KEEPALIVE: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_keepalive, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_IP_TOS: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_qos_ip_tos, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_8021_VLID: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_qos_8021_vlid, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; case UAUDP_CONNECT_QOS_8021_PRI: if ((length >= 1) && (length <= 4)) { proto_tree_add_item(connect_tree, hf_uasip_qos_8021_pri, tvb, offset, length, ENC_BIG_ENDIAN); } else { expert_add_info_format(pinfo, tlv_len_item, &ei_uasip_tlv_length, "Invalid length %d", length); } break; default: break; } offset += length; } } break; case UAUDP_NACK: { proto_tree_add_item_ret_uint(uasip_tree, hf_uasip_expseq, tvb, offset, 2, ENC_BIG_ENDIAN, &ua_tap_info.expseq); /*offset += 2;*/ if (noesip_enabled) { col_add_fstr(pinfo->cinfo, COL_INFO, "NACK"); } else { col_add_fstr(pinfo->cinfo, COL_INFO, "NACK exp:%d", ua_tap_info.expseq); } } break; case UAUDP_DATA: { int datalen; proto_tree_add_item_ret_uint(uasip_tree, hf_uasip_expseq, tvb, offset+0, 2, ENC_BIG_ENDIAN, &ua_tap_info.expseq); proto_tree_add_item_ret_uint(uasip_tree, hf_uasip_sntseq, tvb, offset+2, 2, ENC_BIG_ENDIAN, &ua_tap_info.sntseq); offset += 4; datalen = tvb_reported_length_remaining(tvb, offset); if (noesip_enabled) { if (datalen > 0) { if (direction == SYS_TO_TERM) { call_dissector(ua_sys_to_term_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree); } else if (direction == TERM_TO_SYS) { call_dissector(ua_term_to_sys_handle, tvb_new_subset_length(tvb, offset, datalen), pinfo, tree); } else { col_add_str(pinfo->cinfo, COL_INFO, "DATA - Couldn't resolve direction."); } } else { col_add_str(pinfo->cinfo, COL_INFO, "ACK"); } } else { if (datalen > 0) { col_add_fstr(pinfo->cinfo, COL_INFO, "DATA exp:%d", ua_tap_info.expseq); col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq); } else { col_add_fstr(pinfo->cinfo, COL_INFO, "ACK exp:%d", ua_tap_info.expseq); col_append_fstr(pinfo->cinfo, COL_INFO, " snt:%d", ua_tap_info.sntseq); } } } break; default: break; } #if 0 tap_queue_packet(uasip_tap, pinfo, &ua_tap_info); #endif }
static int dissect_device(proto_tree *tree, tvbuff_t *tvb, int offset) { guint32 product; guint32 vendor_id; guint32 product_id; /* Device path on host (usually /sys/devices/usb/... */ proto_tree_add_item(tree, hf_usbip_path, tvb, offset, 256, ENC_ASCII | ENC_NA); offset += 256; /* Bus id string - Id of the bus the device is connected to */ proto_tree_add_item(tree, hf_usbip_busid, tvb, offset, 32, ENC_ASCII | ENC_NA); offset += 32; /* bus number */ proto_tree_add_item(tree, hf_usbip_busnum, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* device number */ proto_tree_add_item(tree, hf_usbip_devnum, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* USB Speed */ proto_tree_add_item(tree, hf_usbip_speed, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* idVendor */ proto_tree_add_item_ret_uint(tree, hf_usbip_idVendor, tvb, offset, 2, ENC_BIG_ENDIAN, &vendor_id); offset += 2; /* idProduct */ product_id = tvb_get_ntohs(tvb, offset); product = vendor_id << 16 | product_id; proto_tree_add_uint_format_value(tree, hf_usbip_idProduct, tvb, offset, 2, product_id, "%s (0x%04x)", val_to_str_ext_const(product, &ext_usb_products_vals, "Unknown"), product_id); offset += 2; /* bcdDevice */ proto_tree_add_item(tree, hf_usbip_bcdDevice, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Device Class */ proto_tree_add_item(tree, hf_usbip_bDeviceClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Device Sub Class */ proto_tree_add_item(tree, hf_usbip_bDeviceSubClass, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Device Protocol */ proto_tree_add_item(tree, hf_usbip_bDeviceProtocol, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Current Configuration */ proto_tree_add_item(tree, hf_usbip_bConfigurationValue, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Number of Configurations */ proto_tree_add_item(tree, hf_usbip_bNumConfigurations, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Number of Interfaces */ proto_tree_add_item(tree, hf_usbip_bNumInterfaces, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; return offset; }
static void dissect_usb_i1d3_response( tvbuff_t *tvb, packet_info *pinfo, usb_i1d3_conversation_t *conversation, proto_tree *tree) { // The response packet does not contain any information about the command // it is a response to, so we need to reconstruct this information using the // previous packet that we saw. // // Note: currently, for simplicity's sake, this assumes that there is only // one inflight request at any given time - in other words, that there is no // pipelining going on. It is not clear if the device would even be able to // service more than one request at the same time in the first place. usb_i1d3_transaction_t *transaction; if (!PINFO_FD_VISITED(pinfo)) { transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->request_to_transaction, GUINT_TO_POINTER(conversation->previous_packet)); if (transaction) { DISSECTOR_ASSERT(transaction->response == 0); transaction->response = pinfo->num; wmem_map_insert( conversation->response_to_transaction, GUINT_TO_POINTER(transaction->response), (void *)transaction); } } else { // After the first pass, we can't use previous_packet anymore since // there is no guarantee the dissector is called in order, so we use // the reverse mapping that we populated above. transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->response_to_transaction, GUINT_TO_POINTER(pinfo->num)); } if (transaction) { DISSECTOR_ASSERT(transaction->response == pinfo->num); DISSECTOR_ASSERT(transaction->request != 0); } proto_item *request_item = proto_tree_add_uint( tree, hf_usb_i1d3_request_in, tvb, 0, 0, transaction ? transaction->request : 0); PROTO_ITEM_SET_GENERATED(request_item); if (!transaction) { expert_add_info(pinfo, request_item, &ei_usb_i1d3_unexpected_response); } else { proto_item *command_code_item = proto_tree_add_uint( tree, hf_usb_i1d3_command_code, tvb, 0, 0, transaction->command_code); PROTO_ITEM_SET_GENERATED(command_code_item); } const gchar *command_string = transaction ? try_val_to_str( transaction->command_code, usb_i1d3_command_code_strings) : NULL; if (!command_string) command_string = "unknown"; guint32 response_code; proto_item *response_code_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_response_code, tvb, 0, 1, ENC_NA, &response_code); proto_item_append_text( response_code_item, " (%s)", (response_code == 0) ? "OK" : "error"); if (response_code != 0) { col_add_fstr( pinfo->cinfo, COL_INFO, "Error code %u (%s)", response_code, command_string); expert_add_info(pinfo, response_code_item, &ei_usb_i1d3_error); return; } col_add_fstr(pinfo->cinfo, COL_INFO, "OK (%s)", command_string); if (!transaction) return; // As mentioned in ArgyllCMS spectro/i1d3.c, the second byte is usually the // first byte of the command code, except for GET_DIFF. if (transaction->command_code != USB_I1D3_GET_DIFF) { guint32 echoed_command_code; proto_item *echoed_command_code_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_echoed_command_code, tvb, 1, 1, ENC_NA, &echoed_command_code); guint8 expected_command_code = transaction->command_code >> 8; proto_item_append_text( echoed_command_code_item, " [expected 0x%02x]", expected_command_code); if (echoed_command_code != expected_command_code) { expert_add_info( pinfo, echoed_command_code_item, &ei_usb_i1d3_echoed_command_code_mismatch); } }
static void dissect_usb_i1d3_command( tvbuff_t *tvb, packet_info *pinfo, usb_i1d3_conversation_t *conversation, proto_tree *tree) { // Parsing the command code is a bit tricky: if the most significant // byte is non-zero, the command code is the most significant byte, // *and* the next byte is the first byte of the payload. guint32 command_code = tvb_get_ntohs(tvb, 0); guint32 command_code_msb = command_code & 0xff00; gint command_code_length = 2; if (command_code_msb) { command_code = command_code_msb; command_code_length = 1; } proto_item *command_code_item = proto_tree_add_uint( tree, hf_usb_i1d3_command_code, tvb, 0, command_code_length, command_code); usb_i1d3_transaction_t *transaction; if (!PINFO_FD_VISITED(pinfo)) { transaction = usb_i1d3_create_transaction(conversation, pinfo->num); transaction->command_code = command_code; } else { transaction = (usb_i1d3_transaction_t *)wmem_map_lookup( conversation->request_to_transaction, GUINT_TO_POINTER(pinfo->num)); } DISSECTOR_ASSERT(transaction); if (transaction->response != 0) { proto_item *response_item = proto_tree_add_uint( tree, hf_usb_i1d3_response_in, tvb, 0, 0, transaction->response); PROTO_ITEM_SET_GENERATED(response_item); } const gchar *command_code_string = try_val_to_str( command_code, usb_i1d3_command_code_strings); if (command_code_string) { col_set_str(pinfo->cinfo, COL_INFO, command_code_string); } else { expert_add_info(pinfo, command_code_item, &ei_usb_i1d3_unknown_command); col_set_str(pinfo->cinfo, COL_INFO, "Unknown command"); } switch (command_code) { case USB_I1D3_LOCKRESP: { // TODO: verify that the challenge response is correct proto_tree_add_item( tree, hf_usb_i1d3_challenge_response, tvb, 24, 16, ENC_NA); break; } case USB_I1D3_READINTEE: { guint32 offset, length; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readintee_offset, tvb, 1, 1, ENC_NA, &offset); proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readintee_length, tvb, 2, 1, ENC_NA, &length); col_add_fstr(pinfo->cinfo, COL_INFO, "%s (offset: %u, length: %u)", command_code_string, offset, length); if (!PINFO_FD_VISITED(pinfo)) { transaction->offset = offset; transaction->length = length; } break; } case USB_I1D3_READEXTEE: { guint32 offset, length; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readextee_offset, tvb, 1, 2, ENC_BIG_ENDIAN, &offset); proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_readextee_length, tvb, 3, 1, ENC_NA, &length); col_add_fstr(pinfo->cinfo, COL_INFO, "%s (offset: %u, length: %u)", command_code_string, offset, length); if (!PINFO_FD_VISITED(pinfo)) { transaction->offset = offset; transaction->length = length; } break; } case USB_I1D3_MEASURE1: { guint32 integration_time; proto_item *integration_time_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_requested_integration_time, tvb, 1, 4, ENC_LITTLE_ENDIAN, &integration_time); double integration_time_seconds = integration_time / USB_I1D3_CLOCK_FREQUENCY; proto_item_append_text( integration_time_item, " [%.6f seconds]", integration_time_seconds); col_add_fstr(pinfo->cinfo, COL_INFO, "Measure for %.6fs", integration_time_seconds); break; } case USB_I1D3_MEASURE2: { proto_item *edge_count_item = proto_tree_add_item( tree, hf_usb_i1d3_requested_edge_count, tvb, 1, 6, ENC_NA); proto_tree *edge_count_tree = proto_item_add_subtree( edge_count_item, ett_usb_i1d3_requested_edge_count); guint32 edge_count_red, edge_count_green, edge_count_blue; proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_red, tvb, 1, 2, ENC_LITTLE_ENDIAN, &edge_count_red); proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_green, tvb, 3, 2, ENC_LITTLE_ENDIAN, &edge_count_green); proto_tree_add_item_ret_uint( edge_count_tree, hf_usb_i1d3_requested_edge_count_blue, tvb, 5, 2, ENC_LITTLE_ENDIAN, &edge_count_blue); proto_item_append_text( edge_count_item, ": R%u G%u B%u", edge_count_red, edge_count_green, edge_count_blue); col_add_fstr(pinfo->cinfo, COL_INFO, "Measure R%u G%u B%u edges", edge_count_red, edge_count_green, edge_count_blue); break; } case USB_I1D3_SETLED: { guint32 led_mode, led_offtime, led_ontime, pulse_count; proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_mode, tvb, 1, 1, ENC_NA, &led_mode); proto_item *led_offtime_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_offtime, tvb, 2, 1, ENC_NA, &led_offtime); double led_offtime_seconds = led_offtime / USB_I1D3_LED_OFFTIME_FACTOR; proto_item_append_text( led_offtime_item, " [%.6f seconds]", led_offtime_seconds); proto_item *led_ontime_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_ontime, tvb, 3, 1, ENC_NA, &led_ontime); double led_ontime_seconds = led_ontime / ((led_mode == USB_I1D3_LED_BLINK) ? USB_I1D3_LED_ONTIME_FACTOR : USB_I1D3_LED_ONTIME_FADE_FACTOR); proto_item_append_text( led_ontime_item, " [%.6f seconds]", led_ontime_seconds); proto_item *pulse_count_item = proto_tree_add_item_ret_uint( tree, hf_usb_i1d3_led_pulse_count, tvb, 4, 1, ENC_NA, &pulse_count); if (pulse_count == 0x80) { proto_item_append_text(pulse_count_item, " [infinity]"); col_add_fstr(pinfo->cinfo, COL_INFO, "Pulse LED off (%.6fs) and on (%.6fs%s) " "indefinitely", led_offtime_seconds, led_ontime_seconds, (led_mode == USB_I1D3_LED_BLINK_FADE_ON) ? " fading" : ""); } else { col_add_fstr(pinfo->cinfo, COL_INFO, "Pulse LED off (%.6fs) and on (%.6fs%s) " "%u times", led_offtime_seconds, led_ontime_seconds, (led_mode == USB_I1D3_LED_BLINK_FADE_ON) ? " fading" : "", pulse_count); } } } }
static void process_dpnet_query(proto_tree *dpnet_tree, tvbuff_t *tvb, packet_info *pinfo) { gint offset = 0, data_tvb_len; guint8 has_guid; guint8 is_query; proto_tree_add_item(dpnet_tree, hf_dpnet_lead, tvb, 0, 1, ENC_BIG_ENDIAN); offset += 1; is_query = tvb_get_guint8(tvb, offset); proto_tree_add_item(dpnet_tree, hf_dpnet_command, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dpnet_tree, hf_dpnet_payload, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; if(is_query == DPNET_ENUM_QUERY) { col_set_str(pinfo->cinfo, COL_INFO, "DPNET Enum Query"); has_guid = tvb_get_guint8(tvb, offset); proto_tree_add_item(dpnet_tree, hf_dpnet_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (has_guid & DPNET_QUERY_GUID) { proto_tree_add_item(dpnet_tree, hf_dpnet_application, tvb, offset, 16, ENC_BIG_ENDIAN); offset += 16; } data_tvb_len = tvb_reported_length_remaining(tvb, offset); if(data_tvb_len) proto_tree_add_item(dpnet_tree, hf_dpnet_data, tvb, offset, data_tvb_len, ENC_NA); } else if(is_query == DPNET_ENUM_RESPONSE) { guint32 session_offset, session_size; guint32 application_offset, application_size; col_set_str(pinfo->cinfo, COL_INFO, "DPNET Enum Response"); proto_tree_add_item(dpnet_tree, hf_dpnet_reply_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_desc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_bitmask(dpnet_tree, tvb, offset, hf_dpnet_desc_flags, ett_dpnet_desc_flags, desc_flags, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_max_players, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_current_players, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_session_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &session_offset); offset += 4; proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_session_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &session_size); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_password_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_password_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_reserved_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_reserved_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_application_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &application_offset); offset += 4; proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_application_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &application_size); offset += 4; proto_tree_add_item(dpnet_tree, hf_dpnet_instance, tvb, offset, 16, ENC_LITTLE_ENDIAN); offset += 16; proto_tree_add_item(dpnet_tree, hf_dpnet_application, tvb, offset, 16, ENC_LITTLE_ENDIAN); if(session_offset) { /* session_offset starts from the hf_dpnet_payload */ proto_tree_add_item(dpnet_tree, hf_dpnet_session_name, tvb, session_offset + 4, session_size, ENC_UTF_16|ENC_LITTLE_ENDIAN); } if(application_offset) { /* application_offset starts from the hf_dpnet_payload */ proto_tree_add_item(dpnet_tree, hf_dpnet_application_data, tvb, application_offset + 4, application_size, ENC_NA); } } }
static void dissect_dlm_migrate_lockres(proto_tree *tree, tvbuff_t *tvb, int offset) { unsigned int i; guint32 num_locks; static const int * mres_flags[] = { &hf_dlm_mres_flag_recovery, &hf_dlm_mres_flag_migration, &hf_dlm_mres_flag_all_done, NULL }; /* master */ proto_tree_add_item(tree, hf_dlm_master, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* lockname_len */ proto_tree_add_item(tree, hf_dlm_namelen, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* num_locks */ proto_tree_add_item_ret_uint(tree, hf_dlm_mres_num_locks, tvb, offset, 1, ENC_BIG_ENDIAN, &num_locks); offset += 1; /* no locks were found on this lockres! done! */ if (num_locks == 0) return; /* flags */ proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_dlm_mres_flags, ett_mres_flags, mres_flags, ENC_BIG_ENDIAN, BMT_NO_INT | BMT_NO_FALSE | BMT_NO_TFS); offset += 1; /* total_locks */ proto_tree_add_item(tree, hf_dlm_mres_total_locks, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* mig_cookie */ offset = dlm_cookie_handler(tree, tvb, offset, hf_dlm_mres_mig_cookie); /* lockname */ proto_tree_add_item(tree, hf_dlm_name, tvb, offset, 32, ENC_ASCII|ENC_NA); offset += 32; /* lvb */ proto_tree_add_item(tree, hf_dlm_lvb1, tvb, offset, 24, ENC_NA); offset += 24; proto_tree_add_item(tree, hf_dlm_lvb2, tvb, offset, 24, ENC_NA); offset += 24; proto_tree_add_item(tree, hf_dlm_lvb3, tvb, offset, 16, ENC_NA); offset += 16; /* dlm_migratable_lock */ for (i = 0; i < num_locks; i++) { proto_tree *subtree; subtree = proto_tree_add_subtree_format(tree, tvb, offset, 16, ett_migrate_lockres_locks, NULL, "Locks%d: ", i + 1); /* cookie */ offset = dlm_cookie_handler(subtree, tvb, offset, hf_dlm_mres_mig_cookie); proto_tree_add_item(subtree, hf_dlm_pad8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* list */ proto_tree_add_item(subtree, hf_dlm_mres_list, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* flags */ proto_tree_add_item(subtree, hf_dlm_mres_ml_flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* type */ proto_tree_add_item(subtree, hf_dlm_mres_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* convert_type */ proto_tree_add_item(subtree, hf_dlm_mres_convert_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* highest_blocked */ proto_tree_add_item(subtree, hf_dlm_mres_highest_blocked, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(subtree, hf_dlm_mres_node, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } }
static gint dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree) { guint8 sms_encoding = SMS_ENCODING_7BIT; int offset = base_offs; while (offset - base_offs < length) { guint8 tag; /* Information Element Identifier */ unsigned int len; /* Length of payload */ unsigned int len_len = 0;/* Length of "length" field (may be 0) */ proto_item *ti; proto_tree *att_tree, *subtree; guint32 tmp_u; int secs; tag = tvb_get_guint8(tvb, offset); offset++; switch (cbsp_att_tlvdef.def[tag].type) { case TLV_TYPE_TV: len = 1; len_len = 0; break; case TLV_TYPE_FIXED: len = cbsp_att_tlvdef.def[tag].fixed_len; len_len = 0; break; case TLV_TYPE_TLV: len = tvb_get_guint8(tvb, offset); break; case TLV_TYPE_TL16V: len = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN); len_len = 2; break; default: return length; } att_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+len_len+len, ett_cbsp_ie, &ti, "IE: %s", val_to_str(tag, cbsp_iei_names, "Unknown 0x%02x")); proto_tree_add_item(att_tree, hf_cbsp_iei, tvb, offset-1, 1, ENC_NA); if (len_len) proto_tree_add_uint(att_tree, hf_cbsp_ie_len, tvb, offset, len_len, len); offset += len_len; switch (tag) { case CBSP_IEI_MSG_CONTENT: dissect_cbsp_content_ie(tvb, pinfo, offset, len, att_tree, sms_encoding, ti); break; case CBSP_IEI_OLD_SERIAL_NR: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); proto_item_append_text(ti, ": 0x%04x", tmp_u); break; case CBSP_IEI_NEW_SERIAL_NR: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); proto_item_append_text(ti, ": 0x%04x", tmp_u); break; case CBSP_IEI_CATEGORY: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA,&tmp_u); proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_category_names, "")); break; case CBSP_IEI_REP_PERIOD: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_rep_period, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); proto_item_append_text(ti, ": %u", tmp_u); break; case CBSP_IEI_NUM_BCAST_REQ: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); proto_item_append_text(ti, ": %u", tmp_u); break; case CBSP_IEI_CAUSE: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA, &tmp_u); proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_cause_vals, "")); break; case CBSP_IEI_DCS: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA, &tmp_u); subtree = proto_item_add_subtree(att_tree, ett_cbsp_cbs_data_coding); sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, subtree, offset); proto_item_append_text(ti, ": 0x%02x", tmp_u); break; case CBSP_IEI_RECOVERY_IND: proto_tree_add_item(att_tree, hf_cbsp_recovery_ind, tvb, offset, len, ENC_NA); break; case CBSP_IEI_MSG_ID: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); proto_item_append_text(ti, ": 0x%04x", tmp_u); break; case CBSP_IEI_EMERG_IND: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA, &tmp_u); proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_emerg_ind_vals, "")); break; case CBSP_IEI_WARN_TYPE: proto_tree_add_item(att_tree, hf_cbsp_warn_type, tvb, offset, len, ENC_NA); break; case CBSP_IEI_CHANNEL_IND: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA, &tmp_u); proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_chan_ind_vals, "")); break; case CBSP_IEI_NUM_OF_PAGES: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA, &tmp_u); proto_item_append_text(ti, ": %u", tmp_u); break; case CBSP_IEI_SCHEDULE_PERIOD: proto_tree_add_item(att_tree, hf_cbsp_sched_period, tvb, offset, len, ENC_NA); break; case CBSP_IEI_NUM_OF_RES_SLOTS: proto_tree_add_item(att_tree, hf_cbsp_num_of_res_slots, tvb, offset, len, ENC_NA); break; case CBSP_IEI_BCAST_MSG_TYPE: proto_tree_add_item_ret_uint(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA, &tmp_u); proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_bcast_msg_type_vals, "")); break; case CBSP_IEI_WARNING_PERIOD: secs = cbsp_warn_period_to_secs(tvb_get_guint8(tvb, offset)); proto_tree_add_uint(att_tree, hf_cbsp_warning_period, tvb, offset, len, secs); proto_item_append_text(ti, ": %u (s)", secs); break; case CBSP_IEI_KEEP_ALIVE_REP_PERIOD: secs = cbsp_warn_period_to_secs(tvb_get_guint8(tvb, offset)); proto_tree_add_uint(att_tree, hf_cbsp_keepalive_period, tvb, offset, len, secs); proto_item_append_text(ti, ": %u (s)", secs); break; case CBSP_IEI_CELL_LIST: dissect_cell_id_list_ie(tvb, pinfo, offset, len, att_tree, ti); break; case CBSP_IEI_NUM_BCAST_COMPL_LIST: dissect_bc_compl_list_ie(tvb, pinfo, offset, len, att_tree, ti); break; case CBSP_IEI_FAILURE_LIST: dissect_failure_list_ie(tvb, pinfo, offset, len, att_tree, ti); break; case CBSP_IEI_RR_LOADING_LIST: dissect_rr_load_list_ie(tvb, pinfo, offset, len, att_tree, ti); break; case CBSP_IEI_WARN_SEC_INFO: /* this element is bogus / not used anyway, no need for a dissector */ default: /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */ proto_tree_add_item(att_tree, hf_cbsp_ie_payload, tvb, offset, len, ENC_NA); break; } offset += len; } return offset; }
static int dissect_papi_license_manager(tvbuff_t *tvb, packet_info *pinfo, guint offset, proto_tree *tree) { proto_item *ti; proto_tree *licmgr_tree, *licmgr_subtree; guint offset_end, payload_len; ti = proto_tree_add_item(tree, hf_papi_licmgr, tvb, offset, -1, ENC_NA); licmgr_tree = proto_item_add_subtree(ti, ett_papi_licmgr); proto_tree_add_item(licmgr_tree, hf_papi_licmgr_unknown, tvb, offset, 32, ENC_NA); offset += 32; proto_tree_add_item_ret_uint(licmgr_tree, hf_papi_licmgr_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &payload_len); offset += 2; col_set_str(pinfo->cinfo, COL_INFO, "PAPI - Licence Manager"); offset_end = offset + payload_len; while (offset< offset_end) { guint optlen, type; proto_item *tlv_item; type = tvb_get_ntohs(tvb, offset); optlen = tvb_get_ntohs(tvb, offset+2); tlv_item = proto_tree_add_item(licmgr_tree, hf_papi_licmgr_tlv, tvb, offset, 2+2+optlen, ENC_NA ); proto_item_append_text(tlv_item, ": (t=%d,l=%d) %s", type, optlen, val_to_str(type, licmgr_type_vals, "Unknown Type (%02d)") ); licmgr_subtree = proto_item_add_subtree(tlv_item, ett_papi_licmgr_tlv); proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_value, tvb, offset, optlen, ENC_NA); switch (type) { case 1: /* IP Address */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_ip, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %s", tvb_ip_to_str(tvb, offset)); break; case 2: /* Serial Number */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_serial_number, tvb, offset, 32, ENC_ASCII|ENC_NA); proto_item_append_text(tlv_item, ": %s", tvb_get_string_enc(wmem_packet_scope(),tvb, offset, optlen, ENC_ASCII)); break; case 3: /* Hostname */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_hostname, tvb, offset, optlen, ENC_ASCII|ENC_NA); proto_item_append_text(tlv_item, ": %s", tvb_get_string_enc(wmem_packet_scope(),tvb, offset, optlen, ENC_ASCII)); break; case 5: /* MAC Address */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_mac_address, tvb, offset, optlen, ENC_NA); proto_item_append_text(tlv_item, ": %s", tvb_get_ether_name(tvb, offset)); break; case 7: /* License AP remaining */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_ap_remaining, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 8: /* License PEF remaining */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_pef_remaining, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 9: /* License RFP remaining */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_rfp_remaining, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 10: /* License xSec remaining */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_xsec_remaining, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 11: /* License ACR remaining */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_acr_remaining, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 12: /* License AP used */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_ap_used, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 13: /* License PEF used */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_pef_used, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 14: /* License RFP used */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_rfp_used, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 15: /* License xSec used */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_xsec_used, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; case 16: /* License ACR used */ proto_tree_add_item(licmgr_subtree, hf_papi_licmgr_license_acr_used, tvb, offset, 4, ENC_NA); proto_item_append_text(tlv_item, ": %u", tvb_get_ntohl(tvb, offset)); break; } offset += optlen; } proto_tree_add_item(licmgr_tree, hf_papi_licmgr_padding, tvb, offset, -1, ENC_NA); offset += tvb_reported_length_remaining(tvb, offset); return offset; }