static int dissect_epmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *epmd_tree; proto_item *ti; ptvcursor_t *cursor; if (!check_epmd(tvb)) return(0); col_set_str(pinfo->cinfo, COL_PROTOCOL, "EPMD"); if (tree) { ti = proto_tree_add_item(tree, proto_epmd, tvb, 0, -1, FALSE); epmd_tree = proto_item_add_subtree(ti, ett_epmd); cursor = ptvcursor_new(epmd_tree, tvb, 0); if (pinfo->srcport==EPMD_PORT) { dissect_epmd_response(cursor); } else { dissect_epmd_request(cursor); } ptvcursor_free(cursor); } return(tvb_length(tvb)); }
/* * dissect the header of roofnet */ static void dissect_roofnet_header(proto_tree *tree, tvbuff_t *tvb, guint *offset) { ptvcursor_t *cursor = ptvcursor_new(tree, tvb, *offset); ptvcursor_add(cursor, hf_roofnet_version, 1, FALSE); ptvcursor_add(cursor, hf_roofnet_type, 1, FALSE); ptvcursor_add(cursor, hf_roofnet_nlinks, 1, FALSE); ptvcursor_add(cursor, hf_roofnet_next, 1, FALSE); ptvcursor_add(cursor, hf_roofnet_ttl, 2, FALSE); ptvcursor_add(cursor, hf_roofnet_cksum, 2, FALSE); ptvcursor_add(cursor, hf_roofnet_flags, 2, FALSE); ptvcursor_add(cursor, hf_roofnet_data_length, 2, FALSE); ptvcursor_add(cursor, hf_roofnet_query_dst, 4, FALSE); ptvcursor_add(cursor, hf_roofnet_seq, 4, FALSE); *offset = ptvcursor_current_offset(cursor); ptvcursor_free(cursor); }
static void dissect_vicp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *vicp_tree; ptvcursor_t* cursor; guint len; if (tvb_reported_length_remaining(tvb, 0) < 8) { /* Payload too small for VICP */ return; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "VICP"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_vicp, tvb, 0, -1, ENC_NA); vicp_tree = proto_item_add_subtree(ti, ett_vicp); cursor = ptvcursor_new(vicp_tree, tvb, 0); ptvcursor_add(cursor, hf_vicp_operation, 1, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_vicp_version, 1, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_vicp_sequence, 1, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_vicp_unused, 1, ENC_BIG_ENDIAN); len=tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_vicp_length, 4, ENC_BIG_ENDIAN); if(len==0) proto_tree_add_text(vicp_tree, tvb, 0, 0, "No data"); else ptvcursor_add(cursor, hf_vicp_data, len, ENC_NA); ptvcursor_free(cursor); }
/* * dissect the description of link in roofnet */ static void dissect_roofnet_link(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint link) { proto_item *it= NULL; proto_tree *subtree= NULL; ptvcursor_t *cursor= NULL; guint32 addr_src= 0; guint32 addr_dst= 0; addr_src= tvb_get_ipv4(tvb, *offset + ROOFNET_LINK_OFFSET_SRC); addr_dst= tvb_get_ipv4(tvb, *offset + ROOFNET_LINK_OFFSET_DST); it = proto_tree_add_text(tree, tvb, *offset, ROOFNET_LINK_LEN, "link: %u, src: %s, dst: %s", link, (char*)get_hostname(addr_src), (char*)get_hostname(addr_dst)); subtree= proto_item_add_subtree(it, ett_roofnet_link); proto_tree_add_ipv4(subtree, hf_roofnet_link_src, tvb, *offset, 4, addr_src); *offset += 4; cursor = ptvcursor_new(subtree, tvb, *offset); ptvcursor_add(cursor, hf_roofnet_link_forward, 4, FALSE); ptvcursor_add(cursor, hf_roofnet_link_rev, 4, FALSE); ptvcursor_add(cursor, hf_roofnet_link_seq, 4, FALSE); ptvcursor_add(cursor, hf_roofnet_link_age, 4, FALSE); ptvcursor_free(cursor); *offset = ptvcursor_current_offset(cursor); proto_tree_add_ipv4(subtree, hf_roofnet_link_dst, tvb, *offset, 4, addr_dst); /* don't increment offset here because the dst of this link is the src of the next one */ }
/* * dissect_pgm - The dissector for Pragmatic General Multicast */ static void dissect_pgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 pgmhdr_sport; guint16 pgmhdr_dport; guint8 pgmhdr_type; guint8 pgmhdr_opts; guint16 pgmhdr_cksum; guint16 pgmhdr_tsdulen; guint32 sqn; guint16 afi; guint plen = 0; proto_item *ti; const char *pktname; const char *pollstname; char *gsi; gboolean isdata = FALSE; guint pgmlen, reportedlen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGM"); col_clear(pinfo->cinfo, COL_INFO); if (tvb_reported_length_remaining(tvb, 0) < 18) { col_set_str(pinfo->cinfo, COL_INFO, "Packet too small"); return; } pinfo->srcport = pgmhdr_sport = tvb_get_ntohs(tvb, 0); pinfo->destport = pgmhdr_dport = tvb_get_ntohs(tvb, 2); pgmhdr_type = tvb_get_guint8(tvb, 4); pktname = val_to_str(pgmhdr_type, type_vals, "Unknown (0x%02x)"); pgmhdr_opts = tvb_get_guint8(tvb, 5); pgmhdr_cksum = tvb_get_ntohs(tvb, 6); gsi = tvb_bytes_to_str(wmem_packet_scope(), tvb, 8, 6); pgmhdr_tsdulen = tvb_get_ntohs(tvb, 14); sqn = tvb_get_ntohl(tvb, 16); switch(pgmhdr_type) { case PGM_SPM_PCKT: case PGM_NAK_PCKT: case PGM_NNAK_PCKT: case PGM_NCF_PCKT: case PGM_POLR_PCKT: case PGM_ACK_PCKT: col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s", pktname, sqn, gsi); break; case PGM_RDATA_PCKT: case PGM_ODATA_PCKT: col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s tsdulen %d", pktname, sqn, gsi, pgmhdr_tsdulen); isdata = TRUE; break; case PGM_POLL_PCKT: { guint16 poll_stype = tvb_get_ntohs(tvb, 22); pollstname = val_to_str(poll_stype, poll_subtype_vals, "Unknown (0x%02x)"); col_add_fstr(pinfo->cinfo, COL_INFO, "%-5s sqn 0x%x gsi %s subtype %s", pktname, sqn, gsi, pollstname); } break; default: return; } { proto_tree *pgm_tree = NULL; proto_tree *opt_tree = NULL; proto_tree *type_tree = NULL; proto_item *tf, *hidden_item; ptvcursor_t* cursor; ti = proto_tree_add_protocol_format(tree, proto_pgm, tvb, 0, -1, "Pragmatic General Multicast: Type %s" " Src Port %u, Dst Port %u, GSI %s", pktname, pgmhdr_sport, pgmhdr_dport, gsi); pgm_tree = proto_item_add_subtree(ti, ett_pgm); cursor = ptvcursor_new(pgm_tree, tvb, 0); hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 0, 2, ENC_BIG_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 2, 2, ENC_BIG_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); ptvcursor_add(cursor, hf_pgm_main_sport, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_dport, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_type, 1, ENC_BIG_ENDIAN); tf = proto_tree_add_uint_format_value(pgm_tree, hf_pgm_main_opts, tvb, ptvcursor_current_offset(cursor), 1, pgmhdr_opts, "%s (0x%x)", optsstr(pgmhdr_opts), pgmhdr_opts); opt_tree = proto_item_add_subtree(tf, ett_pgm_optbits); ptvcursor_set_tree(cursor, opt_tree); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_opt, 1, ENC_BIG_ENDIAN); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_netsig, 1, ENC_BIG_ENDIAN); ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_varlen, 1, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_main_opts_parity, 1, ENC_BIG_ENDIAN); ptvcursor_set_tree(cursor, pgm_tree); /* Checksum may be 0 (not available), but not for DATA packets */ if ((pgmhdr_type != PGM_RDATA_PCKT) && (pgmhdr_type != PGM_ODATA_PCKT) && (pgmhdr_cksum == 0)) { proto_tree_add_uint_format_value(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "not available"); } else { reportedlen = tvb_reported_length(tvb); pgmlen = tvb_captured_length(tvb); if (pgm_check_checksum && pgmlen >= reportedlen) { vec_t cksum_vec[1]; guint16 computed_cksum; SET_CKSUM_VEC_TVB(cksum_vec[0], tvb, 0, pgmlen); computed_cksum = in_cksum(&cksum_vec[0], 1); if (computed_cksum == 0) { proto_tree_add_uint_format_value(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "0x%04x [correct]", pgmhdr_cksum); } else { hidden_item = proto_tree_add_boolean(pgm_tree, hf_pgm_main_cksum_bad, tvb, ptvcursor_current_offset(cursor), 2, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint_format_value(pgm_tree, hf_pgm_main_cksum, tvb, ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "0x%04x [incorrect, should be 0x%04x]", pgmhdr_cksum, in_cksum_shouldbe(pgmhdr_cksum, computed_cksum)); } } else { ptvcursor_add_no_advance(cursor, hf_pgm_main_cksum, 2, ENC_BIG_ENDIAN); } } ptvcursor_advance(cursor, 2); ptvcursor_add(cursor, hf_pgm_main_gsi, 6, ENC_NA); ptvcursor_add(cursor, hf_pgm_main_tsdulen, 2, ENC_BIG_ENDIAN); switch(pgmhdr_type) { case PGM_SPM_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_spm, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_lead, 4, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ti = ptvcursor_add(cursor, hf_pgm_spm_pathafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_res, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_spm_path, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_spm_path6, 16, ENC_NA); break; default: expert_add_info(pinfo, ti, &ei_address_format_invalid); ptvcursor_free(cursor); return; } break; case PGM_RDATA_PCKT: case PGM_ODATA_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_data, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN); break; case PGM_NAK_PCKT: case PGM_NNAK_PCKT: case PGM_NCF_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_nak, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_nak_sqn, 4, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ti = ptvcursor_add(cursor, hf_pgm_nak_srcafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_nak_srcres, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_nak_src, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_nak_src6, 16, ENC_NA); break; default: expert_add_info(pinfo, ti, &ei_address_format_invalid); break; } afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ti = ptvcursor_add(cursor, hf_pgm_nak_grpafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_nak_grpres, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_nak_grp, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_nak_grp6, 16, ENC_NA); break; default: expert_add_info(pinfo, ti, &ei_address_format_invalid); ptvcursor_free(cursor); return; } break; case PGM_POLL_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_poll, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_poll_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_round, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_subtype, 2, ENC_BIG_ENDIAN); afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); ti = ptvcursor_add(cursor, hf_pgm_poll_pathafi, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_res, 2, ENC_BIG_ENDIAN); switch (afi) { case AFNUM_INET: ptvcursor_add(cursor, hf_pgm_poll_path, 4, ENC_BIG_ENDIAN); break; case AFNUM_INET6: ptvcursor_add(cursor, hf_pgm_poll_path6, 16, ENC_NA); break; default: expert_add_info(pinfo, ti, &ei_address_format_invalid); break; } ptvcursor_add(cursor, hf_pgm_poll_backoff_ivl, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_rand_str, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_poll_matching_bmask, 4, ENC_BIG_ENDIAN); break; case PGM_POLR_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_polr, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_polr_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_polr_round, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_polr_res, 2, ENC_BIG_ENDIAN); break; case PGM_ACK_PCKT: type_tree = proto_tree_add_subtree_format(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, ett_pgm_ack, NULL, "%s Packet", pktname); ptvcursor_set_tree(cursor, type_tree); ptvcursor_add(cursor, hf_pgm_ack_sqn, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_pgm_ack_bitmap, 4, ENC_BIG_ENDIAN); break; } if (pgmhdr_opts & PGM_OPT) dissect_pgmopts(cursor, pinfo, pktname); if (isdata) decode_pgm_ports(tvb, ptvcursor_current_offset(cursor), pinfo, tree, pgmhdr_sport, pgmhdr_dport); ptvcursor_free(cursor); } }
static int dissect_op_uavtalk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint8 packet_type = tvb_get_guint8(tvb, 1) & 0x7; guint32 objid = tvb_get_letohl(tvb, 4); guint32 payload_length = tvb_get_letohs(tvb, 2) - UAVTALK_HEADER_SIZE - UAVTALK_TRAILER_SIZE; guint32 reported_length = tvb_reported_length(tvb); col_set_str(pinfo->cinfo, COL_PROTOCOL, "UAVTALK"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); col_append_fstr(pinfo->cinfo, COL_INFO, "%s: 0x%08x", val_to_str_const(packet_type, uavtalk_packet_types, ""), objid); if (objid & 0x1) { col_append_str(pinfo->cinfo, COL_INFO, "(META)"); } if (tree) { /* we are being asked for details */ proto_tree *op_uavtalk_tree = NULL; ptvcursor_t *cursor; proto_item *ti = NULL; /* Add a top-level entry to the dissector tree for this protocol */ ti = proto_tree_add_item(tree, proto_op_uavtalk, tvb, 0, -1, ENC_NA); /* Create a subtree to contain the dissection of this protocol */ op_uavtalk_tree = proto_item_add_subtree(ti, ett_op_uavtalk); /* Dissect the packet and populate the subtree */ cursor = ptvcursor_new(op_uavtalk_tree, tvb, 0); /* Populate the fields in this protocol */ ptvcursor_add(cursor, hf_op_uavtalk_sync, 1, ENC_LITTLE_ENDIAN); ptvcursor_add_no_advance(cursor, hf_op_uavtalk_version, 1, ENC_LITTLE_ENDIAN); ptvcursor_add(cursor, hf_op_uavtalk_type, 1, ENC_LITTLE_ENDIAN); ptvcursor_add(cursor, hf_op_uavtalk_len, 2, ENC_LITTLE_ENDIAN); ptvcursor_add(cursor, hf_op_uavtalk_objid, 4, ENC_LITTLE_ENDIAN); offset = ptvcursor_current_offset(cursor); ptvcursor_free(cursor); proto_tree_add_item(op_uavtalk_tree, hf_op_uavtalk_crc8, tvb, reported_length - UAVTALK_TRAILER_SIZE, UAVTALK_TRAILER_SIZE, ENC_LITTLE_ENDIAN); } else { offset = UAVTALK_HEADER_SIZE; } { tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, reported_length - UAVTALK_HEADER_SIZE - UAVTALK_TRAILER_SIZE, payload_length); /* Check if we have an embedded objid to decode */ if ((packet_type == 0) || (packet_type == 2)) { /* Call any registered subdissector for this objid */ if (!dissector_try_uint(uavtalk_subdissector_table, objid, next_tvb, pinfo, tree)) { /* No subdissector registered, use the default data dissector */ call_dissector(data_handle, next_tvb, pinfo, tree); } } else { /* Render any remaining data as raw bytes */ call_dissector(data_handle, next_tvb, pinfo, tree); } } return UAVTALK_HEADER_SIZE + UAVTALK_TRAILER_SIZE; }
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 */ ptvcursor_free(cursor); 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"); ptvcursor_free(cursor); 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); } ptvcursor_free(cursor); }