static void dissect_ath(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; /* various lengths as reported in the packet itself */ guint8 hlen = 0; gint32 clen = 0; gint32 dlen = 0; gint32 plen = 0; /* detect the Tribes (Tomcat) version */ gint tribes_version_mark; /* store the info */ const gchar *info_srcaddr = ""; const gchar *info_domain = ""; const gchar *info_command = ""; proto_item *ti, *hlen_item; proto_tree *ath_tree; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATH"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); ti = proto_tree_add_item(tree, proto_ath, tvb, 0, -1, ENC_NA); ath_tree = proto_item_add_subtree(ti, ett_ath); /* Determine the Tribes version, which means determining the Tomcat version. * There are 2 versions : one for Tomcat 6, and one for Tomcat 7/8 * We know that Tomcat 6 packets end with "-E" (Ox2d 0x45 or 11589 in decimal) * and Tomcat 7/8 packets end with "Ox01 0x00" (256 in decimal) * This is why we read these 2 last bytes of the packet */ tribes_version_mark = tvb_get_ntohs(tvb, tvb_reported_length(tvb) - 2); /* dissecting a Tomcat 6 packet */ if (tribes_version_mark == 11589) { /* "-E" */ /* BEGIN */ proto_tree_add_item(ath_tree, hf_ath_begin, tvb, offset, 8, ENC_ASCII|ENC_NA); offset += 8; /* LENGTH */ proto_tree_add_item(ath_tree, hf_ath_length, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* ALIVE TIME */ proto_tree_add_item(ath_tree, hf_ath_alive, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; /* PORT */ proto_tree_add_item(ath_tree, hf_ath_port, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* SECURE PORT */ proto_tree_add_item(ath_tree, hf_ath_sport, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* HOST LENGTH */ hlen_item = proto_tree_add_item(ath_tree, hf_ath_hlen, tvb, offset, 1, ENC_BIG_ENDIAN); hlen = tvb_get_guint8(tvb, offset); offset += 1; /* HOST */ if (hlen == 4) { proto_tree_add_item(ath_tree, hf_ath_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN); info_srcaddr = tvb_ip_to_str(tvb, offset); } else if (hlen == 6) { proto_tree_add_item(ath_tree, hf_ath_ipv6, tvb, offset, 6, ENC_NA); info_srcaddr = tvb_ip6_to_str(tvb, offset); } else { expert_add_info(pinfo, hlen_item, &ei_ath_hlen_invalid); } offset += hlen; /* COMMAND LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_clen, tvb, offset, 4, ENC_BIG_ENDIAN, &clen); offset += 4; /* COMMAND */ proto_tree_add_item(ath_tree, hf_ath_comm, tvb, offset, clen, ENC_ASCII|ENC_NA); if (clen != -1) info_command = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, clen, ENC_ASCII); offset += clen; /* DOMAIN LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_dlen, tvb, offset, 4, ENC_BIG_ENDIAN, &dlen); offset += 4; /* DOMAIN */ proto_tree_add_item(ath_tree, hf_ath_domain, tvb, offset, dlen, ENC_ASCII|ENC_NA); if (dlen != 0) info_domain = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, dlen, ENC_ASCII); offset += dlen; /* UNIQUEID */ proto_tree_add_item(ath_tree, hf_ath_unique, tvb, offset, 16, ENC_NA); offset += 16; /* PAYLOAD LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_plen, tvb, offset, 4, ENC_BIG_ENDIAN, &plen); offset += 4; /* PAYLOAD */ proto_tree_add_item(ath_tree, hf_ath_payload, tvb, offset, plen, ENC_ASCII|ENC_NA); offset += plen; /* END */ proto_tree_add_item(ath_tree, hf_ath_end, tvb, offset, 8, ENC_ASCII|ENC_NA); } /* dissecting a Tomcat 7/8 packet */ else if (tribes_version_mark == 256) { /* BEGIN */ proto_tree_add_item(ath_tree, hf_ath_begin, tvb, offset, 8, ENC_ASCII|ENC_NA); offset += 8; proto_tree_add_item(ath_tree, hf_ath_padding, tvb, offset, 2, ENC_ASCII|ENC_NA); offset += 2; /* LENGTH */ proto_tree_add_item(ath_tree, hf_ath_length, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* ALIVE TIME */ proto_tree_add_item(ath_tree, hf_ath_alive, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; /* PORT */ proto_tree_add_item(ath_tree, hf_ath_port, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* SECURE PORT */ proto_tree_add_item(ath_tree, hf_ath_sport, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* UDP PORT, only in Tomcat 7/8 */ proto_tree_add_item(ath_tree, hf_ath_uport, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* HOST LENGTH */ hlen_item = proto_tree_add_item(ath_tree, hf_ath_hlen, tvb, offset, 1, ENC_BIG_ENDIAN); hlen = tvb_get_guint8(tvb, offset); offset += 1; /* HOST */ if (hlen == 4) { proto_tree_add_item(ath_tree, hf_ath_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN); info_srcaddr = tvb_ip_to_str(tvb, offset); } else if (hlen == 6) { proto_tree_add_item(ath_tree, hf_ath_ipv6, tvb, offset, 6, ENC_NA); info_srcaddr = tvb_ip6_to_str(tvb, offset); } else { expert_add_info(pinfo, hlen_item, &ei_ath_hlen_invalid); } offset += hlen; /* COMMAND LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_clen, tvb, offset, 4, ENC_BIG_ENDIAN, &clen); offset += 4; /* COMMAND */ proto_tree_add_item(ath_tree, hf_ath_comm, tvb, offset, clen, ENC_ASCII|ENC_NA); if (clen != -1) info_command = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, clen, ENC_ASCII); offset += clen; /* DOMAIN LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_dlen, tvb, offset, 4, ENC_BIG_ENDIAN, &dlen); offset += 4; /* DOMAIN */ proto_tree_add_item(ath_tree, hf_ath_domain, tvb, offset, dlen, ENC_ASCII|ENC_NA); if (dlen != 0) info_domain = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, dlen, ENC_ASCII); offset += dlen; /* UNIQUEID */ proto_tree_add_item(ath_tree, hf_ath_unique, tvb, offset, 16, ENC_NA); offset += 16; /* PAYLOAD LENGTH */ proto_tree_add_item_ret_int(ath_tree, hf_ath_plen, tvb, offset, 4, ENC_BIG_ENDIAN, &plen); offset += 4; /* PAYLOAD */ proto_tree_add_item(ath_tree, hf_ath_payload, tvb, offset, plen, ENC_ASCII|ENC_NA); offset += plen; /* END */ proto_tree_add_item(ath_tree, hf_ath_end, tvb, offset, 8, ENC_ASCII|ENC_NA); } else { proto_tree_add_expert(tree, pinfo, &ei_ath_hmark_invalid, tvb, offset, -1); return; } /* set the INFO column, and we're done ! */ if (strcmp(info_command, "") != 0) { if (strcmp(info_command, "BABY-ALEX") == 0) { if (strcmp(info_domain, "") != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, "%s is leaving domain %s", info_srcaddr, info_domain); } else { col_append_fstr(pinfo->cinfo, COL_INFO, "%s is leaving default domain", info_srcaddr); } } else { if (strcmp(info_domain, "") != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to domain %s", info_srcaddr, info_domain); } else { col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to default domain", info_srcaddr); } } } else { if (strcmp(info_domain, "") != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to domain %s", info_srcaddr, info_domain); } else { col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat from %s to default domain", info_srcaddr); } } }
{ return 0; } } static void dissect_header_0_9_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { proto_item *ti; proto_tree *nordic_ble_tree;//, *flags_tree; gboolean bad_crc = FALSE; /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_nordic_ble, tvb, 0, -1, ENC_NA); nordic_ble_tree = proto_item_add_subtree(ti, ett_nordic_ble); pinfo->p2p_dir = P2P_DIR_RECV; /*** PROTOCOL TREE ***/ dissect_packet_counter(tvb, nordic_ble_tree); bad_mic = dissect_flags(tvb, pinfo, nordic_ble_tree); dissect_channel(tvb, nordic_ble_tree); dissect_rssi(tvb, nordic_ble_tree); dissect_event_counter(tvb, nordic_ble_tree); bad_length = dissect_lengths(tvb, pinfo, nordic_ble_tree); dissect_ble_delta_time(tvb, nordic_ble_tree); }
static gboolean dissect_lengths(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 hlen, plen; proto_item* item; gboolean bad_length = FALSE; if (legacy_mode) { hlen = tvb_get_guint8(tvb, _0_9_7_LENGTH_POS); plen = _0_9_7_nordic_ble_MIN_LENGTH; } else { hlen = tvb_get_guint8(tvb, UART_PACKET_HEADER_LEN_INDEX); plen = tvb_get_guint8(tvb, UART_PACKET_PACKET_LEN_INDEX); } if ((hlen + plen) != tvb_length(tvb)) { if (!legacy_mode) { proto_tree_add_item(tree, hf_nordic_ble_header_length, tvb, UART_PACKET_HEADER_LEN_INDEX, 1, ENC_BIG_ENDIAN); } item = proto_tree_add_item(tree, hf_nordic_ble_payload_length, tvb, get_packet_length_index(), 1, ENC_BIG_ENDIAN); #if IS_VERSION_1_11 expert_add_info(pinfo, item, &ei_nordic_ble_bad_length); #elif IS_VERSION_1_10 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "UART packet lengths do not match actual packet length."); #endif bad_length = TRUE; } else if ((hlen + plen) < get_total_len_min()) { if (!legacy_mode) { proto_tree_add_item(tree, hf_nordic_ble_header_length, tvb, UART_PACKET_HEADER_LEN_INDEX, 1, ENC_BIG_ENDIAN); } item = proto_tree_add_item(tree, hf_nordic_ble_payload_length, tvb, get_packet_length_index(), 1, ENC_BIG_ENDIAN); #if IS_VERSION_1_11 expert_add_info(pinfo, item, &ei_nordic_ble_bad_length); #elif IS_VERSION_1_10 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "UART packet length is too small (likely corrupted)."); #endif bad_length = TRUE; } else if ((hlen + plen) > get_total_len_max()) { if (!legacy_mode) { proto_tree_add_item(tree, hf_nordic_ble_header_length, tvb, UART_PACKET_HEADER_LEN_INDEX, 1, ENC_BIG_ENDIAN); } item = proto_tree_add_item(tree, hf_nordic_ble_payload_length, tvb, get_packet_length_index(), 1, ENC_BIG_ENDIAN); #if IS_VERSION_1_11 expert_add_info(pinfo, item, &ei_nordic_ble_bad_length); #elif IS_VERSION_1_10 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "UART packet length is too large (likely corrupted)."); #endif bad_length = TRUE; } return bad_length; }
static void dissect_msdp_notification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, guint16 tlv_len) { guint8 error, error_sub; const value_string *vals; proto_tree_add_item(tree, hf_msdp_not_o, tvb, *offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_msdp_not_error, tvb, *offset, 1, ENC_BIG_ENDIAN); error = tvb_get_guint8(tvb, *offset); error &= 0x7F; /* Error is 7-bit field. O-bit is bit 8 */ *offset += 1; /* Depending on the Error Code, we collect the correct * value_strings for the Error subcode */ switch (error) { case MESSAGE_HEADER_ERROR: vals = hdr_error_vals; break; case SA_REQUEST_ERROR: vals = sa_req_error_vals; break; case SA_MESSAGE_SA_RESPONSE_ERROR: vals = sa_msg_error_vals; break; case FSM_ERROR: vals = fsm_error_vals; break; case HOLD_TIMER_EXPIRED: case NOTIFICATION: case CEASE: vals = sa_unspec_error_vals; break; default: vals = sa_unspec_error_vals; break; } error_sub = tvb_get_guint8(tvb, *offset); proto_tree_add_uint_format_value(tree, hf_msdp_not_error_sub, tvb, *offset, 1, error_sub, "%s (%u)", val_to_str_const(error_sub, vals, "<Unknown Error subcode>"), error_sub); *offset += 1; /* Do switch again, this time to dissect the data portion * correctly. Ugly. */ switch (error) { tvbuff_t *next_tvb; case SA_REQUEST_ERROR: add_notification_data_ipv4addr(tvb, tree, offset, hf_msdp_not_group_address); break; case SA_MESSAGE_SA_RESPONSE_ERROR: if (error_sub == 0) { break; } else if (error_sub == 1) { proto_tree_add_item(tree, hf_msdp_not_entry_count, tvb, *offset, 1, ENC_BIG_ENDIAN); *offset += 1; break; } else if (error_sub == 2) { add_notification_data_ipv4addr(tvb, tree, offset, hf_msdp_not_rp_address); break; } else if (error_sub == 3 || error_sub == 8) { add_notification_data_ipv4addr(tvb, tree, offset, hf_msdp_not_group_address); break; } else if (error_sub == 4) { add_notification_data_ipv4addr(tvb, tree, offset, hf_msdp_not_source_address); break; } else if (error_sub == 5) { proto_tree_add_item(tree, hf_msdp_not_sprefix_len, tvb, *offset, 1, ENC_BIG_ENDIAN); *offset += 1; break; } else if (error_sub == 6) { /* No break, causes fall through to next label */ } else if (error_sub == 7) { proto_tree_add_text(tree, tvb, *offset, tlv_len - 5, "Packet with unknown encapsulation: %u bytes", tlv_len - 5); *offset += tlv_len - 5; break; } else { proto_tree_add_text(tree, tvb, *offset, tlv_len - 5, "<Unknown data>: %u bytes", tlv_len -5); *offset += tlv_len - 5; break; } /* Fall through */ case MESSAGE_HEADER_ERROR: case NOTIFICATION: /* Data contains the message that had an error. Even a * broken Notification message causes a Notification * message with Error Code set to Notification to be * sent back. */ next_tvb = tvb_new_subset_remaining(tvb, *offset); dissect_msdp(next_tvb, pinfo, tree); break; case FSM_ERROR: case HOLD_TIMER_EXPIRED: case CEASE: /* Do nothing. These contain no data */ break; default: if (tlv_len - 5 > 0) proto_tree_add_text(tree, tvb, *offset, tlv_len - 5, "<Unknown data>: %u bytes", tlv_len -5); *offset += tlv_len - 5; break; } return; }
static void dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *usb_audio_tree, proto_tree *parent_tree, gint offset) { guint8 code; guint8 cable; gboolean save_fragmented; proto_tree *tree = NULL; col_set_str(pinfo->cinfo, COL_INFO, "USB-MIDI Event Packets"); code = tvb_get_guint8(tvb, offset); cable = (code & 0xF0) >> 4; code &= 0x0F; if (parent_tree) { proto_item *ti; ti = proto_tree_add_protocol_format(usb_audio_tree, proto_usb_audio, tvb, offset, 4, "USB Midi Event Packet"); tree = proto_item_add_subtree(ti, ett_usb_audio); proto_tree_add_item(tree, hf_midi_cable_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_code_index, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_event, tvb, offset+1, 3, ENC_BIG_ENDIAN); } save_fragmented = pinfo->fragmented; /* Reassemble SysEx commands */ if (is_sysex_code(code)) { tvbuff_t* new_tvb = NULL; fragment_head *frag_sysex_msg = NULL; pinfo->fragmented = TRUE; if (code == 0x04) { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, 3, TRUE); } else { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, (gint)(code - 4), FALSE); } if (is_last_sysex_packet_in_tvb(tvb, offset)) { new_tvb = process_reassembled_data(tvb, offset+1, pinfo, "Reassembled Message", frag_sysex_msg, &sysex_msg_frag_items, NULL, usb_audio_tree); if (code != 0x04) { /* Reassembled */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx Reassembled)"); } else { /* Not last packet of reassembled Short Message */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx fragment)"); } if (new_tvb) { call_dissector(sysex_handle, new_tvb, pinfo, parent_tree); } } } pinfo->fragmented = save_fragmented; }
static int dissect_mojito_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, mojito_header_data_t* header_data) { proto_tree *header_tree, *version_tree, *contact_tree, *flag_tree; proto_item *header_item, *contact_item, *flag_item; int start_offset = offset; int contact_start_offset; header_tree = proto_tree_add_subtree(tree, tvb, offset, 61, ett_mojito_header, &header_item, "Gnutella Header"); proto_tree_add_item(header_tree, hf_mojito_messageid, tvb, offset, 16, ENC_NA); offset += 16; proto_tree_add_item(header_tree, hf_mojito_fdhtmessage, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; version_tree = proto_tree_add_subtree(header_tree, tvb, offset, 2, ett_mojito_header_version, NULL, "Version"); proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* Payload Length : in Little Endian */ header_data->payloadlength = tvb_get_letohl(tvb, offset); proto_tree_add_item(header_tree, hf_mojito_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; header_data->opcode = tvb_get_guint8(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(header_data->opcode, opcodeflags, "Unknown")); proto_tree_add_item(header_tree, hf_mojito_opcode, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; contact_start_offset = offset; contact_tree = proto_tree_add_subtree(header_tree, tvb, offset, 35, ett_mojito_contact, &contact_item, "Originating Contact"); proto_tree_add_item(contact_tree, hf_mojito_vendor, tvb, offset, 4, ENC_ASCII|ENC_NA); offset += 4; version_tree = proto_tree_add_subtree(contact_tree, tvb, offset, 2, ett_mojito_contact_version, NULL, "Contact Version"); proto_tree_add_item(version_tree, hf_mojito_origmjrversion, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(version_tree, hf_mojito_origmnrversion, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(contact_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA); offset += 20; offset = dissect_mojito_address(tvb, pinfo, contact_tree, offset, "Socket Address"); if (offset == 0) { return 0; } proto_item_set_len(contact_item, offset - contact_start_offset); proto_tree_add_item(header_tree, hf_mojito_instanceid, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /*Flags*/ flag_item = proto_tree_add_item(header_tree, hf_mojito_flags, tvb, offset, 1, ENC_BIG_ENDIAN); flag_tree = proto_item_add_subtree(flag_item, ett_mojito_flags); proto_tree_add_item(flag_tree, hf_mojito_flags_shutdown, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flag_tree, hf_mojito_flags_firewalled, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(header_tree, hf_mojito_extendedlength, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_item_set_len(header_item, offset-start_offset); return offset; }
/* * Dissect ROS PDUs inside a PPDU. */ static int dissect_ros(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; conversation_t *conversation; ros_conv_info_t *ros_info = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* do we have application context from the acse dissector? */ if (data == NULL) return 0; asn1_ctx.private_data = data; /* save parent_tree so subdissectors can create new top nodes */ top_tree=parent_tree; conversation = find_or_create_conversation(pinfo); /* * Do we already have our info */ ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros); if (ros_info == NULL) { /* No. Attach that information to the conversation. */ ros_info = (ros_conv_info_t *)g_malloc(sizeof(ros_conv_info_t)); ros_info->matched=g_hash_table_new(ros_info_hash_matched, ros_info_equal_matched); ros_info->unmatched=g_hash_table_new(ros_info_hash_unmatched, ros_info_equal_unmatched); conversation_add_proto_data(conversation, proto_ros, ros_info); ros_info->next = ros_info_items; ros_info_items = ros_info; } item = proto_tree_add_item(parent_tree, proto_ros, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_ros); col_set_str(pinfo->cinfo, COL_PROTOCOL, "ROS"); col_clear(pinfo->cinfo, COL_INFO); while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=dissect_ros_ROS(FALSE, tvb, offset, &asn1_ctx , tree, -1); if(offset == old_offset){ item = proto_tree_add_text(tree, tvb, offset, -1,"Unknown ROS PDU"); if(item){ expert_add_info(pinfo, item, &ei_ros_unknown_ros_pdu); next_tree=proto_item_add_subtree(item, ett_ros_unknown); dissect_unknown_ber(pinfo, tvb, offset, next_tree); } break; } } return tvb_length(tvb); }
static void dissect_sapenqueue_conn_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint8 opcode){ proto_item *conn_admin = NULL; proto_tree *conn_admin_tree = NULL; conn_admin = proto_tree_add_item(tree, hf_sapenqueue_conn_admin, tvb, offset, -1, FALSE); conn_admin_tree = proto_item_add_subtree(conn_admin, ett_sapenqueue); switch (opcode){ case 0x01: /* Parameter Request */ case 0x02:{ /* Parameter Response */ gint name_length_remaining = 0; guint8 length = 0, total_length = 0; guint32 count = 0, id = 0, name_length = 0; proto_item *params = NULL, *param = NULL; proto_tree *params_tree = NULL, *param_tree = NULL; count = tvb_get_ntohl(tvb, offset); proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params_count, tvb, offset, 4, FALSE); offset += 4; params = proto_tree_add_item(conn_admin_tree, hf_sapenqueue_conn_admin_params, tvb, offset, 1, FALSE); params_tree = proto_item_add_subtree(params, ett_sapenqueue); while (count > 0 && tvb_offset_exists(tvb, offset)){ /* As we don't have the right size yet, start with 1 byte */ param = proto_tree_add_item(params_tree, hf_sapenqueue_conn_admin_param, tvb, offset, 1, FALSE); param_tree = proto_item_add_subtree(param, ett_sapenqueue); id = tvb_get_ntohl(tvb, offset); proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_id, tvb, offset, 4, FALSE); offset += 4; length = 4; if (id == 0x03){ /* Set Name parameter */ name_length = tvb_strsize(tvb, offset); if (name_length > 0) { proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_name, tvb, offset, name_length, FALSE); offset += name_length; length += name_length; } } else if (id == 0x04) { /* No support parameter */ /* This parameter appears to have more fields only for responses */ if (opcode == 0x02) { proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4; length += 4; } } else if (id == 0x06){ /* Set Unicode Support Parameter */ name_length = tvb_get_ntohl(tvb, offset); proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_len, tvb, offset, 4, FALSE); offset += 4; /* If the reported length is not correct, use the remaining of the packet as length */ name_length_remaining = tvb_captured_length_remaining(tvb, offset); if (name_length_remaining < 0){ expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_offset); break; } if ((guint32)name_length_remaining < name_length) { name_length = (guint32)name_length_remaining; expert_add_info(pinfo, param, &ei_sapenqueue_support_invalid_length); } proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, name_length, FALSE); offset += name_length; length += 4 + name_length; } else { /* The rest of the parameters have an integer value field */ proto_tree_add_item(param_tree, hf_sapenqueue_conn_admin_param_value, tvb, offset, 4, FALSE); offset += 4; length += 4; } /* Set the right size for the parameter tree */ proto_item_set_len(param, length); count -= 1; total_length += length; } proto_item_set_len(params, total_length); break; } } }
static void dissect_sapenqueue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 dest = 0, type = 0, opcode = 0; guint32 offset = 4; proto_item *ti = NULL; proto_tree *sapenqueue_tree = NULL; /* If the packet has less than 20 bytes we can be sure that is not an * Enqueue server packet. */ if (tvb_captured_length(tvb) < 20){ return; } /* Add the protocol to the column */ col_add_str(pinfo->cinfo, COL_PROTOCOL, "SAPENQUEUE"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); dest = tvb_get_guint8(tvb, offset + 16); col_append_fstr(pinfo->cinfo, COL_INFO, "Dest=%s", val_to_str(dest, hf_sapenqueue_dest_vals, "Unknown")); opcode = tvb_get_guint8(tvb, offset + 17); type = tvb_get_guint8(tvb, offset + 19); col_append_fstr(pinfo->cinfo, COL_INFO, ",Type=%s", val_to_str(type, hf_sapenqueue_type_vals, "Unknown")); if (dest == 0x06){ col_append_fstr(pinfo->cinfo, COL_INFO, ",Opcode=%s", val_to_str(opcode, hf_sapenqueue_conn_admin_opcode_vals, "Unknown")); } if (tree){ /* we are being asked for details */ /* Add the main sapenqueue subtree */ ti = proto_tree_add_item(tree, proto_sapenqueue, tvb, 0, -1, FALSE); sapenqueue_tree = proto_item_add_subtree(ti, ett_sapenqueue); proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_magic, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_id, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_length, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_length_frag, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_dest, tvb, offset, 1, FALSE); offset += 1; if (dest == 0x06){ /* This field is only relevant if the destination is Connection Admin */ proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_conn_admin_opcode, tvb, offset, 1, FALSE); } offset += 1; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_more_frags, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(sapenqueue_tree, hf_sapenqueue_type, tvb, offset, 1, FALSE); offset += 1; switch (dest){ case 0x03:{ /* Server Admin */ dissect_sapenqueue_server_admin(tvb, pinfo, sapenqueue_tree, offset); break; } case 0x06:{ /* Connection Admin */ dissect_sapenqueue_conn_admin(tvb, pinfo, sapenqueue_tree, offset, opcode); break; } } } }
static void dissect_jpeg( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) { proto_item *ti = NULL; proto_tree *jpeg_tree = NULL; proto_tree *main_hdr_tree = NULL; proto_tree *restart_hdr_tree = NULL; proto_tree *qtable_hdr_tree = NULL; guint32 fragment_offset = 0; guint16 len = 0; guint8 type = 0; guint8 q = 0; gint h = 0; gint w = 0; unsigned int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "JPEG"); col_set_str(pinfo->cinfo, COL_INFO, "JPEG message"); if ( tree ) { ti = proto_tree_add_item( tree, hfi_jpeg, tvb, offset, -1, ENC_NA ); jpeg_tree = proto_item_add_subtree( ti, ett_jpeg ); ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_main_hdr, tvb, offset, 8, ENC_NA); main_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_ts, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_offs, tvb, offset, 3, ENC_BIG_ENDIAN); fragment_offset = tvb_get_ntoh24(tvb, offset); offset += 3; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_type, tvb, offset, 1, ENC_BIG_ENDIAN); type = tvb_get_guint8(tvb, offset); offset += 1; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_q, tvb, offset, 1, ENC_BIG_ENDIAN); q = tvb_get_guint8(tvb, offset); offset += 1; w = tvb_get_guint8(tvb, offset) * 8; proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_width, tvb, offset, 1, w); offset += 1; h = tvb_get_guint8(tvb, offset) * 8; proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_height, tvb, offset, 1, h); offset += 1; if (type >= 64 && type <= 127) { ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_restart_hdr, tvb, offset, 4, ENC_NA); restart_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_interval, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_f, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_l, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_count, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } if (q >= 128 && fragment_offset == 0) { ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_qtable_hdr, tvb, offset, -1, ENC_NA); qtable_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_mbz, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_prec, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); len = tvb_get_ntohs(tvb, offset); offset += 2; if (len > 0) { proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_data, tvb, offset, len, ENC_NA); offset += len; } proto_item_set_len(ti, len + 4); } /* The rest of the packet is the JPEG data */ proto_tree_add_item( jpeg_tree, &hfi_rtp_jpeg_payload, tvb, offset, -1, ENC_NA ); } }
static void dissect_sapenqueue_server_admin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset){ guint8 opcode = 0; proto_item *server_admin = NULL; proto_tree *server_admin_tree = NULL; server_admin = proto_tree_add_item(tree, hf_sapenqueue_server_admin, tvb, offset, -1, FALSE); server_admin_tree = proto_item_add_subtree(server_admin, ett_sapenqueue); proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_version, tvb, offset, 1, FALSE); offset += 1; offset += 3; /* Unknown bytes */ proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_flag, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_length, tvb, offset, 4, FALSE); offset += 4; opcode = tvb_get_guint8(tvb, offset); proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_opcode, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_flags, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_rc, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_eyecatcher, tvb, offset, 4, FALSE); offset += 4; if (tvb_captured_length_remaining(tvb, offset) > 0){ switch(opcode){ case 0x06:{ /* EnAdmTraceRequest */ guint8 pattern_length = 0; guint32 nopatterns = 0, total_length = 0; proto_item *trace_request = NULL, *trace_request_patterns = NULL, *trace_request_pattern = NULL; proto_tree *trace_request_tree = NULL, *trace_request_patterns_tree = NULL, *trace_request_pattern_tree = NULL; trace_request = proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_trace_request, tvb, offset, -1, FALSE); trace_request_tree = proto_item_add_subtree(trace_request, ett_sapenqueue); proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_protocol_version, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_action, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_limit, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_thread, tvb, offset, 1, FALSE); offset += 1; offset += 4; /* TODO: Unknown field here */ proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_level, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_level, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_logging, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_max_file_size, tvb, offset, 4, FALSE); offset += 4; nopatterns = tvb_get_ntohl(tvb, offset); proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_nopatterns, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_nopatterns, tvb, offset, 4, FALSE); offset += 4; offset += 4; /* TODO: Unknown field here */ proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_eyecatcher, tvb, offset, 4, FALSE); offset += 4; /* As we don't have the right size yet, start with 1 byte */ trace_request_patterns = proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_patterns, tvb, offset, 1, FALSE); trace_request_patterns_tree = proto_item_add_subtree(trace_request_patterns, ett_sapenqueue); while (nopatterns > 0 && tvb_offset_exists(tvb, offset)){ /* As we don't have the right size yet, start with 1 byte */ trace_request_pattern = proto_tree_add_item(trace_request_patterns_tree, hf_sapenqueue_server_admin_trace_pattern, tvb, offset, 1, FALSE); trace_request_pattern_tree = proto_item_add_subtree(trace_request_pattern, ett_sapenqueue); pattern_length = tvb_get_guint8(tvb, offset) + 1; /* Pattern string is null terminated */ proto_tree_add_item(trace_request_pattern_tree, hf_sapenqueue_server_admin_trace_pattern_len, tvb, offset, 1, FALSE); offset += 1; /* Set the max length to the remaining of the packet, just in case a malformed packet arrives */ if (!tvb_offset_exists(tvb, offset + pattern_length)) { pattern_length = (guint8)tvb_captured_length_remaining(tvb, offset); expert_add_info(pinfo, trace_request_pattern, &ei_sapenqueue_pattern_invalid_length); } proto_tree_add_item(trace_request_pattern_tree, hf_sapenqueue_server_admin_trace_pattern_value, tvb, offset, pattern_length, FALSE); offset += pattern_length; /* Set the right size for the pattern tree */ pattern_length += 1; /* Add also the length field */ proto_item_set_len(trace_request_pattern, pattern_length); nopatterns -= 1; total_length += pattern_length; } proto_item_set_len(trace_request_patterns, total_length); proto_tree_add_item(trace_request_tree, hf_sapenqueue_server_admin_trace_eyecatcher, tvb, offset, 4, FALSE); offset += 4; break; } default:{ proto_tree_add_item(server_admin_tree, hf_sapenqueue_server_admin_value, tvb, offset, -1, FALSE); break; } } } }
static void dissect_rsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *rsip_tree; guint8 msgtype; gboolean msgcnt_required; int eoff; msgtype = tvb_get_guint8(tvb, 1); msgcnt_required = (pinfo->ipproto == IP_PROTO_UDP)? TRUE : FALSE; col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSIP"); col_clear(pinfo->cinfo, COL_INFO); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(msgtype, msg_type_vals, "Unknown Message Type (0x%0x)")); if (tree) { ti = proto_tree_add_item(tree, proto_rsip, tvb, 0, -1, FALSE); rsip_tree = proto_item_add_subtree(ti, ett_rsip); proto_tree_add_item(rsip_tree, hf_rsip_version, tvb, 0, 1, FALSE); proto_tree_add_item(rsip_tree, hf_rsip_message_type, tvb, 1, 1, FALSE); proto_tree_add_item(rsip_tree, hf_rsip_message_length, tvb, 2, 2, FALSE); eoff = tvb_reported_length(tvb); switch (msgtype) { case 1: /* Error Response */ rsip_message_error_response(tvb, rsip_tree, 4, eoff); break; case 2: /* Register Request */ rsip_message_register_request(tvb, rsip_tree, 4, eoff); break; case 3: /* Register Response */ rsip_message_register_response(tvb, rsip_tree, 4, eoff); break; case 4: /* De-register Request */ rsip_message_deregister_request(tvb, rsip_tree, 4, eoff); break; case 5: /* De-register Response */ rsip_message_deregister_response(tvb, rsip_tree, 4, eoff); break; case 6: /* Assign Request RSA-IP */ rsip_message_assign_request_rsaip(tvb, rsip_tree, 4, eoff); break; case 7: /* Assign Response RSA-IP */ rsip_message_assign_response_rsaip(tvb, rsip_tree, 4, eoff); break; case 8: /* Assign Request RSAP-IP */ rsip_message_assign_request_rsapip(tvb, rsip_tree, 4, eoff); break; case 9: /* Assign Response RSAP-IP */ rsip_message_assign_response_rsapip(tvb, rsip_tree, 4, eoff); break; case 10: /* Extend Request */ rsip_message_extend_request(tvb, rsip_tree, 4, eoff); break; case 11: /* Extend Response */ rsip_message_extend_response(tvb, rsip_tree, 4, eoff); break; case 12: /* Free Request */ rsip_message_free_request(tvb, rsip_tree, 4, eoff); break; case 13: /* Free Response */ rsip_message_free_response(tvb, rsip_tree, 4, eoff); break; case 14: /* Query Request */ rsip_message_query_request(tvb, rsip_tree, 4, eoff); break; case 15: /* Query Response */ rsip_message_query_response(tvb, rsip_tree, 4, eoff); break; case 16: /* Listen Request */ rsip_message_listen_request(tvb, rsip_tree, 4, eoff); break; case 17: /* Listen Response */ rsip_message_listen_response(tvb, rsip_tree, 4, eoff); break; case 22: /* Assign Request RSIPsec */ rsip_message_assign_request_rsipsec(tvb, rsip_tree, 4, eoff); break; case 23: /* Assign Response RSIPsec */ rsip_message_assign_response_rsipsec(tvb, rsip_tree, 4, eoff); break; } } }
/* Code to actually dissect the packets */ static int rsip_parameter(tvbuff_t *tvb, proto_tree *rsip_tree, int off, int eoff) { int consumed, i, paramleft; guint8 addrtype, flowpolicy, method, number, paramtype, tuntype; guint16 error, ind, paramlen, portnum; guint32 bid, cid, leasetm, msgc; proto_tree *p_tree, *v_tree; proto_item *pti, *vti; struct e_in6_addr in6; /* XXX */ if (off >= eoff) return 0; paramtype = tvb_get_guint8(tvb, off); paramlen = tvb_get_ntohs(tvb, off + 1); pti = proto_tree_add_text(rsip_tree, tvb, off, 3 + paramlen, "%s", val_to_str(paramtype, param_type_vals, "Unknown (%d)")); p_tree = proto_item_add_subtree(pti, ett_rsip_param); proto_tree_add_item(p_tree, hf_rsip_parameter_type, tvb, off, 1, FALSE); proto_tree_add_item(p_tree, hf_rsip_parameter_length, tvb, off + 1, 2, FALSE); consumed = 3; if (paramlen == 0) return consumed; vti = proto_tree_add_item(p_tree, hf_rsip_parameter_value, tvb, off + 3, paramlen, FALSE); v_tree = proto_item_add_subtree(vti, ett_rsip_param_val); switch (paramtype) { case 1: /* Address */ proto_tree_add_item(v_tree, hf_rsip_parameter_address_type, tvb, off + 3, 1, FALSE); addrtype = tvb_get_guint8(tvb, off + 3); switch (addrtype) { case 0: /* Reserved */ break; case 1: /* IPv4 */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv4, tvb, off + 4, paramlen - 1, FALSE); proto_item_append_text(pti, ": %s", tvb_ip_to_str(tvb, off + 4)); } else proto_item_append_text(pti, ": Any IPv4 Address"); break; case 2: /* IPv4 netmask */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv4_netmask, tvb, off + 4, paramlen - 1, FALSE); proto_item_append_text(pti, "(netmask): %s", tvb_ip_to_str(tvb, off + 4)); } else proto_item_append_text(pti, ": Any IPv4 Netmask"); break; case 3: /* IPv6 */ if (paramlen - 1 > 0) { tvb_get_ipv6(tvb, off + 4, &in6); proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv6, tvb, off + 4, paramlen - 1, FALSE); proto_item_append_text(pti, ": %s", ip6_to_str(&in6)); } else proto_item_append_text(pti, ": Any IPv6 Address"); break; case 4: /* FQDN */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_fqdn, tvb, off + 4, paramlen - 1, FALSE); proto_item_append_text(pti, ": %s", tvb_format_text(tvb, off + 4, paramlen - 1)); } else proto_item_append_text(pti, ": Any Fully Qualified Domain Name"); break; default: proto_tree_add_text(p_tree, tvb, off + 4, paramlen - 1, ": Unknown Address Type"); break; } break; case 2: /* Ports */ proto_tree_add_item(v_tree, hf_rsip_parameter_ports_number, tvb, off + 3, 1, FALSE); number = tvb_get_guint8(tvb, off + 3); if (paramlen == 1) { switch (number) { case 0: proto_item_append_text(pti, ": Unspecified"); break; case 1: proto_item_append_text(pti, ": Any port"); break; default: proto_item_append_text(pti, ": Any %d ports", number); break; } } else { portnum = tvb_get_ntohs(tvb, off + 4); if (number == 1) { proto_tree_add_item(v_tree, hf_rsip_parameter_ports_port_number, tvb, off + 4, 2, FALSE); } else { paramleft = paramlen - 1; if (paramleft == 2) { proto_tree_add_uint_format_value(v_tree, hf_rsip_parameter_ports_port_number, tvb, off + 4, 2, portnum, "%d - %d", portnum, portnum + number); proto_item_append_text(pti, ": %d - %d", portnum, portnum + number); } else { for (i = off + 4; paramleft > 0; i += 2, paramleft -= 2) proto_tree_add_item(v_tree, hf_rsip_parameter_ports_port_number, tvb, i, 2, FALSE); proto_item_append_text(pti, ": List of %d Ports", number); } } } break; case 3: /* Lease Time */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_lease_time, tvb, off + 3, paramlen, FALSE); leasetm = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d seconds", leasetm); break; case 4: /* Client ID */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_client_id, tvb, off + 3, paramlen, FALSE); cid = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", cid); break; case 5: /* Bind ID */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_bind_id, tvb, off + 3, paramlen, FALSE); bid = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", bid); break; case 6: /* Tunnel Type */ /* XXX if paramlen != 1 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_tunnel_type, tvb, off + 3, paramlen, FALSE); tuntype = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(tuntype, tunnel_type_vals, "Unknown Tunnel Type (%d)")); break; case 7: /* RSIP Method */ /* XXX if paramlen != 1 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_method, tvb, off + 3, paramlen, FALSE); method = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(method, method_vals, "Unknown RSIP Method (%d)")); break; case 8: /* Error */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_error, tvb, off + 3, paramlen, FALSE); error = tvb_get_ntohs(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(error, error_number_vals, "Undefined Error (%d)")); break; case 9: /* Flow Policy */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_flow_policy_local, tvb, off + 3, 1, FALSE); flowpolicy = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(flowpolicy, lcl_flow_policy_vals, "Undefined Local Flow Policy (%d)")); proto_tree_add_item(v_tree, hf_rsip_parameter_flow_policy_remote, tvb, off + 4, 1, FALSE); flowpolicy = tvb_get_guint8(tvb, off + 4); proto_item_append_text(pti, "/%s", val_to_str(flowpolicy, rmt_flow_policy_vals, "Undefined Remote Flow Policy (%d)")); break; case 10: /* Indicator */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_indicator, tvb, off + 3, 2, FALSE); ind = tvb_get_ntohs(tvb, off + 3); proto_item_append_text(pti, ": %d", ind); break; case 11: /* Message Counter */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_message_counter, tvb, off + 3, 4, FALSE); msgc = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", msgc); break; case 12: /* Vendor Specific */ proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_vendor_id, tvb, off + 3, 2, FALSE); proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_subtype, tvb, off + 5, 2, FALSE); proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_value, tvb, off + 9, paramlen - 4, FALSE); break; case 22: /* SPI */ proto_tree_add_item(v_tree, hf_rsip_parameter_spi_number, tvb, off + 3, 2, FALSE); /* XXX need loop? */ proto_tree_add_item(v_tree, hf_rsip_parameter_spi, tvb, off + 5, 4, FALSE); break; default: break; } consumed += paramlen; return consumed; }
dissect_cups(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_tree *cups_tree = NULL; proto_tree *ptype_subtree = NULL; proto_item *ti = NULL; gint offset = 0; gint next_offset; guint len; const guint8 *str; cups_ptype_t ptype; unsigned int state; col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_CUPS); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_cups, tvb, offset, -1, ENC_NA); cups_tree = proto_item_add_subtree(ti, ett_cups); /* Format (1450 bytes max.): */ /* type state uri ["location" ["info" ["make-and-model"]]]\n */ ptype = get_hex_uint(tvb, offset, &next_offset); len = next_offset - offset; if (len != 0) { ti = proto_tree_add_uint(cups_tree, hf_cups_ptype, tvb, offset, len, ptype); ptype_subtree = proto_item_add_subtree(ti, ett_cups_ptype); proto_tree_add_item(ptype_subtree, hf_cups_ptype_default, tvb, offset, len, ENC_BIG_ENDIAN); proto_tree_add_item(ptype_subtree, hf_cups_ptype_implicit, tvb, offset, len, ENC_BIG_ENDIAN); proto_tree_add_item(ptype_subtree, hf_cups_ptype_variable, tvb, offset, len, ENC_BIG_ENDIAN); proto_tree_add_item(ptype_subtree, hf_cups_ptype_large, tvb, offset, len, ENC_BIG_ENDIAN); proto_tree_add_item(ptype_subtree, hf_cups_ptype_medium, tvb, offset, len, ENC_BIG_ENDIAN);
static proto_item * decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) { guint16 udp_port; guint32 ip4_addr; struct e_in6_addr ip6_addr; proto_item *tf = NULL; proto_tree *field_tree = NULL; if (bi->nsip_tree) { tf = proto_tree_add_text(element_tree, bi->tvb, bi->offset, element->total_length, "IP Element"); field_tree = proto_item_add_subtree(tf, ett_nsip_ip_element); /* IP address */ switch (element->version) { case NSIP_IP_VERSION_4: ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset); proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4, bi->tvb, bi->offset, element->address_length, ENC_BIG_ENDIAN); proto_item_append_text(tf, ": IP address: %s", ip_to_str((guint8 *)&ip4_addr)); break; case NSIP_IP_VERSION_6: tvb_get_ipv6(bi->tvb, bi->offset, &ip6_addr); proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb, bi->offset, element->address_length, ENC_NA); proto_item_append_text(tf, ": IP address: %s", ip6_to_str((struct e_in6_addr *)&ip6_addr)); break; default: ; } } bi->offset += element->address_length; if (bi->nsip_tree) { /* UDP port value */ udp_port = tvb_get_ntohs(bi->tvb, bi->offset); proto_tree_add_uint_format(field_tree, hf_nsip_ip_element_udp_port, bi->tvb, bi->offset, 2, udp_port, "UDP Port: %u", udp_port); proto_item_append_text(tf, ", UDP Port: %u", udp_port); } bi->offset += 2; if (bi->nsip_tree) { /* Signalling weight */ proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); } bi->offset++; if (bi->nsip_tree) { /* Data weight */ proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight, bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN); } bi->offset++; return tf; }
static int dissect_mint_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 packet_length, guint received_via) { proto_item *ti; proto_tree *mint_tree = NULL; proto_tree *mint_header_tree = NULL; proto_tree *mint_data_tree = NULL; proto_tree *mint_ctrl_tree = NULL; guint16 bytes_remaining; guint16 packet_type; guint8 type, length, header_length; guint32 message_type; guint8 element_length; static header_field_info *display_hfi_tlv_vals; packet_type = tvb_get_ntohs(tvb, offset + 12); col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, mint_packettype_vals, "Type 0x%02x")); ti = proto_tree_add_item(tree, hfi_mint, tvb, offset, packet_length, ENC_NA); mint_tree = proto_item_add_subtree(ti, ett_mint); ti = proto_tree_add_item(mint_tree, &hfi_mint_header, tvb, offset, 16, ENC_NA); mint_header_tree = proto_item_add_subtree(ti, ett_mint_header); /* MiNT header */ proto_tree_add_item(mint_header_tree, &hfi_mint_header_unknown1, tvb, offset, 4, ENC_NA); offset += 4; proto_tree_add_item(mint_header_tree, &hfi_mint_header_dstid, tvb, offset, 4, ENC_NA); offset += 4; proto_tree_add_item(mint_header_tree, &hfi_mint_header_srcid, tvb, offset, 4, ENC_NA); offset += 4; proto_tree_add_item(mint_header_tree, &hfi_mint_header_dstdatatype, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(mint_header_tree, &hfi_mint_header_srcdatatype, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* FIXME: This is probably not the right way to determine the packet type. * It's more likely something in mint_header_unknown1 but I haven't * found out what. */ switch(packet_type) { case MINT_TYPE_DATA_UC: ti = proto_tree_add_item(mint_tree, &hfi_mint_data, tvb, offset, packet_length - 16, ENC_NA); mint_data_tree = proto_item_add_subtree(ti, ett_mint_data); proto_tree_add_item(mint_data_tree, &hfi_mint_data_unknown1, tvb, offset, 2, ENC_NA); offset += 2; /* Transported user frame */ if (offset < packet_length) offset += dissect_eth_frame(tvb, pinfo, tree, offset, packet_length - offset); break; case MINT_TYPE_DATA_BCMC: ti = proto_tree_add_item(mint_tree, &hfi_mint_data, tvb, offset, packet_length - 16, ENC_NA); mint_data_tree = proto_item_add_subtree(ti, ett_mint_data); /* Decode as vlan only for now. To be verified against a capture * with CoS != 0 */ proto_tree_add_item(mint_data_tree, &hfi_mint_data_vlan, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(mint_data_tree, &hfi_mint_data_seqno, tvb, offset, 4, ENC_NA); offset += 4; proto_tree_add_item(mint_data_tree, &hfi_mint_data_unknown1, tvb, offset, 4, ENC_NA); offset += 4; /* Transported user frame */ if (offset < packet_length) offset += dissect_eth_frame(tvb, pinfo, tree, offset, packet_length - offset); break; case MINT_TYPE_CTRL_0x0c: ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb, offset, packet_length - 16, ENC_NA); mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb, offset, 32, ENC_NA); offset += 32; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown1, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown2, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown3, tvb, offset, 1, ENC_NA); offset += 1; header_length = tvb_get_guint8(tvb, offset); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_length, tvb, offset, 1, ENC_NA); offset += 1; message_type = tvb_get_ntohl(tvb, offset); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_message_type, tvb, offset, 4, ENC_NA); offset += 4; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_sender, tvb, offset, 4, ENC_NA); offset += 4; switch (message_type) { case 0x43534E50: /* CSNP */ element_length = 12; display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_csnp; break; case 0x48454C4F: /* HELO */ element_length = 0; display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_helo; break; case 0x4C535000: /* LSP */ element_length = 8; display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_lsp; break; case 0x50534E50: /* PSNP */ element_length = 4; display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_psnp; break; default: element_length = 0; display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_unknown; } /* FIXME: This should go into the per message_type switch above */ if (header_length > 12) { proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_unknown, tvb, offset, header_length - 12, ENC_NA); offset += header_length - 12; } while (offset < packet_length - 2) { type = tvb_get_guint8(tvb, offset); proto_tree_add_item(mint_ctrl_tree, display_hfi_tlv_vals, tvb, offset, 1, ENC_NA); offset += 1; length = tvb_get_guint8(tvb, offset); /* FIXME: This is a hack - reliable array detection missing */ if (type == 1 && length == 128) { proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_array, tvb, offset, 1, ENC_NA); offset += 1; length = tvb_get_guint8(tvb, offset); } proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_length, tvb, offset, 1, ENC_NA); offset += 1; if (offset + length > packet_length) { /* FIXME: print expert information */ break; } if (type == 1 && element_length) { guint32 end_offset = offset + length; for (; offset < end_offset; offset += element_length) { proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_element, tvb, offset, element_length, ENC_NA); } } else { proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_value, tvb, offset, length, ENC_NA); offset += length; } } break; case MINT_TYPE_CTRL_0x1e: ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb, offset, packet_length - 16, ENC_NA); mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb, offset, 32, ENC_NA); offset += 32; bytes_remaining = packet_length - offset; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x1e_unknown, tvb, offset, bytes_remaining, ENC_NA); offset += bytes_remaining; break; case MINT_TYPE_ETH_0x22: ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb, offset, packet_length - 16, ENC_NA); mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb, offset, 32, ENC_NA); offset += 32; proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_message, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; while (offset < packet_length - 2) { proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_type, tvb, offset, 1, ENC_NA); offset += 1; length = tvb_get_guint8(tvb, offset); proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_length, tvb, offset, 1, ENC_NA); offset += 1; if (offset + length > packet_length) { /* print expert information */ break; } proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_value, tvb, offset, length, ENC_NA); offset += length; } break; default: bytes_remaining = packet_length - offset; switch(received_via) { case PORT_MINT_CONTROL_TUNNEL: case ETHERTYPE_MINT: proto_tree_add_item(mint_tree, &hfi_mint_control_unknown1, tvb, offset, bytes_remaining, ENC_NA); break; case PORT_MINT_DATA_TUNNEL: proto_tree_add_item(mint_tree, &hfi_mint_data_unknown1, tvb, offset, bytes_remaining, ENC_NA); break; default: DISSECTOR_ASSERT_NOT_REACHED(); } offset += bytes_remaining; break; } #if defined MINT_DEVELOPMENT tree_expanded_set(ett_mint, TRUE); tree_expanded_set(ett_mint_ethshim, TRUE); tree_expanded_set(ett_mint_header, TRUE); tree_expanded_set(ett_mint_ctrl, TRUE); tree_expanded_set(ett_mint_data, TRUE); #endif return offset; }
static gint dissect_btmcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { proto_item *main_item; proto_tree *main_tree; proto_item *pitem; gint offset = 0; guint32 op_code; guint32 response_code; guint32 mdl_id; guint32 mdep_id; guint32 bluetooth_clock_sync_time; guint64 timestamp_sync_time; main_item = proto_tree_add_item(tree, proto_btmcap, tvb, offset, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_btmcap); col_set_str(pinfo->cinfo, COL_PROTOCOL, "MCAP"); switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_set_str(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ", pinfo->p2p_dir); break;
static void dissect_sdh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDH"); col_clear(pinfo->cinfo,COL_INFO); if (tree) { proto_tree *sdh_tree; proto_item *sdh_item; int level = get_sdh_level(tvb, pinfo); guint8 h1; guint8 h2; guint16 au; int auoffset; sdh_item = proto_tree_add_protocol_format(tree, proto_sdh, tvb, 0, -1, "SDH"); sdh_tree = proto_item_add_subtree(sdh_item, ett_sdh); h1 = tvb_get_guint8(tvb, 0*level+(3*level*COLUMNS)); h2 = tvb_get_guint8(tvb, 3*level+(3*level*COLUMNS)); au = (h2 | ((0x03 & h1) << 8)); proto_tree_add_item(sdh_tree, hf_sdh_a1, tvb, 0*level, 3*level, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_a2, tvb, 3*level, 3*level, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_j0, tvb, 6*level, 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_b1, tvb, 0*level+(1*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_e1, tvb, 3*level+(1*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_f1, tvb, 6*level+(1*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d1, tvb, 0*level+(2*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d2, tvb, 3*level+(2*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d3, tvb, 6*level+(2*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_h1, tvb, 0*level+(3*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_h2, tvb, 3*level+(3*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_uint(sdh_tree, hf_sdh_au, tvb, 0*level+(3*level*COLUMNS), 3*level+1, au); proto_tree_add_item(sdh_tree, hf_sdh_b2, tvb, 0*level+(4*level*COLUMNS), 3*level, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_k1, tvb, 3*level+(4*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_k2, tvb, 6*level+(4*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d4, tvb, 0*level+(5*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d5, tvb, 3*level+(5*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d6, tvb, 6*level+(5*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d7, tvb, 0*level+(6*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d8, tvb, 3*level+(6*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d9, tvb, 6*level+(6*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d10, tvb, 0*level+(7*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d11, tvb, 3*level+(7*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_d12, tvb, 6*level+(7*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_s1, tvb, 0*level+(8*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_m1, tvb, 3*level+2+(8*level*COLUMNS), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sdh_tree, hf_sdh_e2, tvb, 6*level+(8*level*COLUMNS), 1, ENC_BIG_ENDIAN); /*XXX: POH that au points to may not be in the same frame. Also wrong on pointer justification*/ /*calculate start of SPE by wrapping AU pointer*/ auoffset = (((9 + 3*COLUMNS) /*start after H3*/ + au*3 + 9*(au/87) /*add extra SOH rows to offset*/) * level) % (COLUMNS*9*level); proto_tree_add_item(sdh_tree, hf_sdh_j1, tvb, auoffset, 1, ENC_BIG_ENDIAN); } }
static gboolean ros_try_string(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, struct SESSION_DATA_STRUCTURE* session) { ros_info_t *rinfo; gint32 opcode_lcl = 0; const gchar *opname = NULL; const gchar *suffix = NULL; new_dissector_t opdissector = NULL; const value_string *lookup; proto_item *item=NULL; proto_tree *ros_tree=NULL; if((session != NULL) && ((rinfo = (ros_info_t*)g_hash_table_lookup(protocol_table, oid)) != NULL)) { if(tree){ item = proto_tree_add_item(tree, *(rinfo->proto), tvb, 0, -1, ENC_NA); ros_tree = proto_item_add_subtree(item, *(rinfo->ett_proto)); } col_set_str(pinfo->cinfo, COL_PROTOCOL, rinfo->name); /* if this is a bind operation */ if((session->ros_op & ROS_OP_TYPE_MASK) == ROS_OP_BIND) { /* use the in-built operation codes */ if((session->ros_op & ROS_OP_PDU_MASK) == ROS_OP_ERROR) opcode_lcl = err_ros_bind; else opcode_lcl = op_ros_bind; } else /* otherwise just take the opcode */ opcode_lcl = session->ros_op & ROS_OP_OPCODE_MASK; /* default lookup in the operations */ lookup = rinfo->opr_code_strings; switch(session->ros_op & ROS_OP_PDU_MASK) { case ROS_OP_ARGUMENT: opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, TRUE); suffix = "_argument"; break; case ROS_OP_RESULT: opdissector = ros_lookup_opr_dissector(opcode_lcl, rinfo->opr_code_dissectors, FALSE); suffix = "_result"; break; case ROS_OP_ERROR: opdissector = ros_lookup_err_dissector(opcode_lcl, rinfo->err_code_dissectors); lookup = rinfo->err_code_strings; break; default: break; } if(opdissector) { opname = val_to_str(opcode_lcl, lookup, "Unknown opcode (%d)"); col_set_str(pinfo->cinfo, COL_INFO, opname); if(suffix) col_append_str(pinfo->cinfo, COL_INFO, suffix); (*opdissector)(tvb, pinfo, ros_tree, NULL); return TRUE; } } return FALSE; }
static void dissect_tftp_message(tftp_conv_info_t *tftp_info, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *tftp_tree; proto_item *ti; gint offset = 0; guint16 opcode; guint16 bytes; guint16 blocknum; guint i1; guint16 error; tvbuff_t *data_tvb = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TFTP"); ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA); tftp_tree = proto_item_add_subtree(ti, ett_tftp); opcode = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb, offset, 2, opcode); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)")); offset += 2; /* read and write requests contain file names for other messages, we add the filenames from the conversation */ if (opcode!=TFTP_RRQ && opcode!=TFTP_WRQ) { if (tftp_info->source_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb, 0, 0, tftp_info->source_file); PROTO_ITEM_SET_GENERATED(ti); } if (tftp_info->destination_file) { ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb, 0, 0, tftp_info->destination_file); PROTO_ITEM_SET_GENERATED(ti); } } switch (opcode) { case TFTP_RRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_source_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->source_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII); /* we either have a source file name (for read requests) or a destination file name (for write requests) when we set one of the names, we clear the other */ tftp_info->destination_file = NULL; col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_WRQ: i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_destination_file, tvb, offset, i1, ENC_ASCII|ENC_NA); tftp_info->destination_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII); tftp_info->source_file = NULL; /* see above */ col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_transfer_type, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s", tvb_format_stringzpad(tvb, offset, i1)); offset += i1; tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_INFO: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; case TFTP_DATA: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); /* Sequence analysis on blocknums (first pass only) */ if (!pinfo->fd->flags.visited) { if (blocknum > tftp_info->next_block_num) { /* There is a gap. Don't try to recover from this. */ tftp_info->next_block_num = blocknum + 1; tftp_info->blocks_missing = TRUE; /* TODO: add info to a result table for showing expert info in later passes */ } else if (blocknum == tftp_info->next_block_num) { /* OK, inc what we expect next */ tftp_info->next_block_num++; } } offset += 2; /* Show number of bytes in this block, and whether it is the end of the file */ bytes = tvb_reported_length_remaining(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s", blocknum, (bytes < tftp_info->blocksize)?" (last)":"" ); /* Show data in tree */ if (bytes > 0) { data_tvb = tvb_new_subset(tvb, offset, -1, bytes); call_dissector(data_handle, data_tvb, pinfo, tree); } /* If Export Object tap is listening, need to accumulate blocks info list to send to tap. But if already know there are blocks missing, there is no point in trying. */ if (have_tap_listener(tftp_eo_tap) && !tftp_info->blocks_missing) { file_block_t *block; if (blocknum == 1) { /* Reset data for this conversation, freeing any accumulated blocks! */ cleanup_tftp_blocks(tftp_info); tftp_info->next_tap_block_num = 1; } if (blocknum != tftp_info->next_tap_block_num) { /* Ignore. Could be missing frames, or just clicking previous frame */ return; } if (bytes > 0) { /* Create a block for this block */ block = (file_block_t*)g_malloc(sizeof(file_block_t)); block->length = bytes; block->data = tvb_memdup(NULL, data_tvb, 0, bytes); /* Add to the end of the list (does involve traversing whole list..) */ tftp_info->block_list = g_slist_append(tftp_info->block_list, block); tftp_info->file_length += bytes; /* Look for next blocknum next time */ tftp_info->next_tap_block_num++; } /* Tap export object only when reach end of file */ if (bytes < tftp_info->blocksize) { tftp_eo_t *eo_info; /* If don't have a filename, won't tap file info */ if ((tftp_info->source_file == NULL) && (tftp_info->destination_file == NULL)) { cleanup_tftp_blocks(tftp_info); return; } /* Create the eo_info to pass to the listener */ eo_info = wmem_new(wmem_packet_scope(), tftp_eo_t); /* Set filename */ if (tftp_info->source_file) { eo_info->filename = g_strdup(tftp_info->source_file); } else if (tftp_info->destination_file) { eo_info->filename = g_strdup(tftp_info->destination_file); } /* Send block list, which will be combined and freed at tap. */ eo_info->payload_len = tftp_info->file_length; eo_info->pkt_num = blocknum; eo_info->block_list = tftp_info->block_list; /* Send to tap */ tap_queue_packet(tftp_eo_tap, pinfo, eo_info); /* Have sent, so forget list of blocks, and only pay attention if we get back to the first block again. */ tftp_info->block_list = NULL; tftp_info->next_tap_block_num = 1; } } break; case TFTP_ACK: blocknum = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2, blocknum); col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i", blocknum); break; case TFTP_ERROR: error = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2, error); col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s", val_to_str(error, tftp_error_code_vals, "Unknown (%u)")); offset += 2; i1 = tvb_strsize(tvb, offset); proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset, i1, ENC_ASCII|ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s", tvb_format_stringzpad(tvb, offset, i1)); expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range); break; case TFTP_OACK: tftp_dissect_options(tvb, pinfo, offset, tftp_tree, opcode, tftp_info); break; default: proto_tree_add_item(tftp_tree, hf_tftp_data, tvb, offset, -1, ENC_NA); break; } }
/* Both Source-Active and Source-Active Response have the same format * with one exception. Encapsulated multicast data is not allowed in * SA Response. */ static void dissect_msdp_sa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, int length) { guint8 entries; if (length < 1) return; entries = tvb_get_guint8(tvb, *offset); proto_tree_add_uint(tree, hf_msdp_sa_entry_count, tvb, *offset, 1, entries); *offset += 1; length -= 1; if (length < 4) { *offset += length; return; } proto_tree_add_item(tree, hf_msdp_sa_rp_addr, tvb, *offset, 4, ENC_BIG_ENDIAN); *offset += 4; length -= 4; /* Put each of the (S,G) entries in their own subtree. * This is probably visually better. */ while (entries-- > 0) { proto_item *ei; proto_tree *entry_tree; if (length < 12) { *offset += length; return; } ei = proto_tree_add_text(tree, tvb, *offset, 12, "(S,G) block: %s/%u -> %s", tvb_ip_to_str(tvb, *offset + 8), tvb_get_guint8(tvb, *offset + 3), tvb_ip_to_str(tvb, *offset + 4)); entry_tree = proto_item_add_subtree(ei, ett_msdp_sa_entry); proto_tree_add_item(entry_tree, hf_msdp_sa_reserved, tvb, *offset, 3, ENC_BIG_ENDIAN); *offset += 3; length -= 3; proto_tree_add_item(entry_tree, hf_msdp_sa_sprefix_len, tvb, *offset, 1, ENC_BIG_ENDIAN); *offset += 1; length -= 1; proto_tree_add_item(entry_tree, hf_msdp_sa_group_addr, tvb, *offset, 4, ENC_BIG_ENDIAN); *offset += 4; length -= 4; proto_tree_add_item(entry_tree, hf_msdp_sa_src_addr, tvb, *offset, 4, ENC_BIG_ENDIAN); *offset += 4; length -= 4; } /* * Check if an encapsulated multicast IPv4 packet follows */ if (length > 0) { proto_item *ei; proto_tree *enc_tree; gint available_length, reported_length; tvbuff_t *next_tvb; ei = proto_tree_add_text(tree, tvb, *offset, length, "Encapsulated IPv4 packet: %u bytes", length); enc_tree = proto_item_add_subtree(ei, ett_msdp_sa_enc_data); available_length = tvb_length_remaining(tvb, *offset); reported_length = tvb_reported_length_remaining(tvb, *offset); DISSECTOR_ASSERT(available_length >= 0); DISSECTOR_ASSERT(reported_length >= 0); if (available_length > reported_length) available_length = reported_length; if (available_length > length) available_length = length; if (reported_length > length) reported_length = length; next_tvb = tvb_new_subset(tvb, *offset, available_length, reported_length); /* Set the information columns read-only so that they * reflect the MSDP packet rather than the * encapsulated packet. */ col_set_writable(pinfo->cinfo, FALSE); call_dissector(ip_handle, next_tvb, pinfo, enc_tree); } *offset += length; return; }
static void dissect_itdm_125usec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *itdm_item = NULL; proto_tree *itdm_tree = NULL; int offset; guint32 flowid; guint32 chanid; guint16 chloc1; guint16 chloc2; guint8 chcmd; guint8 actbit; guint8 ackbit; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM"); flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET); chanid = tvb_get_ntoh24(tvb, ITDM_CHANID_OFFSET); chcmd = tvb_get_guint8(tvb, ITDM_CHCMD_OFFSET); chloc1 = tvb_get_ntohs(tvb, ITDM_CHLOC1_OFFSET); actbit = (chcmd & 0x10) ? 1 : 0; ackbit = (chcmd & 0x20) ? 1 : 0; chcmd = chcmd & 0x0f; col_add_fstr(pinfo->cinfo, COL_INFO, "Flow %d Chan %d ACT %d ACK %d %s", flowid, chanid, actbit, ackbit, val_to_str_const(chcmd, chcmd_vals, "Reserved")); if (chcmd == ITDM_CMD_NEW_CHAN || chcmd == ITDM_CMD_CLOSE_CHAN || chcmd == ITDM_CMD_CYCLIC_REAF) { col_append_fstr(pinfo->cinfo, COL_INFO, " Loc1 %d", chloc1); } else if (chcmd == ITDM_CMD_RELOC_CHAN) { chloc2 = tvb_get_ntohs(tvb, ITDM_CHLOC2_OFFSET); col_append_fstr(pinfo->cinfo, COL_INFO, " Loc1 %d Loc2 %d", chloc1, chloc2); } offset = 0; if (tree) { itdm_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA); itdm_tree = proto_item_add_subtree(itdm_item, ett_itdm); proto_tree_add_item(itdm_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(itdm_tree, hf_itdm_ack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_act, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_chcmd, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_tree, hf_itdm_chid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; if (chcmd == ITDM_CMD_PACKET_RATE) { proto_tree_add_item(itdm_tree, hf_itdm_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } else { proto_tree_add_item(itdm_tree, hf_itdm_chloc1, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (chcmd == ITDM_CMD_CYCLIC_REAF || chcmd == ITDM_CMD_NEW_CHAN || chcmd == ITDM_CMD_CLOSE_CHAN) { proto_tree_add_item(itdm_tree, hf_itdm_cxnsize, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } else { proto_tree_add_item(itdm_tree, hf_itdm_chloc2, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } } } next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(data_handle, next_tvb, pinfo, tree); }
static int dissect_mrdisc_mra(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset) { guint16 num; /* Advertising Interval */ proto_tree_add_item(parent_tree, hf_advint, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* checksum */ igmp_checksum(parent_tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0); offset += 2; /* skip unused bytes */ offset += 2; /* number of options */ num = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(parent_tree, hf_numopts, tvb, offset, 2, num); offset += 2; /* process any options */ while (num--) { proto_tree *tree; proto_item *item; guint8 type,len; int old_offset = offset; item = proto_tree_add_item(parent_tree, hf_options, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_options); type = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_option, tvb, offset, 1, type); offset += 1; len = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_option_len, tvb, offset, 1, len); offset += 1; switch (type) { case MRDISC_QI: proto_item_set_text(item,"Option: %s == %d", val_to_str(type, mrdisc_options, "unknown %x"), tvb_get_ntohs(tvb, offset)); proto_tree_add_item(tree, hf_qi, tvb, offset, len, ENC_BIG_ENDIAN); offset += len; break; case MRDISC_RV: proto_item_set_text(item,"Option: %s == %d", val_to_str(type, mrdisc_options, "unknown %x"), tvb_get_ntohs(tvb, offset)); proto_tree_add_item(tree, hf_rv, tvb, offset, len, ENC_BIG_ENDIAN); offset += len; break; default: proto_item_set_text(item,"Option: unknown"); proto_tree_add_item(tree, hf_option_bytes, tvb, offset, len, ENC_NA); offset += len; } proto_item_set_len(item, offset-old_offset); } return offset; }
static void dissect_itdm_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *itdm_ctl_item = NULL; proto_tree *itdm_ctl_tree = NULL; int offset; guint32 flowid; guint8 command; guint32 trans_id; guint32 paired_trans_id; guint32 allocd_flowid; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM-Control"); flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET); command = tvb_get_guint8(tvb, ITDM_CTL_CMD_OFFSET); allocd_flowid = tvb_get_ntoh24(tvb, ITDM_CTL_FLOWID_OFFSET); trans_id = tvb_get_ntohl(tvb, ITDM_CTL_TRANSID_OFFSET); paired_trans_id = tvb_get_ntohl(tvb, ITDM_CTL_PAIRED_TRANSID_OFFSET); col_add_fstr(pinfo->cinfo, COL_INFO, "Flow %d Command %s ", flowid, val_to_str_const(command, itdm_ctl_command_vals, "Reserved")); if (command != ITDM_CTL_CMD_AFI_REQ ) { col_append_fstr(pinfo->cinfo, COL_INFO, " Alloc'd FlowID %d", allocd_flowid); } col_append_fstr(pinfo->cinfo, COL_INFO, " TransID 0x%x ", trans_id); if (command != ITDM_CTL_CMD_AFI_REQ ) { col_append_fstr(pinfo->cinfo, COL_INFO, " Paired TransID 0x%x", paired_trans_id); } offset = 0; if (tree) { itdm_ctl_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA); itdm_ctl_tree = proto_item_add_subtree(itdm_ctl_item, ett_itdm_ctl); /* These eventually should go into a SFP.0 dissector... */ proto_tree_add_item(itdm_ctl_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_ctl_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_ctl_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_ctl_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_transid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_command, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (command != ITDM_CTL_CMD_AFI_REQ) { proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_flowid, tvb, offset, 3, ENC_BIG_ENDIAN); } offset += 3; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_dm, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* rsvd.. */ offset += 1; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_emts, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (command != ITDM_CTL_CMD_AFI_REQ) { proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_ptid, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; /* rsvd.. */ offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_cksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(data_handle, next_tvb, pinfo, tree); }
offset += 126; } return offset; } static gint dissect_rpcap_findalldevs_ifaddr (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, gint offset) { proto_tree *tree; proto_item *ti; gint boffset = offset; ti = proto_tree_add_item (parent_tree, hf_findalldevs_ifaddr, tvb, offset, -1, ENC_NA); tree = proto_item_add_subtree (ti, ett_findalldevs_ifaddr); offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_addr, ti); offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_netmask, NULL); offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_broadaddr, NULL); offset = dissect_rpcap_ifaddr (tvb, pinfo, tree, offset, hf_if_dstaddr, NULL); proto_item_set_len (ti, offset - boffset); return offset; } static gint dissect_rpcap_findalldevs_if (tvbuff_t *tvb, packet_info *pinfo _U_,
/* * Function for AVP dissector. */ static void dissect_avps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *avp_tree) { gint offset; guint16 avp_code; guint16 avp_flags; guint32 avp_length; guint16 avp_type; guint32 vendor_id; guint32 avp_hdr_length; guint32 avp_data_length; guint32 padding; gint32 buffer_length; tvbuff_t *group_tvb; tvbuff_t *eap_tvb; tvbuff_t *encap_tvb; proto_item *single_avp_item; proto_tree *single_avp_tree; proto_item *avp_eap_item; proto_tree *avp_eap_tree; proto_item *avp_encap_item; proto_tree *avp_encap_tree; offset = 0; buffer_length = tvb_reported_length(tvb); /* Go through all AVPs */ while (buffer_length > 0) { avp_code = tvb_get_ntohs(tvb, offset); avp_flags = tvb_get_ntohs(tvb, offset + 2); avp_data_length = tvb_get_ntohs(tvb, offset + 4); /* Check AVP flags for vendor specific AVP */ if (avp_flags & PANA_AVP_FLAG_V) { vendor_id = tvb_get_ntohl(tvb, 8); avp_hdr_length = 12; } else { vendor_id = 0; avp_hdr_length = 8; } avp_length = avp_hdr_length + avp_data_length; /* Check AVP type */ avp_type = pana_avp_get_type(avp_code, vendor_id); /* Check padding */ padding = (4 - (avp_length % 4)) % 4; single_avp_item = proto_tree_add_text(avp_tree, tvb, offset, avp_length + padding, "%s (%s) length: %d bytes (%d padded bytes)", val_to_str(avp_code, avp_code_names, "Unknown (%d)"), val_to_str(avp_type, avp_type_names, "Unknown (%d)"), avp_length, avp_length + padding); single_avp_tree = proto_item_add_subtree(single_avp_item, ett_pana_avp_info); /* AVP Code */ proto_tree_add_uint_format_value(single_avp_tree, hf_pana_avp_code, tvb, offset, 2, avp_code, "%s (%u)", val_to_str(avp_code, avp_code_names, "Unknown (%d)"), avp_code); offset += 2; /* AVP Flags */ dissect_pana_avp_flags(single_avp_tree, tvb, offset, avp_flags); offset += 2; /* AVP Length */ proto_tree_add_item(single_avp_tree, hf_pana_avp_data_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Reserved */ proto_tree_add_item(single_avp_tree, hf_pana_avp_reserved, tvb, offset, 2, ENC_NA); offset += 2; if (avp_flags & PANA_AVP_FLAG_V) { /* Vendor ID */ proto_tree_add_item(single_avp_tree, hf_pana_avp_vendorid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } if (! (avp_flags & PANA_AVP_FLAG_V)) { /* AVP Value */ switch(avp_type) { case PANA_GROUPED: { proto_item *avp_group_item; proto_tree *avp_group_tree; avp_group_item = proto_tree_add_text(single_avp_tree, tvb, offset, avp_data_length, "Grouped AVP"); avp_group_tree = proto_item_add_subtree(avp_group_item, ett_pana_avp); group_tvb = tvb_new_subset(tvb, offset, MIN(avp_data_length, tvb_reported_length(tvb)-offset), avp_data_length); dissect_avps(group_tvb, pinfo, avp_group_tree); break; } case PANA_UTF8STRING: { const guint8 *data; data = tvb_get_ptr(tvb, offset, avp_data_length); proto_tree_add_string_format(single_avp_tree, hf_pana_avp_data_string, tvb, offset, avp_data_length, data, "UTF8String: %*.*s", avp_data_length, avp_data_length, data); break; } case PANA_OCTET_STRING: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_bytes, tvb, offset, avp_data_length, ENC_NA); break; } case PANA_INTEGER32: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_int32, tvb, offset, 4, ENC_BIG_ENDIAN); break; } case PANA_UNSIGNED32: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_uint32, tvb, offset, 4, ENC_BIG_ENDIAN); break; } case PANA_INTEGER64: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_int64, tvb, offset, 8, ENC_BIG_ENDIAN); break; } case PANA_UNSIGNED64: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_uint64, tvb, offset, 8, ENC_BIG_ENDIAN); break; } case PANA_ENUMERATED: { proto_tree_add_item(single_avp_tree, hf_pana_avp_data_enumerated, tvb, offset, 4, ENC_BIG_ENDIAN); break; } case PANA_RESULT_CODE: { proto_tree_add_text(single_avp_tree, tvb, offset, avp_data_length, "Value: %d (%s)", tvb_get_ntohl(tvb, offset), val_to_str(tvb_get_ntohs(tvb, offset), avp_code_names, "Unknown (%d)")); break; } case PANA_EAP: { avp_eap_item = proto_tree_add_text(single_avp_tree, tvb, offset, avp_data_length, "AVP Value (EAP packet)"); avp_eap_tree = proto_item_add_subtree(avp_eap_item, ett_pana_avp); eap_tvb = tvb_new_subset_length(tvb, offset, avp_data_length); if (eap_handle != NULL) { call_dissector(eap_handle, eap_tvb, pinfo, avp_eap_tree); } break; } case PANA_ENCAPSULATED: { avp_encap_item = proto_tree_add_text(single_avp_tree, tvb, offset, avp_data_length, "AVP Value (PANA packet)"); avp_encap_tree = proto_item_add_subtree(avp_encap_item, ett_pana_avp); encap_tvb = tvb_new_subset_length(tvb, offset, avp_data_length); dissect_pana_pdu(encap_tvb, pinfo, avp_encap_tree); break; } } } offset += avp_data_length + padding; /* Update the buffer length */ buffer_length -= avp_length + padding; } }
static tvbuff_t * dissect_board_id_and_strip_it_from_tvb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree_add_item(tree, hf_nordic_ble_board_id, tvb, BOARD_ID_INDEX, BOARD_ID_LENGTH, ENC_BIG_ENDIAN); return tvb_new_subset(tvb, BOARD_ID_LENGTH, -1, -1); }
/* * Function for the PANA PDU dissector. */ static void dissect_pana_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *pana_tree = NULL; guint16 flags; guint16 msg_type; guint32 msg_length; guint32 avp_length; guint32 seq_num; conversation_t *conversation; pana_conv_info_t *pana_info; pana_transaction_t *pana_trans; int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PANA"); col_clear(pinfo->cinfo, COL_INFO); /* Get message length, type and flags */ msg_length = tvb_get_ntohs(tvb, 2); flags = tvb_get_ntohs(tvb, 4); msg_type = tvb_get_ntohs(tvb, 6); seq_num = tvb_get_ntohl(tvb, 12); avp_length = msg_length - 16; col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s-%s", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)")); /* Make the protocol tree */ if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, proto_pana, tvb, 0, -1, ENC_NA); pana_tree = proto_item_add_subtree(ti, ett_pana); } /* * We need to track some state for this protocol on a per conversation * basis so we can do neat things like request/response tracking */ conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ pana_info = (pana_conv_info_t *)conversation_get_proto_data(conversation, proto_pana); if (!pana_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ pana_info = wmem_new(wmem_file_scope(), pana_conv_info_t); pana_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_pana, pana_info); } if(!pinfo->fd->flags.visited){ if(flags&PANA_FLAG_R){ /* This is a request */ pana_trans=wmem_new(wmem_file_scope(), pana_transaction_t); pana_trans->req_frame=pinfo->fd->num; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->fd->abs_ts; wmem_map_insert(pana_info->pdus, GUINT_TO_POINTER(seq_num), (void *)pana_trans); } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); if(pana_trans){ pana_trans->rep_frame=pinfo->fd->num; } } } else { pana_trans=(pana_transaction_t *)wmem_map_lookup(pana_info->pdus, GUINT_TO_POINTER(seq_num)); } if(!pana_trans){ /* create a "fake" pana_trans structure */ pana_trans=wmem_new(wmem_packet_scope(), pana_transaction_t); pana_trans->req_frame=0; pana_trans->rep_frame=0; pana_trans->req_time=pinfo->fd->abs_ts; } /* print state tracking in the tree */ if(flags&PANA_FLAG_R){ /* This is a request */ if(pana_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(pana_tree, hf_pana_response_in, tvb, 0, 0, pana_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else { /* This is a reply */ if(pana_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(pana_tree, hf_pana_response_to, tvb, 0, 0, pana_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &pana_trans->req_time); it=proto_tree_add_time(pana_tree, hf_pana_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } /* Reserved field */ proto_tree_add_item(pana_tree, hf_pana_reserved_type, tvb, offset, 2, ENC_NA); offset += 2; /* Length */ proto_tree_add_item(pana_tree, hf_pana_length_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Flags */ dissect_pana_flags(pana_tree, tvb, offset, flags); offset += 2; /* Message Type */ proto_tree_add_uint_format_value(pana_tree, hf_pana_msg_type, tvb, offset, 2, msg_type, "%s-%s (%d)", val_to_str(msg_type, msg_type_names, "Unknown (%d)"), val_to_str(flags & PANA_FLAG_R, msg_subtype_names, "Unknown (%d)"), msg_type); offset += 2; /* Session ID */ proto_tree_add_item(pana_tree, hf_pana_session_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* Sequence Number */ proto_tree_add_item(pana_tree, hf_pana_seqnumber, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* AVPs */ if(avp_length != 0){ tvbuff_t *avp_tvb; proto_tree *avp_tree; proto_item *avp_item; avp_tvb = tvb_new_subset_length(tvb, offset, avp_length); avp_item = proto_tree_add_text(pana_tree, tvb, offset, avp_length, "Attribute Value Pairs"); avp_tree = proto_item_add_subtree(avp_item, ett_pana_avp); if (avp_tree != NULL) { dissect_avps(avp_tvb, pinfo, avp_tree); } } }
static void dissect_packet_counter(tvbuff_t *tvb, proto_tree *tree) { proto_tree_add_item(tree, hf_nordic_ble_packet_counter, tvb, get_pc_index(), 2, ENC_LITTLE_ENDIAN); }
static int dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) { proto_tree *ext_tree, *flags_tree; proto_item *tf; guint16 extlen; int endoffset; guint8 flags; guint32 vallen, vallen_round, siglen; extlen = tvb_get_ntohs(tvb, offset+2); if (extlen < 8) { /* Extension length isn't enough for the extension header. * Report the error, and return an offset that goes to * the end of the tvbuff, so we stop dissecting. */ proto_tree_add_text(ntp_tree, tvb, offset+2, 2, "Extension length %u < 8", extlen); offset += tvb_length_remaining(tvb, offset); return offset; } if (extlen % 4) { /* Extension length isn't a multiple of 4. * Report the error, and return an offset that goes * to the end of the tvbuff, so we stop dissecting. */ proto_tree_add_text(ntp_tree, tvb, offset+2, 2, "Extension length %u isn't a multiple of 4", extlen); offset += tvb_length_remaining(tvb, offset); return offset; } endoffset = offset + extlen; tf = proto_tree_add_item(ntp_tree, hf_ntp_ext, tvb, offset, extlen, ENC_NA); ext_tree = proto_item_add_subtree(tf, ett_ntp_ext); flags = tvb_get_guint8(tvb, offset); tf = proto_tree_add_uint(ext_tree, hf_ntp_ext_flags, tvb, offset, 1, flags); flags_tree = proto_item_add_subtree(tf, ett_ntp_ext_flags); proto_tree_add_uint(flags_tree, hf_ntp_ext_flags_r, tvb, offset, 1, flags); proto_tree_add_uint(flags_tree, hf_ntp_ext_flags_error, tvb, offset, 1, flags); proto_tree_add_uint(flags_tree, hf_ntp_ext_flags_vn, tvb, offset, 1, flags); offset++; proto_tree_add_item(ext_tree, hf_ntp_ext_op, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_uint(ext_tree, hf_ntp_ext_len, tvb, offset, 2, extlen); offset += 2; if ((flags & NTP_EXT_VN_MASK) != 2) { /* don't care about autokey v1 */ return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_associd, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* check whether everything up to "vallen" is present */ if (extlen < MAX_MAC_LEN) { /* XXX - report as error? */ return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_tstamp, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ext_tree, hf_ntp_ext_fstamp, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* XXX fstamp can be server flags */ vallen = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(ext_tree, hf_ntp_ext_vallen, tvb, offset, 4, vallen); offset += 4; vallen_round = (vallen + 3) & (-4); if (vallen != 0) { if ((guint32)(endoffset - offset) < vallen_round) { /* * Value goes past the length of the extension * field. */ proto_tree_add_text(ext_tree, tvb, offset, endoffset - offset, "Value length makes value go past the end of the extension field"); return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_val, tvb, offset, vallen, ENC_NA); } offset += vallen_round; siglen = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(ext_tree, hf_ntp_ext_siglen, tvb, offset, 4, siglen); offset += 4; if (siglen != 0) { if (offset + (int)siglen > endoffset) { /* * Value goes past the length of the extension * field. */ proto_tree_add_text(ext_tree, tvb, offset, endoffset - offset, "Signature length makes value go past the end of the extension field"); return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_sig, tvb, offset, siglen, ENC_NA); } return endoffset; }