/* * read a number and add it to tree */ static void read_number(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree, int asWhat, guint8 type_code) { int byteLength; read_type(offset, tvb, etch_tree); byteLength = get_byte_length(type_code); if (byteLength > 0) { proto_item *ti; const gchar *symbol = NULL; guint32 hash = 0; gbl_symbol_buffer = wmem_strbuf_new_label(wmem_packet_scope()); /* no symbol found yet */ if (byteLength == 4) { hash = tvb_get_ntohl(tvb, *offset); symbol = try_val_to_str_ext(hash, gbl_symbols_vs_ext); if(symbol != NULL) { asWhat = hf_etch_symbol; gbl_have_symbol = TRUE; wmem_strbuf_append_printf(gbl_symbol_buffer,"%s",symbol); } } ti = proto_tree_add_item(etch_tree, asWhat, tvb, *offset, byteLength, ENC_BIG_ENDIAN); *offset += byteLength; if (symbol != NULL) { proto_item_append_text(ti, " (0x%08x) %s", hash, symbol); } } }
/* * Preparse the message for the info column */ static wmem_strbuf_t* get_column_info(tvbuff_t *tvb) { int byte_length; guint8 type_code; wmem_strbuf_t *result_buf; int my_offset = 0; /* We've a full PDU: 8 bytes + pdu_packetlen bytes */ result_buf = wmem_strbuf_new_label(wmem_packet_scope()); my_offset += (4 + 4 + 1); /* skip Magic, Length, Version */ type_code = tvb_get_guint8(tvb, my_offset); byte_length = get_byte_length(type_code); my_offset++; if (byte_length == 4) { const gchar *symbol; guint32 hash; hash = tvb_get_ntohl(tvb, my_offset); symbol = try_val_to_str_ext(hash, gbl_symbols_vs_ext); if (symbol != NULL) { wmem_strbuf_append_printf(result_buf, "%s()", symbol); } } return result_buf; }
static void dissect_UDPR1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string) { const gchar *status_string; guint32 seq_num, status; status = tvb_get_letohl(tvb, 0); status_string = try_val_to_str_ext(status, &error_code_mapping_ext); if (status_string) { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR1 Status: %s", status_string); } else { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR1 Undefined error code %d", status); } /* Get the transaction identifier */ seq_num = tvb_get_letohl(tvb, 4); adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); if (! adwin_tree) return; SET_PACKET_TYPE(adwin_tree, APT_UDPR1); ADWIN_ADD_LE(adwin_tree, status, 0, 4); ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4); ADWIN_ADD_LE(adwin_tree, val1, 8, 4); ADWIN_ADD_LE(adwin_tree, val1f, 8, 4); ADWIN_ADD_LE(adwin_tree, val2, 12, 4); ADWIN_ADD_LE(adwin_tree, val3, 16, 4); ADWIN_ADD_LE(adwin_tree, val4, 20, 4); ADWIN_ADD_LE(adwin_debug_tree, unused, 24, 8); }
const char *ipprotostr(const int proto) { const char *s; if ((s = try_val_to_str_ext(proto, &ipproto_val_ext)) != NULL) return s; s = "Unknown"; #ifdef HAVE_GETPROTOBYNUMBER /* * XXX - have another flag for resolving network-layer * protocol names? */ if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name || gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns) { static char buf[128]; struct protoent *pe; pe = getprotobynumber(proto); if (pe) { g_strlcpy(buf, pe->p_name, sizeof(buf)); s = buf; } } #endif return s; }
/* * Here we get a special value_string, that return another value_string * pointer instead of string value. This let us use the try_val_to_str * to get val_to_str value from the value of a parameter on a more * easier way than using switch cases */ static const guint8 *dissect_mqpcf_parm_getintval(guint uPrm, guint uVal) { const value_string *pVs; pVs = (const value_string *)try_val_to_str_ext(uPrm, GET_VALS_EXTP(MQCFINT_Parse)); if (pVs) { return (const guint8 *)try_val_to_str(uVal, pVs); } return NULL; }
gchar * val_to_str_ext_wmem(wmem_allocator_t *scope, const guint32 val, value_string_ext *vse, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_val_to_str_ext(val, vse); if (ret != NULL) return wmem_strdup(scope, ret); return wmem_strdup_printf(scope, fmt, val); }
/* Like val_to_str for extended value strings */ const gchar * val_to_str_ext(const guint32 val, value_string_ext *vse, const char *fmt) { const gchar *ret; DISSECTOR_ASSERT(fmt != NULL); ret = try_val_to_str_ext(val, vse); if (ret != NULL) return ret; return wmem_strdup_printf(wmem_packet_scope(), fmt, val); }
/* Like val_to_str_const for extended value strings */ const gchar * val_to_str_ext_const(const guint32 val, value_string_ext *vse, const char *unknown_str) { const gchar *ret; DISSECTOR_ASSERT(unknown_str != NULL); ret = try_val_to_str_ext(val, vse); if (ret != NULL) return ret; return unknown_str; }
static void dissect_UDPR2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string) { const gchar *status_string; guint32 i, status, seq_num; status = tvb_get_letohl(tvb, 0); status_string = try_val_to_str_ext(status, &error_code_mapping_ext); if (status_string) { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR2 Status: %s", status_string); } else { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR2 Undefined error code %d", status); } /* Get the transaction identifier */ seq_num = tvb_get_letohl(tvb, 4); adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); if (! adwin_tree) return; SET_PACKET_TYPE(adwin_tree, APT_UDPR2); ADWIN_ADD_LE(adwin_tree, status, 0, 4); ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4); if (! global_adwin_dissect_data) { proto_tree_add_text(adwin_debug_tree, tvb, 8, 250 * 4, "Data"); return; } for (i = 0; i < 250; i++) { proto_item *item; guint32 offset = 8 + i * (int)sizeof(guint32); gint32 value = tvb_get_letohl(tvb, offset); void * fvalue = &value; proto_tree_add_text(adwin_debug_tree, tvb, offset, 4, "Data[%3d]: %10d - %10f - 0x%08x", i, value, *(float*)fvalue, value); item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4); PROTO_ITEM_SET_HIDDEN(item); item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4); PROTO_ITEM_SET_HIDDEN(item); item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4); PROTO_ITEM_SET_HIDDEN(item); } }
static void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint message_type; proto_item *message_item; proto_tree *message_tree; const char* mgt_msg_str; message_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_decoder, tvb, offset, -1, "MAC Management Message Type (%u bytes)", tvb_reported_length(tvb)); message_tree = proto_item_add_subtree(message_item, ett_mac_mgmt_msg_decoder); if (tvb_reported_length(tvb) == 0) { expert_add_info(pinfo, message_item, &ei_empty_payload); return; } /* Get the payload type */ message_type = tvb_get_guint8(tvb, offset); proto_tree_add_item(message_tree, hf_mac_mgmt_msg_type, tvb, offset, 1, ENC_NA); mgt_msg_str = val_to_str_ext_const(message_type, &mgt_msg_abbrv_vals_ext, "Unknown"); /* Display message type in Info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", mgt_msg_str); /* add the payload type into the info column */ if (try_val_to_str_ext(message_type, &mgt_msg_abbrv_vals_ext) == NULL) { /* display the MAC payload in Hex */ proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); return; } /* add the MAC header info to parent*/ proto_item_append_text(proto_tree_get_parent(tree), ", %s", mgt_msg_str); /* Decode and display the MAC payload */ if (!dissector_try_uint(subdissector_message_table, message_type, tvb_new_subset_remaining(tvb, 1), pinfo, tree)) { proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); } }
void RtpAudioStream::decode() { if (rtp_packets_.size() < 1) return; // gtk/rtp_player.c:decode_rtp_stream // XXX This is more messy than it should be. gsize resample_buff_len = 0x1000; SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len); spx_uint32_t cur_in_rate = 0, visual_out_rate = 0; char *write_buff = NULL; qint64 write_bytes = 0; unsigned channels = 0; unsigned sample_rate = 0; int last_sequence = 0; double rtp_time_prev = 0.0; double arrive_time_prev = 0.0; double pack_period = 0.0; double start_time = 0.0; double start_rtp_time = 0.0; guint32 start_timestamp = 0; size_t decoded_bytes_prev = 0; for (int cur_packet = 0; cur_packet < rtp_packets_.size(); cur_packet++) { SAMPLE *decode_buff = NULL; // XXX The GTK+ UI updates a progress bar here. rtp_packet_t *rtp_packet = rtp_packets_[cur_packet]; stop_rel_time_ = start_rel_time_ + rtp_packet->arrive_offset; ws_codec_resampler_get_rate(visual_resampler_, &cur_in_rate, &visual_out_rate); QString payload_name; if (rtp_packet->info->info_payload_type_str) { payload_name = rtp_packet->info->info_payload_type_str; } else { payload_name = try_val_to_str_ext(rtp_packet->info->info_payload_type, &rtp_payload_type_short_vals_ext); } if (!payload_name.isEmpty()) { payload_names_ << payload_name; } if (cur_packet < 1) { // First packet start_timestamp = rtp_packet->info->info_timestamp; start_rtp_time = 0; rtp_time_prev = 0; last_sequence = rtp_packet->info->info_seq_num - 1; } size_t decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate); if (decoded_bytes == 0 || sample_rate == 0) { // We didn't decode anything. Clean up and prep for the next packet. last_sequence = rtp_packet->info->info_seq_num; continue; } if (audio_out_rate_ == 0) { // First non-zero wins audio_out_rate_ = sample_rate; RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_); // Prepend silence to match our sibling streams. tempfile_->seek(0); int prepend_samples = (start_rel_time_ - global_start_rel_time_) * audio_out_rate_; if (prepend_samples > 0) { writeSilence(prepend_samples); } } if (rtp_packet->info->info_seq_num != last_sequence+1) { out_of_seq_timestamps_.append(stop_rel_time_); } last_sequence = rtp_packet->info->info_seq_num; double rtp_time = (double)(rtp_packet->info->info_timestamp-start_timestamp)/sample_rate - start_rtp_time; double arrive_time; if (timing_mode_ == Uninterrupted) { arrive_time = rtp_time; } else { arrive_time = (double)rtp_packet->arrive_offset/1000 - start_time; } double diff = qAbs(arrive_time - rtp_time); if (diff*1000 > jitter_buffer_size_ && timing_mode_ == Uninterrupted) { // rtp_player.c:628 jitter_drop_timestamps_.append(stop_rel_time_); RTP_STREAM_DEBUG("Packet drop by jitter buffer exceeded %f > %d", diff*1000, jitter_buffer_size_); /* if there was a silence period (more than two packetization period) resync the source */ if ( (rtp_time - rtp_time_prev) > pack_period*2 ) { int silence_samples; RTP_STREAM_DEBUG("Resync..."); silence_samples = (int)((arrive_time - arrive_time_prev)*sample_rate - decoded_bytes_prev / sample_bytes_); /* Fix for bug 4119/5902: don't insert too many silence frames. * XXX - is there a better thing to do here? */ silence_samples = qMin(silence_samples, max_silence_samples_); writeSilence(silence_samples); silence_timestamps_.append(stop_rel_time_); decoded_bytes_prev = 0; /* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */ /* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */ start_timestamp = rtp_packet->info->info_timestamp; start_rtp_time = 0; start_time = (double)rtp_packet->arrive_offset/1000; rtp_time_prev = 0; } } else { // rtp_player.c:664 /* Add silence if it is necessary */ int silence_samples; if (timing_mode_ == Uninterrupted) { silence_samples = 0; } else { silence_samples = (int)((rtp_time - rtp_time_prev)*sample_rate - decoded_bytes_prev / sample_bytes_); } if (silence_samples != 0) { wrong_timestamp_timestamps_.append(stop_rel_time_); } if (silence_samples > 0) { /* Fix for bug 4119/5902: don't insert too many silence frames. * XXX - is there a better thing to do here? */ silence_samples = qMin(silence_samples, max_silence_samples_); writeSilence(silence_samples); silence_timestamps_.append(stop_rel_time_); } // XXX rtp_player.c:696 adds audio here. rtp_time_prev = rtp_time; pack_period = (double) decoded_bytes / sample_bytes_ / sample_rate; decoded_bytes_prev = decoded_bytes; arrive_time_prev = arrive_time; } // Write samples to our file. write_buff = (char *) decode_buff; write_bytes = rtp_packet->info->info_payload_len * sample_bytes_; if (audio_out_rate_ != sample_rate) { // Resample the audio to match our previous output rate. if (!audio_resampler_) { audio_resampler_ = ws_codec_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL); ws_codec_resampler_skip_zeros(audio_resampler_); RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_); } else { spx_uint32_t audio_out_rate; ws_codec_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate); // Adjust rates if needed. if (sample_rate != cur_in_rate) { ws_codec_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate); ws_codec_resampler_set_rate(visual_resampler_, sample_rate, visual_out_rate); RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_); } } spx_uint32_t in_len = (spx_uint32_t)rtp_packet->info->info_payload_len; spx_uint32_t out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0); if (out_len * sample_bytes_ > resample_buff_len) { while ((out_len * sample_bytes_ > resample_buff_len)) resample_buff_len *= 2; resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len); } ws_codec_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len); write_buff = (char *) decode_buff; write_bytes = out_len * sample_bytes_; } // Write the decoded, possibly-resampled audio to our temp file. tempfile_->write(write_buff, write_bytes); // Collect our visual samples. spx_uint32_t in_len = (spx_uint32_t)rtp_packet->info->info_payload_len; spx_uint32_t out_len = (visual_out_rate * in_len / sample_rate) + (visual_out_rate % sample_rate != 0); if (out_len * sample_bytes_ > resample_buff_len) { while ((out_len * sample_bytes_ > resample_buff_len)) resample_buff_len *= 2; resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len); } ws_codec_resampler_process_int(visual_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len); for (unsigned i = 0; i < out_len; i++) { packet_timestamps_[stop_rel_time_ + (double) i / visual_out_rate] = rtp_packet->frame_num; if (qAbs(resample_buff[i]) > max_sample_val_) max_sample_val_ = qAbs(resample_buff[i]); visual_samples_.append(resample_buff[i]); } // Finally, write the resampled audio to our temp file and clean up. g_free(decode_buff); } g_free(resample_buff); }
void RtpAudioStream::addRtpPacket(const struct _packet_info *pinfo, const _rtp_info *rtp_info) { if (!rtp_info) return; // Combination of gtk/rtp_player.c:decode_rtp_stream + decode_rtp_packet // XXX This is more messy than it should be. SAMPLE *decode_buff = NULL; SAMPLE *resample_buff = NULL; spx_uint32_t cur_in_rate, visual_out_rate; char *write_buff; qint64 write_bytes; unsigned channels; unsigned sample_rate; rtp_packet_t rtp_packet; stop_rel_time_ = nstime_to_sec(&pinfo->rel_ts); ws_codec_resampler_get_rate(visual_resampler_, &cur_in_rate, &visual_out_rate); QString payload_name; if (rtp_info->info_payload_type_str) { payload_name = rtp_info->info_payload_type_str; } else { payload_name = try_val_to_str_ext(rtp_info->info_payload_type, &rtp_payload_type_short_vals_ext); } if (!payload_name.isEmpty()) { payload_names_ << payload_name; } // First, decode the payload. rtp_packet.info = (_rtp_info *) g_memdup(rtp_info, sizeof(struct _rtp_info)); rtp_packet.arrive_offset = start_rel_time_; if (rtp_info->info_all_data_present && (rtp_info->info_payload_len != 0)) { rtp_packet.payload_data = (guint8 *)g_malloc(rtp_info->info_payload_len); memcpy(rtp_packet.payload_data, rtp_info->info_data + rtp_info->info_payload_offset, rtp_info->info_payload_len); } else { rtp_packet.payload_data = NULL; } //size_t decoded_bytes = decode_rtp_packet(&rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate); write_buff = (char *) decode_buff; write_bytes = rtp_info->info_payload_len * sample_bytes_; if (tempfile_->pos() == 0) { // First packet. Let it determine our sample rate. audio_out_rate_ = sample_rate; last_sequence_ = rtp_info->info_seq_num - 1; // Prepend silence to match our sibling streams. int prepend_samples = (start_rel_time_ - global_start_rel_time_) * audio_out_rate_; if (prepend_samples > 0) { int prepend_bytes = prepend_samples * sample_bytes_; char *prepend_buff = (char *) g_malloc(prepend_bytes); SAMPLE silence = 0; memccpy(prepend_buff, &silence, prepend_samples, sample_bytes_); tempfile_->write(prepend_buff, prepend_bytes); } } else if (audio_out_rate_ != sample_rate) { // Resample the audio to match our previous output rate. if (!audio_resampler_) { audio_resampler_ = ws_codec_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL); ws_codec_resampler_skip_zeros(audio_resampler_); // RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_); } else { spx_uint32_t audio_out_rate; ws_codec_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate); // Adjust rates if needed. if (sample_rate != cur_in_rate) { ws_codec_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate); ws_codec_resampler_set_rate(visual_resampler_, sample_rate, visual_out_rate); // RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_); } } spx_uint32_t in_len = (spx_uint32_t)rtp_info->info_payload_len; spx_uint32_t out_len = (audio_out_rate_ * (spx_uint32_t)rtp_info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0); resample_buff = (SAMPLE *) g_malloc(out_len * sample_bytes_); ws_codec_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len); write_buff = (char *) decode_buff; write_bytes = out_len * sample_bytes_; } if (rtp_info->info_seq_num != last_sequence_+1) { out_of_seq_timestamps_.append(stop_rel_time_); // XXX Add silence to tempfile_ and visual_samples_ } last_sequence_ = rtp_info->info_seq_num; // Write the decoded, possibly-resampled audio to our temp file. tempfile_->write(write_buff, write_bytes); // Collect our visual samples. spx_uint32_t in_len = (spx_uint32_t)rtp_info->info_payload_len; spx_uint32_t out_len = (visual_out_rate * in_len / sample_rate) + (visual_out_rate % sample_rate != 0); resample_buff = (SAMPLE *) g_realloc(resample_buff, out_len * sizeof(SAMPLE)); ws_codec_resampler_process_int(visual_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len); for (unsigned i = 0; i < out_len; i++) { packet_timestamps_[stop_rel_time_ + (double) i / visual_out_rate] = pinfo->fd->num; if (qAbs(resample_buff[i]) > max_sample_val_) max_sample_val_ = qAbs(resample_buff[i]); visual_samples_.append(resample_buff[i]); } // Finally, write the resampled audio to our temp file and clean up. g_free(rtp_packet.payload_data); g_free(decode_buff); g_free(resample_buff); }
static void dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count) { char pdu_msg_type; nstime_t timeValue; int client_size = 0; guint value = 0; int size = 0; guint public_key = 0; char valStr[1024]; const char *valBulk = NULL; const char *valMac = NULL; proto_item *ti; proto_item *cli_key_item; proto_tree *wtls_msg_type_tree; proto_tree *wtls_msg_type_item_tree; proto_tree *wtls_msg_type_item_sub_tree; proto_tree *wtls_msg_type_item_sub_sub_tree; pdu_msg_type = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_uint(tree, hf_wtls_hands, tvb, offset,count, pdu_msg_type); wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type, tvb,offset,1,ENC_BIG_ENDIAN); offset+=1; count = tvb_get_ntohs (tvb, offset); proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; switch(pdu_msg_type) { case WTLS_HANDSHAKE_CLIENT_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset, count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version, tvb,offset,1,ENC_BIG_ENDIAN); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random, tvb,offset,12,ENC_NA); offset+=12; offset = add_session_id (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, hf_wtls_hands_cli_hello_session_str, tvb, offset); /* process client_key_ids structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cli_key_id, tvb, offset, count+2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of client_key_ids structure */ proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; /* cycle through client_key_ids entries */ for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch(value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,ENC_NA); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process trusted_keys structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_trust_key_id, tvb, offset, count+2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of trusted_keys structure */ proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch (value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,ENC_NA); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); /* need to fetch identifier and display it */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process cipher_suites structure */ count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cipher_suite, tvb, offset, count+1, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { value = tvb_get_guint8 (tvb, offset); valBulk = try_val_to_str_ext(value, &wtls_vals_cipher_bulk_ext); offset++; client_size=1; valMac = try_val_to_str_ext(tvb_get_guint8 (tvb, offset), &wtls_vals_cipher_mac_ext); if (valBulk != NULL) { if (valMac != NULL) { g_snprintf(valStr,1024,"%s, %s",valBulk,valMac); } else { g_snprintf(valStr,1024,"%s, Unknown MAC (0x%02x)",valBulk,tvb_get_guint8 (tvb, offset)); } } else { if (valMac != NULL) { g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), %s",value,valMac); } else { g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), Unknown MAC (0x%02x)",value, tvb_get_guint8 (tvb, offset)); } } offset++; client_size++; proto_tree_add_string(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset-2,2, valStr); } count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_compression_methods, tvb, offset, count+1, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { client_size=0; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_compression, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; } proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_sequence_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_key_refresh, tvb, offset, 1, ENC_LITTLE_ENDIAN); break; case WTLS_HANDSHAKE_SERVER_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset, count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version, tvb,offset,1,ENC_BIG_ENDIAN); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random, tvb,offset,12,ENC_NA); offset+=12; offset = add_session_id (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, hf_wtls_hands_serv_hello_session_str, tvb, offset); proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cli_key_id, tvb,offset,1,ENC_BIG_ENDIAN); offset++; cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_bulk, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_mac, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_compression, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_sequence_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_key_refresh, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; case WTLS_HANDSHAKE_CERTIFICATE : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates, tvb, offset,count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); count = tvb_get_ntohs (tvb, offset); offset+=2; for (;count > 0;count-=client_size) { cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_certificate, tvb, offset,1, ENC_NA); client_size=0; wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); proto_item_set_len(cli_key_item, client_size); value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch(value) { case CERTIFICATE_WTLS: proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_version, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_issuer_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_issuer_charset, hf_wtls_hands_certificate_wtls_issuer_size, hf_wtls_hands_certificate_wtls_issuer_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_before, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_after, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_subject_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_subject_charset, hf_wtls_hands_certificate_wtls_subject_size, hf_wtls_hands_certificate_wtls_subject_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } public_key = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_public_key_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } switch (public_key) { case PUBLIC_KEY_RSA : value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_exponent, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_modules, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; break; case PUBLIC_KEY_ECDH : break; case PUBLIC_KEY_ECDSA : break; } value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature, tvb,offset,2+value,value*8); offset+=2+value; client_size+=2+value; break; case CERTIFICATE_X509: case CERTIFICATE_X968: value = tvb_get_ntohs (tvb, offset); offset+=2; client_size+=2; client_size += value; offset += value; break; case CERTIFICATE_URL: value = tvb_get_guint8 (tvb, offset); offset++; client_size++; client_size += value; offset += value; break; } proto_item_set_len(cli_key_item, client_size); } break; default: /*offset+=count;*/ break; } }
static void dissect_UDPR4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string) { const gchar *status_string; guint32 data_type, i, status, seq_num; status = tvb_get_letohl(tvb, 0); status_string = try_val_to_str_ext(status, &error_code_mapping_ext); if (status_string) { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR4 Status: %s", status_string); } else { *info_string = wmem_strdup_printf(wmem_packet_scope(), "UDPR4 Undefined error code %d", status); } /* Get the transaction identifier */ seq_num = tvb_get_letohl(tvb, 4); adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); if (! adwin_tree) return; SET_PACKET_TYPE(adwin_tree, APT_UDPR4); ADWIN_ADD_LE(adwin_tree, status, 0, 4); ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4); ADWIN_ADD_LE(adwin_tree, packet_no, 1408, 4); ADWIN_ADD_LE(adwin_tree, data_type, 1412, 4); data_type = tvb_get_letohl(tvb, 1412); if (! global_adwin_dissect_data) { proto_tree_add_text(adwin_debug_tree, tvb, 8, 350 * 4, "Data"); return; } for (i = 0; i < 350; i++) { proto_item *item; guint32 offset = 8 + i * (int)sizeof(guint32); gint32 value = tvb_get_letohl(tvb, offset); void * fvalue = &value; switch (data_type) { case 2: case 3: case 4: /* some kind of int, usually int/long */ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4, "Data[%3d]: %10d - 0x%08x", i, value, value); item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4); PROTO_ITEM_SET_HIDDEN(item); item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4); PROTO_ITEM_SET_HIDDEN(item); break; case 5: /* float */ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4, "Data[%3d]: %10f - 0x%08x", i, *(float*)fvalue, value); item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4); PROTO_ITEM_SET_HIDDEN(item); item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4); PROTO_ITEM_SET_HIDDEN(item); break; default: /* string, double, variant, something funny... */ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4, "Data[%3d]: 0x%08x", i, value); item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4); PROTO_ITEM_SET_HIDDEN(item); } } }