bool dissect_protobuf_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf) { int len = WireFormat::FieldByteSize( field, *message ); map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT32: proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt32( *message, field ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetFloat( *message, field ) ); break; case FieldDescriptor::CPPTYPE_UINT64: proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetUInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_INT64: proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetInt64( *message, field ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetDouble( *message, field ) ); break; case FieldDescriptor::CPPTYPE_BOOL: proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetBool( *message, field ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetEnum( *message, field ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetString( *message, field ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }
static void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset, guint uPrm, guint uVal, int hfindex, guint iCnt, guint iMaxCnt, guint iDigit, gboolean bParse) { header_field_info *hfinfo; const guint8 *pVal = NULL; if (bParse) pVal = dissect_mqpcf_parm_getintval(uPrm, uVal); hfinfo = proto_registrar_get_nth(hfindex); if (iMaxCnt > 1) { if (pVal) { proto_tree_add_int_format(tree, hfindex, tvb, offset, 4, uVal, "%s[%*d]: %8x-(%9d)-%s", hfinfo->name, iDigit, iCnt, uVal, uVal, pVal); } else { proto_tree_add_int_format(tree, hfindex, tvb, offset, 4, uVal, "%s[%*d]: %8x-(%9d)", hfinfo->name, iDigit, iCnt, uVal, uVal); } } else { if (pVal) { proto_tree_add_int_format_value(tree, hfindex, tvb, offset, 4, uVal, "%8x-(%9d)-%s", uVal, uVal, pVal); } else { proto_tree_add_int_format_value(tree, hfindex, tvb, offset, 4, uVal, "%8x-(%9d)", uVal, uVal); } } }
/* Decode RNG-RSP messages. */ void dissect_mac_mgmt_msg_rng_rsp_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ranging_status_item = NULL; proto_item *dl_freq_override_item = NULL; proto_item *ss_mac_address_item = NULL; proto_item *frame_number_item = NULL; proto_item *opportunity_number_item = NULL; guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *rng_rsp_item = NULL; proto_item *tlv_item = NULL; proto_tree *rng_rsp_tree = NULL; proto_tree *sub_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; guint tlv_len; guint this_offset = 0; tlv_info_t sub_tlv_info; gint sub_tlv_type; gint sub_tlv_len; guint sub_tlv_offset; float timing_adjust; float power_level_adjust; gint offset_freq_adjust; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_RNG_RSP) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type RNG-RSP */ rng_rsp_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-RSP (5)"); /* add MAC RNG-RSP subtree */ rng_rsp_tree = proto_item_add_subtree(rng_rsp_item, ett_mac_mgmt_msg_rng_rsp_decoder); /* display the Message Type */ proto_tree_add_item(rng_rsp_tree, hf_rng_rsp_message_type, tvb, offset, 1, FALSE); proto_tree_add_item(rng_rsp_tree, hf_rng_req_reserved, tvb, 1, 1, FALSE); offset += 2; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case RNG_RSP_TIMING_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Timing Adjust (%u byte(s))", tlv_len); timing_adjust = (float)(gint32)tvb_get_ntohl(tvb, tlv_offset) / 4; tlv_item = proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_timing_adjust, tvb, tlv_offset, 4, timing_adjust, " %.2f modulation symbols", timing_adjust); if ((timing_adjust < -2) || (timing_adjust > 2)) proto_item_append_text(tlv_item, " (during periodic ranging shall not exceed +- 2)"); break; } case RNG_RSP_POWER_LEVEL_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Level Adjust (%u byte(s))", tlv_len); power_level_adjust = (float)(gint8)tvb_get_guint8(tvb, tlv_offset) / 4; proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_power_level_adjust, tvb, tlv_offset, 1, power_level_adjust, " %.2f dB", power_level_adjust); break; } case RNG_RSP_OFFSET_FREQ_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Offset Frequency Adjust (%u byte(s))", tlv_len); offset_freq_adjust = tvb_get_ntohl(tvb, tlv_offset); proto_tree_add_int_format_value(sub_tree, hf_rng_rsp_offset_freq_adjust, tvb, tlv_offset, 4, offset_freq_adjust, " %d Hz", offset_freq_adjust); break; } case RNG_RSP_RANGING_STATUS: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, FALSE); ranging_status_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_DL_FREQ_OVERRIDE: { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, FALSE); dl_freq_override_item = proto_tree_add_item(sub_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, FALSE); proto_item_append_text(dl_freq_override_item, " kHz"); break; } case RNG_RSP_UL_CHANNEL_ID_OVERRIDE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_DL_OPERATIONAL_BURST_PROFILE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_operational_burst_profile, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_diuc, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_ccc, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_SS_MAC_ADDRESS: if (tlv_len == 6) { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); ss_mac_address_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); } else { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); } break; case RNG_RSP_BASIC_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_PRIMARY_MGMT_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_AAS_BROADCAST_PERMISSION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_FRAME_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, FALSE); frame_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, FALSE); break; case RNG_RSP_OPPORTUNITY_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, FALSE); opportunity_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, FALSE); if (tvb_get_ntohl(tvb, tlv_offset) == 0) proto_item_append_text(opportunity_number_item, " (may not be 0!)"); break; case RNG_RSP_SERVICE_LEVEL_PREDICTION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_RESOURCE_RETAIN_FLAG: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_HO_PROCESS_OPTIMIZATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_process_optimization, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_0, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_1_2, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_3, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_4, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_5, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_6, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_7, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_8, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_9, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_10, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_11, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_12, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_13, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_14, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_15, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_SBC_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SBC-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_sbc_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_REG_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "REG-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_reg_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; /* Implemented message encoding 33 (Table 367 in IEEE 802.16e-2007) */ case RNG_RSP_DL_OP_BURST_PROFILE_OFDMA: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_op_burst_profile_ofdma, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_least_robust_diuc, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_repetition_coding_indication, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_config_change_count_of_dcd, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_HO_ID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_LOCATION_UPDATE_RESPONSE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_PAGING_INFORMATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_paging_information, tvb, tlv_offset, 5, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_cycle, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_offset, tvb, tlv_offset+2, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_group_id, tvb, tlv_offset+3, 2, FALSE); break; case RNG_RSP_POWER_SAVING_CLASS_PARAMETERS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class Parameters (%u byte(s))", tlv_len); dissect_power_saving_class(sub_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset); break; case RNG_RSP_SA_CHALLENGE_TUPLE: /* Display SA Challenge Tuple header */ sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SA Challenge Tuple (%u byte(s))", tlv_len); /* add subtree */ /* Use a local copy of tlv_offset */ this_offset = tlv_offset; while(this_offset < tlv_len) { /* Get the sub TLV data. */ init_tlv_info(&sub_tlv_info, tvb, this_offset); /* get the sub TLV type */ sub_tlv_type = get_tlv_type(&sub_tlv_info); /* get the TLV length */ sub_tlv_len = get_tlv_length(&sub_tlv_info); if(tlv_type == -1 || sub_tlv_len > MAX_TLV_LEN || sub_tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, (tvb_len - offset), FALSE); break; } /* get the offset to the sub TLV data */ sub_tlv_offset = this_offset + get_tlv_value_offset(&sub_tlv_info); switch (sub_tlv_type) { case RNG_RSP_SA_CHALLENGE_BS_RANDOM: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; case RNG_RSP_SA_CHALLENGE_AKID: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; default: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; } this_offset = sub_tlv_len + sub_tlv_offset; } break; case DSx_UPLINK_FLOW: /* display Uplink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Uplink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case DSx_DOWNLINK_FLOW: /* display Downlink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Downlink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_RANGING_CODE_ATTRIBUTES: /* case SHORT_HMAC_TUPLE: */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_subchan, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_time_symbol_reference, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_subchannel_reference, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_code_index, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number2, tvb, tlv_offset, 4, FALSE); break; case SHORT_HMAC_TUPLE_COR2: if (include_cor2_changes) { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len); wimax_short_hmac_tuple_decoder(sub_tree, tvb, tlv_offset, tvb_len - offset); } else { /* Unknown TLV type */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); } break; default: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (ranging_status_item && dl_freq_override_item) proto_item_append_text(ranging_status_item, " (shall be set to 2 because Downlink Frequency Override is present)"); if (ss_mac_address_item && frame_number_item) { proto_item_append_text(frame_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Frame Number!)"); } if (ss_mac_address_item && opportunity_number_item) { proto_item_append_text(opportunity_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Initial Ranging Opportunity Number!)"); } if (!ranging_status_item) proto_item_append_text(rng_rsp_tree, " (Ranging status is missing!)"); } }
/* Dissect OSC bundle */ static int dissect_osc_bundle(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *bundle_tree; gint end = offset + len; guint32 sec; guint32 frac; nstime_t ns; /* check for valid #bundle */ if(tvb_strneql(tvb, offset, bundle_str, 8) != 0) return -1; /* create bundle */ ti = proto_tree_add_item(osc_tree, hf_osc_bundle_type, tvb, offset, len, ENC_NA); bundle_tree = proto_item_add_subtree(ti, ett_osc_bundle); offset += 8; /* skip bundle_str */ /* read timetag */ sec = tvb_get_ntohl(tvb, offset); frac = tvb_get_ntohl(tvb, offset+4); if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(bundle_tree, hf_osc_bundle_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(bundle_tree, hf_osc_bundle_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; /* ::read size, read block:: */ while(offset < end) { /* peek bundle element size */ gint32 size = tvb_get_ntohl(tvb, offset); /* read bundle element size */ proto_tree_add_int_format_value(bundle_tree, hf_osc_bundle_element_size_type, tvb, offset, 4, size, "%i bytes", size); offset += 4; /* check for zero size bundle element */ if(size == 0) continue; /* peek first bundle element char */ switch(tvb_get_guint8(tvb, offset)) { case '#': /* this is a bundle */ if(dissect_osc_bundle(tvb, ti, bundle_tree, offset, size)) return -1; else break; case '/': /* this is a message */ if(dissect_osc_message(tvb, ti, bundle_tree, offset, size)) return -1; else break; default: return -1; /* neither message nor bundle */ } /* check for integer overflow */ if(size > G_MAXINT - offset) return -1; else offset += size; } if(offset != end) return -1; else return 0; }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree; proto_tree *header_tree; gint slen; gint rem; gint end = offset + len; const gchar *path; gint path_len; gint path_offset; const gchar *format; gint format_offset; gint format_len; const gchar *ptr; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi; proto_tree *blob_tree; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0) && (frac == 1) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri; proto_tree *rgba_tree; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str; proto_item *mi = NULL; proto_tree *midi_tree; guint8 port; guint8 command; guint8 data1; guint8 data2; guint8 status; guint8 channel; gboolean system_msg; guint8 status_shifted; port = tvb_get_guint8(tvb, offset); command = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status = command & 0xF0; channel = command & 0x0F; system_msg = status == 0xF0; /* is system message */ status_shifted = status >> 4; if(system_msg) status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown"); else status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown"); if(system_msg) { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, %s, %i, %i", port, status_str, data1, data2); } else { switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: case MIDI_STATUS_NOTE_PRESSURE: { const gchar *note_str; note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, note_str, data2); break; } case MIDI_STATUS_CONTROLLER: { const gchar *control_str; control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %s, %i", port, channel, status_str, control_str, data2); break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i", port, channel, status_str, bender); break; } default: { mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Port %i, Channel %i, %s, %i, %i", port, channel, status_str, data1, data2); break; } } } midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(system_msg) { proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch(status_shifted) { case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_NOTE_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CONTROLLER: { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_CHANNEL_PRESSURE: { proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case MIDI_STATUS_PITCH_BENDER: { const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000; proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender); offset += 2; break; } default: { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } } } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
static int dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; proto_tree *wlan_tree = NULL, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; guint8 version; guint16 length; guint32 phy_type; guint32 flags; guint32 channel; gint calc_channel; gint32 rssi; guint8 rate; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+1); col_add_fstr(pinfo->cinfo, COL_INFO, "NetMon WLAN Capture v%u, Length %u", version, length); if (version != 2) { /* XXX - complain */ goto skip; } if (length < MIN_HEADER_LEN) { /* XXX - complain */ goto skip; } /* Dissect the packet */ ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); /* * XXX - is this the NDIS_OBJECT_HEADER structure: * * https://msdn.microsoft.com/en-us/library/windows/hardware/ff566588(v=vs.85).aspx * * at the beginning of a DOT11_EXTSTA_RECV_CONTEXT structure: * * https://msdn.microsoft.com/en-us/library/windows/hardware/ff548626(v=vs.85).aspx * * If so, the byte at an offset of 0 would be the appropriate type for the * structure following it, i.e. NDIS_OBJECT_TYPE_DEFAULT. */ proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* * This isn't in the DOT11_EXTSTA_RECV_CONTEXT structure. */ ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN); opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* * uReceiveFlags? */ flags = tvb_get_letohl(tvb, offset); offset += 4; if (flags != 0xffffffff) { /* * uPhyId? */ phy_type = tvb_get_letohl(tvb, offset); switch (phy_type) { case PHY_TYPE_UNKNOWN: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; case PHY_TYPE_FHSS: phdr->phy = PHDR_802_11_PHY_11_FHSS; phdr->phy_info.info_11_fhss.presence_flags = 0; break; case PHY_TYPE_IR_BASEBAND: phdr->phy = PHDR_802_11_PHY_11_IR; break; case PHY_TYPE_DSSS: phdr->phy = PHDR_802_11_PHY_11_DSSS; break; case PHY_TYPE_HR_DSSS: phdr->phy = PHDR_802_11_PHY_11B; phdr->phy_info.info_11b.presence_flags = 0; break; case PHY_TYPE_OFDM: phdr->phy = PHDR_802_11_PHY_11A; phdr->phy_info.info_11a.presence_flags = 0; break; case PHY_TYPE_ERP: phdr->phy = PHDR_802_11_PHY_11G; phdr->phy_info.info_11g.presence_flags = 0; break; case PHY_TYPE_HT: phdr->phy = PHDR_802_11_PHY_11N; phdr->phy_info.info_11n.presence_flags = 0; break; case PHY_TYPE_VHT: phdr->phy = PHDR_802_11_PHY_11AC; phdr->phy_info.info_11ac.presence_flags = 0; break; default: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; } proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* * uChCenterFrequency? */ channel = tvb_get_letohl(tvb, offset); if (channel < 1000) { if (channel == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel, "Unknown"); } else { guint frequency; phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = channel; proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); switch (phdr->phy) { case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11G: /* 2.4 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, TRUE); break; case PHDR_802_11_PHY_11A: /* 5 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, FALSE); break; default: frequency = 0; break; } if (frequency != 0) { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = frequency; } } } else { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = channel; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, tvb, offset, 4, channel, "%u Mhz", channel); calc_channel = ieee80211_mhz_to_chan(channel); if (calc_channel != -1) { phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = calc_channel; } } offset += 4; /* * usNumberOfMPDUsReceived is missing. */ /* * lRSSI? */ rssi = tvb_get_letohl(tvb, offset); if (rssi == 0) { proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; phdr->signal_dbm = rssi; proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); } offset += 4; /* * ucDataRate? */ rate = tvb_get_guint8(tvb, offset); if (rate == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; phdr->data_rate = rate; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "%f Mb/s", rate*.5); } offset += 1; } else offset += 13; /* * ullTimestamp? * * If so, should this check the presense flag in flags? */ phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); /*offset += 8;*/ skip: offset = length; /* dissect the 802.11 packet next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); return offset; }
bool dissect_protobuf_repeated_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf, int iRepeatedIndex) { int len = 0; string scratch; if( !field->options().packed() ) { len += WireFormat::TagSize( field->number(), field->type() ); } map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() ); if( it == g_mapHandles.end() ) { return false; // bug } Handles* handles = it->second; const Reflection *reflection = message->GetReflection(); const EnumValueDescriptor* enumDesc = NULL; switch( field->cpp_type() ) { case FieldDescriptor::CPPTYPE_UINT32: if( field->type() == FieldDescriptor::TYPE_FIXED32 ) { len += WireFormatLite::kFixed32Size; } else { len += WireFormatLite::UInt32Size( reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT32: if( field->type() == FieldDescriptor::TYPE_SFIXED32 ) { len += WireFormatLite::kSFixed32Size; } else if( field->type() == FieldDescriptor::TYPE_SINT32 ) { len += WireFormatLite::SInt32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); } proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_FLOAT: len += WireFormatLite::kFloatSize; proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedFloat( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_UINT64: if( field->type() == FieldDescriptor::TYPE_FIXED64 ) { len += WireFormatLite::kFixed64Size; } else { len += WireFormatLite::UInt64Size( reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_INT64: if( field->type() == FieldDescriptor::TYPE_SFIXED64 ) { len += WireFormatLite::kSFixed64Size; } else if( field->type() == FieldDescriptor::TYPE_SINT64 ) { len += WireFormatLite::SInt64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } else { len += WireFormatLite::Int64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); } proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_DOUBLE: len += WireFormatLite::kDoubleSize; proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedDouble( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_BOOL: len += WireFormatLite::kBoolSize; proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedBool( *message, field, iRepeatedIndex ) ); break; case FieldDescriptor::CPPTYPE_ENUM: enumDesc = reflection->GetRepeatedEnum( *message, field, iRepeatedIndex ); len += WireFormatLite::EnumSize( enumDesc->number() ); proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() ); break; case FieldDescriptor::CPPTYPE_STRING: len += WireFormatLite::StringSize( reflection->GetRepeatedStringReference( *message, field, iRepeatedIndex, &scratch ) ); proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, reflection->GetRepeatedString( *message, field, iRepeatedIndex ).c_str() ); break; default: proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true ); }; *offset += len; return true; }
static int dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; proto_tree *wlan_tree = NULL, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; guint8 version; guint16 length; guint32 phy_type; guint32 flags; guint32 channel; gint calc_channel; gint32 rssi; guint8 rate; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+1); col_add_fstr(pinfo->cinfo, COL_INFO, "NetMon WLAN Capture v%u, Length %u", version, length); if (version != 2) { /* XXX - complain */ goto skip; } if (length < MIN_HEADER_LEN) { /* XXX - complain */ goto skip; } /* Dissect the packet */ ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN); opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; flags = tvb_get_letohl(tvb, offset); offset += 4; if (flags != 0xffffffff) { phy_type = tvb_get_letohl(tvb, offset); switch (phy_type) { case PHY_TYPE_11B: phdr->phy = PHDR_802_11_PHY_11B; break; case PHY_TYPE_11A: phdr->phy = PHDR_802_11_PHY_11A; phdr->phy_info.info_11a.presence_flags = 0; break; case PHY_TYPE_11G: phdr->phy = PHDR_802_11_PHY_11G; phdr->phy_info.info_11g.presence_flags = 0; break; case PHY_TYPE_11N: phdr->phy = PHDR_802_11_PHY_11N; phdr->phy_info.info_11n.presence_flags = 0; break; default: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; } proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; channel = tvb_get_letohl(tvb, offset); if (channel < 1000) { if (channel == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel, "Unknown"); } else { guint frequency; phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = channel; proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); switch (phdr->phy) { case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11G: /* 2.4 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, TRUE); break; case PHDR_802_11_PHY_11A: /* 5 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, FALSE); break; default: frequency = 0; break; } if (frequency != 0) { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = frequency; } } } else { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = channel; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, tvb, offset, 4, channel, "%u Mhz", channel); calc_channel = ieee80211_mhz_to_chan(channel); if (calc_channel != -1) { phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = calc_channel; } } offset += 4; rssi = tvb_get_letohl(tvb, offset); if (rssi == 0) { proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; phdr->signal_dbm = rssi; proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); } offset += 4; rate = tvb_get_guint8(tvb, offset); if (rate == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; phdr->data_rate = rate; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "%f Mb/s", rate*.5); } offset += 1; } else offset += 13; phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); /*offset += 8;*/ skip: offset = length; /* dissect the 802.11 packet next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); return offset; }
/* Dissect OSC message */ static int dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len) { proto_tree *message_tree = NULL; proto_tree *header_tree = NULL; gint slen; gint rem; gint end = offset + len; const gchar *path = NULL; gint path_len; gint path_offset; const gchar *format = NULL; gint format_offset; gint format_len; const gchar *ptr = NULL; /* peek/read path */ path_offset = offset; path = tvb_get_const_stringz(tvb, path_offset, &path_len); if( (rem = path_len%4) ) path_len += 4-rem; if(!is_valid_path(path)) return -1; /* peek/read fmt */ format_offset = path_offset + path_len; format = tvb_get_const_stringz(tvb, format_offset, &format_len); if( (rem = format_len%4) ) format_len += 4-rem; if(!is_valid_format(format)) return -1; /* create message */ ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format); message_tree = proto_item_add_subtree(ti, ett_osc_message); /* append header */ ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA); header_tree = proto_item_add_subtree(ti, ett_osc_message_header); /* append path */ proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA); /* append format */ proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA); offset += path_len + format_len; /* ::parse argument:: */ ptr = format + 1; /* skip ',' */ while( (*ptr != '\0') && (offset < end) ) { switch(*ptr) { case OSC_INT32: proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_FLOAT: proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case OSC_STRING: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_BLOB: { proto_item *bi = NULL; proto_tree *blob_tree = NULL; gint32 blen = tvb_get_ntohl(tvb, offset); slen = blen; if( (rem = slen%4) ) slen += 4-rem; bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen); blob_tree = proto_item_add_subtree(bi, ett_osc_blob); proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen); offset += 4; /* check for zero length blob */ if(blen == 0) break; proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA); offset += slen; break; } case OSC_TRUE: proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA); break; case OSC_FALSE: proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA); break; case OSC_NIL: proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA); break; case OSC_BANG: proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA); break; case OSC_INT64: proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_DOUBLE: proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; break; case OSC_TIMETAG: { guint32 sec = tvb_get_ntohl(tvb, offset); guint32 frac = tvb_get_ntohl(tvb, offset+4); nstime_t ns; if( (sec == 0UL) && (frac == 1UL) ) proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str); else proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN); offset += 8; } break; case OSC_SYMBOL: slen = tvb_strsize(tvb, offset); if( (rem = slen%4) ) slen += 4-rem; proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA); offset += slen; break; case OSC_CHAR: offset += 3; proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA); offset += 1; break; case OSC_RGBA: { proto_item *ri = NULL; proto_tree *rgba_tree = NULL; ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN); rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba); proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; } case OSC_MIDI: { const gchar *status_str = NULL; const gchar *control_str = NULL; proto_item *mi = NULL; proto_tree *midi_tree = NULL; guint8 channel; guint8 status; guint8 data1; guint8 data2; channel = tvb_get_guint8(tvb, offset); status = tvb_get_guint8(tvb, offset+1); data1 = tvb_get_guint8(tvb, offset+2); data2 = tvb_get_guint8(tvb, offset+3); status_str = val_to_str_const(status, MIDI_status, "Unknown"); if(status == MIDI_STATUS_CONTROLLER) /* MIDI Controller */ { control_str = val_to_str_const(data1, MIDI_control, "Unknown"); mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), %s (0x%02x), 0x%02x", channel, status_str, status, control_str, data1, data2); } else mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4, "MIDI: Channel %2i, %s (0x%02x), 0x%02x, 0x%02x", channel, status_str, status, data1, data2); midi_tree = proto_item_add_subtree(mi, ett_osc_midi); proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if(status == MIDI_STATUS_CONTROLLER) { proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_value_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } break; } default: /* if we get here, there must be a bug in the dissector */ DISSECTOR_ASSERT_NOT_REACHED(); break; } ptr++; } if(offset != end) return -1; else return 0; }
static int dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *wlan_tree, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; guint8 version; guint16 length; guint32 flags; guint32 channel; gint32 rssi; guint8 rate; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+1); col_add_fstr(pinfo->cinfo, COL_INFO, "NetMon WLAN Capture v%u, Length %u", version, length); if (version != 2) { /* XXX - complain */ goto skip; } if (length < MIN_HEADER_LEN) { /* XXX - complain */ goto skip; } /* Dissect the packet */ if (tree) { ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN); opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; flags = tvb_get_letohl(tvb, offset); offset += 4; if (flags != 0xffffffff) { proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; channel = tvb_get_letohl(tvb, offset); if (channel < 1000) { proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); } else { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, tvb, offset, 4, channel, "%u Mhz", channel); } offset += 4; rssi = tvb_get_letohl(tvb, offset); proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); offset += 4; rate = tvb_get_guint8(tvb, offset); if (rate == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "Unknown"); } else { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "%f Mb/s", rate*.5); } offset += 1; } else offset += 13; proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); offset += 8; } /* no return */ skip: offset = length; /* dissect the 802.11 header next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(ieee80211_handle, next_tvb, pinfo, tree); return offset; }