/* packet-mih.c * Definitions for MIH (Media independent Handover) packet disassembly structures and routines * Refer to (IEEE 802.21) IEEE Standard for Local and metropolitan area networks- Part 21: Media Independent Handover Services, 21 Jan 2009 * * Copyright 2011, ANKITH AGARWAL * * The original patch submitted in 2011 was improved and expanded in 2012 by Fraunhofer Institute for Open Communication Systems (FOKUS) * The improvements include filtering of all fields as well as including definitions from the revised IEEE 802.21b document from 10 May 2012 * * Copyright 2012, Alton MacDonald * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include #include void proto_register_mih(void); void proto_reg_handoff_mih(void); static dissector_handle_t mih_handle; #define MIH_PORT 4551 #define VERSION_MASK 0xF0 #define ACKREQ_MASK 0x8 #define ACKRESP_MASK 0x4 #define UIR_MASK 0x2 #define MORE_FRAG_MASK 0x1 #define FRAG_NO_MASK 0xFE #define SID_MASK 0xF000 #define OPCODE_MASK 0x0C00 #define AID_MASK 0x03FF #define TRANS_ID_MASK 0x0FFF #define LEN_OF_LEN_MASK 0x80 /*Type values for TLV encoding*/ #define SRC_MIHF_ID 1 #define DEST_MIHF_ID 2 #define STATUS 3 #define LINK_TYPE 4 #define MIH_EVT_LIST 5 #define MIH_CMD_LIST 6 #define MIH_IQ_TYPE_LIST 7 #define MIH_TRANS_LIST 8 #define LINK_ADDR_LIST 9 #define MBB_HO_SUPP_LIST 10 #define REG_REQUEST_CODE 11 #define VALID_TIME_INTR 12 #define LINK_ID 13 #define NEW_LINK_ID 14 #define OLD_ACCESS_ROUTER 15 #define NEW_ACCESS_ROUTER 16 #define IP_RENEWAL_FLAG 17 #define IP_MOB_MGMT 18 #define IP_CFG_MTHDS 19 #define LINK_DN_REASON 20 #define TIMER_INTERVAL 21 #define LINK_GOING_DN_REASON 22 #define LINK_PARAM_RPT_LIST 23 #define DEV_STATES_REQ 24 #define LINK_ID_LIST 25 #define DEV_STATES_RSP_LIST 26 #define STATUS_REQ_SET 27 #define STATUS_RSP_LIST 28 #define CFG_REQ_LIST 29 #define CFG_RSP_LIST 30 #define LINK_POA_LIST 31 #define PREF_LINK_LIST 32 #define HO_REQ_QUERY_LIST 33 #define HO_STATUS 34 #define ACCESS_ROUTER_ADDR 35 #define DHCP_SER_ADDR 36 #define FA_ADDR 37 #define LINK_ACTION_REQ_LIST 38 #define LINK_ACTION_RSP_LIST 39 #define HO_RESULT 40 #define LINK_RES_STATUS 41 #define RES_RETENTION_STATUS 42 #define IQ_BIN_DATA_LIST 43 #define IQ_RDF_DATA_LIST 44 #define IQ_RDF_SCHEMA_URL 45 #define IQ_RDF_SCHM_LIST 46 #define MAX_RSP_SIZE 47 #define IR_BIN_DATA_LIST 48 #define IR_RDF_DATA_LIST 49 #define IR_SCHM_URL_LIST 50 #define IR_RDF_SCHM_LIST 51 #define MN_MIHF_ID 52 #define Q_RES_RPT_FLAG 53 #define EVT_CFG_INFO_LIST 54 #define TGT_NET_INFO 55 #define TGT_NET_INFO_LIST 56 #define ASGN_RES_SET 57 #define LINK_DET_INFO_LIST 58 #define MN_LINK_ID 59 #define POA_LINK_ADDR 60 #define UNAUTH_INFO_REQ 61 #define NET_TYPE 62 #define REQ_RES_SET 63 #define VEND_SPECIFIC_TLV 100 /*Bitmasks in 802.21 are encoded in Network-Byte-Order: bit0 is leftmost bit*/ /*MASK for event list*/ #define LINK_DETECT_MASK 0x80000000 #define LINK_UP_MASK 0x40000000 #define LINK_DOWN_MASK 0x20000000 #define LINK_PARAM_MASK 0x10000000 #define LINK_GD_MASK 0x08000000 #define LINK_HO_IMM_MASK 0x04000000 #define LINK_HO_COMP_MASK 0x02000000 #define LINK_PDU_MASK 0x01000000 /*MASK for command list*/ /*1st bit is reserved*/ #define CMD_EVT_SUBS_MASK 0x40000000 #define CMD_EVT_UNSUBS_MASK 0x20000000 #define CMD_GET_PARA_MASK 0x10000000 #define CMD_CONF_TH_MASK 0x08000000 #define CMD_LINK_AC_MASK 0x04000000 /*MASK for Info Query list*/ #define IQ_BIN_DATA_MASK 0x80000000 #define IQ_RDF_DATA_MASK 0x40000000 #define IQ_RDF_SCH_U_MASK 0x20000000 #define IQ_RDF_SCH_MASK 0x10000000 #define IQ_IE_NET_TYPE_MASK 0x08000000 #define IQ_IE_OP_ID_MASK 0x04000000 #define IQ_SERV_ID_MASK 0x02000000 #define IQ_IE_COUN_MASK 0x01000000 #define IQ_NET_ID_MASK 0x00800000 #define IQ_NET_AUX_MASK 0x00400000 #define IQ_IE_ROAM_MASK 0x00200000 #define IQ_IE_COST_MASK 0x00100000 #define IQ_IE_QOS_MASK 0x00080000 #define IQ_IE_DATA_MASK 0x00040000 #define IQ_IE_REGDOM_MASK 0x00020000 #define IQ_IE_FREQ_MASK 0x00010000 #define IQ_IE_IP_CFG_MASK 0x00008000 #define IQ_IE_CAP_MASK 0x00004000 #define IQ_IE_SUP_MASK 0x00002000 #define IQ_IE_MOB_MG_MASK 0x00001000 #define IQ_IE_EM_SERV_MASK 0x00000800 #define IQ_IE_IMS_MASK 0x00000400 #define IQ_IE_MOB_NET_MASK 0x00000200 #define IQ_IE_POA_ADDR_MASK 0x00000100 #define IQ_IE_POA_LOC_MASK 0x00000080 #define IQ_IE_POA_CHAN_MASK 0x00000040 #define IQ_IE_POA_SYS_MASK 0x00000020 #define IQ_IE_POA_SUB_MASK 0x00000010 #define IQ_IE_POA_IP_MASK 0x00000008 /*MASK for mobility Management methods*/ #define MOB_MIP4_MASK 0x8000 #define MOB_MIP4_REG_MASK 0x4000 #define MOB_MIP6_MASK 0x2000 #define MOB_HMIP6_MASK 0x1000 #define MOB_LOW_LAT_MASK 0x0800 #define MOB_FMIP6_MASK 0x0400 #define MOB_IKE_MULTI_MASK 0x0200 /*MASK for ip configuration methods*/ #define IP_CFG_STAT_MASK 0x80000000 #define IP_CFG_DHCP4_MASK 0x40000000 #define IP_CFG_MIP4_FA_MASK 0x20000000 #define IP_CFG_MIP4_NFA_MASK 0x10000000 /*bits 4-10 reserved for IPv4 address configuration*/ #define IP_CFG_IP6_SL_MASK 0x00100000 #define IP_CFG_DHCP6_MASK 0x00080000 #define IP_CFG_IP6_MAN_MASK 0x00040000 /*information holder integers...*/ static int proto_mih; static int hf_mih_version; static int hf_mih_ack_req; static int hf_mih_ack_resp; static int hf_mih_uir; static int hf_mih_more_frag; static int hf_mih_frag_no; static int hf_mih_mid; static int hf_mih_service_id; static int hf_mih_opcode; static int hf_mih_serv_actionid; static int hf_mih_event_actionid; static int hf_mih_command_actionid; static int hf_mih_info_actionid; static int hf_mih_tid; static int hf_mih_pay_len; static int hf_mih_type; static int hf_mih_type_length; static int hf_mih_type_length_ext; static int hf_mihf_id; static int hf_mihf_id_mac; static int hf_mihf_id_ipv4; static int hf_mihf_id_ipv6; static int hf_status; static int hf_ip_methods_supported; static int hf_ip_dhcp_services; static int hf_fn_agent; static int hf_access_router; static int hf_link_type; static int hf_link_type_ext; static int hf_ipv4_addr; static int hf_ipv6_addr; static int hf_link_dn_reason; static int hf_link_gdn_reason; static int hf_mac_addr; static int hf_link_param_gen; static int hf_link_param_qos; static int hf_link_param_gg; static int hf_link_param_802_11; static int hf_link_param_fdd; static int hf_link_param_edge; static int hf_link_param_eth; static int hf_link_param_c2k; static int hf_link_param_hrpd; static int hf_link_param_802_16; static int hf_link_param_802_20; static int hf_link_param_802_22; static int hf_link_param_value; static int hf_op_mode; static int hf_link_ac_type; static int hf_link_ac_ext_time; static int hf_link_ac_result; static int hf_ho_reason; static int hf_ho_status; static int hf_reg_request_code; static int hf_ip_renewal; static int hf_max_resp_size; static int hf_time_interval; static int hf_valid_time_interval; static int hf_tsp_carrier; static int hf_mbb_ho_supp; static int hf_link_addr_type; static int hf_link_transport_addr_type; static int hf_link_addr_string; static int hf_link_data_rate; static int hf_plmn_id; static int hf_location_area_id; static int hf_cell_id; static int hf_ci; static int hf_threshold_val; static int hf_threshold_x_dir; static int hf_threshold_action; static int hf_config_status; static int hf_num_cos; static int hf_num_queue; static int hf_channel_id; static int hf_predef_cfg_id; static int hf_network_id; static int hf_net_aux_id; static int hf_sig_strength_dbm; static int hf_sig_strength_per; static int hf_cos_id; static int hf_cos_value; static int hf_sinr; static int hf_rdf_data; static int hf_rdf_mime_type; static int hf_link_res_status; static int hf_res_retention_status; static int hf_res_rpt_flag; static int hf_unauth_info_req; static int hf_rdf_sch; static int hf_rdf_sch_url; static int hf_ir_bin_data; static int hf_iq_bin_data_x; static int hf_vendor_specific_tlv; static int hf_reserved_tlv; static int hf_experimental_tlv; static int hf_unknown_tlv; static int hf_fragmented_tlv; /*header fields for event list */ static int hf_event_list; static int hf_event_link_detect; static int hf_event_link_up; static int hf_event_link_dn; static int hf_event_link_param; static int hf_event_link_gd; static int hf_event_ho_imm; static int hf_event_ho_comp; static int hf_event_pdu_tx_stat; /*header fields for command list*/ static int hf_cmd_list; static int hf_cmd_event_subs; static int hf_cmd_event_unsub; static int hf_cmd_get_param; static int hf_cmd_con_thres; static int hf_cmd_link_action; /*header fields for iq type list*/ static int hf_iq_list; static int hf_iq_bin_data; static int hf_iq_rdf_data; static int hf_iq_rdf_sch_url; static int hf_iq_rdf_sch; static int hf_iq_net_type; static int hf_iq_op_id; static int hf_iq_serv_pro_id; static int hf_iq_country_code; static int hf_iq_net_id; static int hf_iq_net_aux_id; static int hf_iq_roam_part; static int hf_iq_cost; static int hf_iq_net_qos; static int hf_iq_net_dat_rt; static int hf_iq_net_reg_dom; static int hf_iq_freq_bands; static int hf_iq_ip_cfg_mthds; static int hf_iq_net_cap; static int hf_iq_supp_lcp; static int hf_iq_net_mob_mg; static int hf_iq_net_emserv; static int hf_iq_net_ims_pcscf; static int hf_iq_net_mob_net; static int hf_iq_link_addr; static int hf_iq_poa_loc; static int hf_iq_poa_chan_range; static int hf_iq_poa_sys_info; static int hf_iq_poa_sub_info; static int hf_iq_poa_ip; /*header fields for mob mgmt*/ static int hf_mob_list; static int hf_mob_mip4; static int hf_mob_mip4_reg; static int hf_mob_mip6; static int hf_mob_hmip6; static int hf_mob_low_lat; static int hf_mob_fmip6; static int hf_mob_ike_multi; /*header fields for configure methods*/ static int hf_cfg_mthds; static int hf_cfg_ip4_stat; static int hf_cfg_dhcp4; static int hf_cfg_mip_fa; static int hf_cfg_mip_wo_fa; static int hf_cfg_ip6_sac; static int hf_cfg_dhcp6; static int hf_cfg_ip6_manual; /*header fields for transport list*/ static int hf_trans_list; static int hf_trans_udp; static int hf_trans_tcp; /*header fields for device state requests and responses*/ static int hf_dev_states_req; static int hf_dev_states_req_dev_info; static int hf_dev_states_req_batt_lvl; static int hf_dev_states_resp; static int hf_dev_batt_level; static int hf_dev_info; /*header fields for Link Action Attributes*/ static int hf_link_ac_attr; static int hf_link_ac_attr_link_scan; static int hf_link_ac_attr_link_res_retain; static int hf_link_ac_attr_data_fwd_req; /*header fields for transport subtypes*/ static int hf_link_subtype_eth; static int hf_link_subtype_eth_10m; static int hf_link_subtype_eth_100m; static int hf_link_subtype_eth_1000m; static int hf_link_subtype_wireless_other; static int hf_link_subtype_wireless_other_dvb; static int hf_link_subtype_wireless_other_tdmb; static int hf_link_subtype_wireless_other_atsc; static int hf_link_subtype_ieee80211; static int hf_link_subtype_ieee80211_24; static int hf_link_subtype_ieee80211_5; static int hf_link_subtype_ieee80211_49; static int hf_link_subtype_ieee80211_365; static int hf_link_subtype_ieee80211_316; static int hf_link_subtype_umts; static int hf_link_subtype_umts_99; static int hf_link_subtype_umts_4; static int hf_link_subtype_umts_5; static int hf_link_subtype_umts_6; static int hf_link_subtype_umts_7; static int hf_link_subtype_umts_8; static int hf_link_subtype_cdma2000; static int hf_link_subtype_cdma2000_0; static int hf_link_subtype_cdma2000_a; static int hf_link_subtype_cdma2000_b; static int hf_link_subtype_cdma2000_c; static int hf_link_subtype_ieee80216; static int hf_link_subtype_ieee80216_25; static int hf_link_subtype_ieee80216_35; /*header fields for MIH Capabilities*/ static int hf_mihcap; static int hf_mihcap_es; static int hf_mihcap_cs; static int hf_mihcap_is; /*header fields for High Level Network Capabilities*/ static int hf_net_caps; static int hf_net_caps_sec; static int hf_net_caps_qos0; static int hf_net_caps_qos1; static int hf_net_caps_qos2; static int hf_net_caps_qos3; static int hf_net_caps_qos4; static int hf_net_caps_qos5; static int hf_net_caps_ia; static int hf_net_caps_es; static int hf_net_caps_mihcap; /*trees and subtrees...*/ static int ett_mih; static int ett_ver_flags; static int ett_mid; static int ett_tlv; static int ett_cmd_bitmap; static int ett_event_bitmap; static int ett_mob_mgt_bitmap; static int ett_cfg_mtd_bitmap; static int ett_iq_type_bitmap; static int ett_trans_list_bitmap; static int ett_dev_states_bitmap; static int ett_mihcap_bitmap; static int ett_net_caps_bitmap; static int ett_ac_attr_bitmap; static int ett_subtype_eth_bitmap; static int ett_subtype_wireless_other_bitmap; static int ett_subtype_ieee80211_bitmap; static int ett_subtype_umts_bitmap; static int ett_subtype_cdma2000_bitmap; static int ett_subtype_ieee80216_bitmap; static int ett_min_pk_tx_delay; static int ett_avg_pk_tx_delay; static int ett_max_pk_tx_delay; static int ett_pk_delay_jitter; static int ett_pk_loss_rate; static int ett_list_prefer_link; static int ett_ip_dhcp_server; static int ett_fn_agent; static int ett_access_router; static int ett_link_states_req; static int ett_link_desc_req; static int ett_dev_states_resp; /*field definitions of evt, cmd, mob mgmt, ip cfg, iq type */ static int * const event_fields[] = { &hf_event_link_detect, &hf_event_link_up, &hf_event_link_dn, &hf_event_link_param, &hf_event_link_gd, &hf_event_ho_imm, &hf_event_ho_comp, &hf_event_pdu_tx_stat, NULL }; static int * const cmd_fields[] = { &hf_cmd_event_subs, &hf_cmd_event_unsub, &hf_cmd_get_param, &hf_cmd_con_thres, &hf_cmd_link_action, NULL }; static int * const iq_type_fields[] = { &hf_iq_bin_data, &hf_iq_rdf_data, &hf_iq_rdf_sch_url, &hf_iq_rdf_sch, &hf_iq_net_type, &hf_iq_op_id, &hf_iq_serv_pro_id, &hf_iq_country_code, &hf_iq_net_id, &hf_iq_net_aux_id, &hf_iq_roam_part, &hf_iq_cost, &hf_iq_net_qos, &hf_iq_net_dat_rt, &hf_iq_net_reg_dom, &hf_iq_freq_bands, &hf_iq_ip_cfg_mthds, &hf_iq_net_cap, &hf_iq_supp_lcp, &hf_iq_net_mob_mg, &hf_iq_net_emserv, &hf_iq_net_ims_pcscf, &hf_iq_net_mob_net, &hf_iq_link_addr, &hf_iq_poa_loc, &hf_iq_poa_chan_range, &hf_iq_poa_sys_info, &hf_iq_poa_sub_info, &hf_iq_poa_ip, NULL }; static int * const mob_fields[] = { &hf_mob_mip4, &hf_mob_mip4_reg, &hf_mob_mip6, &hf_mob_hmip6, &hf_mob_low_lat, &hf_mob_fmip6, &hf_mob_ike_multi, NULL }; static int * const cfg_fields[] = { &hf_cfg_ip4_stat, &hf_cfg_dhcp4, &hf_cfg_mip_fa, &hf_cfg_mip_wo_fa, &hf_cfg_ip6_sac, &hf_cfg_dhcp6, &hf_cfg_ip6_manual, NULL }; /*field definitions for various bitmaps */ static int * const trans_fields[] = { &hf_trans_udp, &hf_trans_tcp, NULL }; static int * const dev_states_fields[] = { &hf_dev_states_req_dev_info, &hf_dev_states_req_batt_lvl, NULL }; static int * const mihcap_fields[] = { &hf_mihcap_es, &hf_mihcap_cs, &hf_mihcap_is, NULL }; static int * const net_caps_fields[] = { &hf_net_caps_sec, &hf_net_caps_qos0, &hf_net_caps_qos1, &hf_net_caps_qos2, &hf_net_caps_qos3, &hf_net_caps_qos4, &hf_net_caps_qos5, &hf_net_caps_ia, &hf_net_caps_es, &hf_net_caps_mihcap, NULL }; static int * const ac_attr_fields[] = { &hf_link_ac_attr_link_scan, &hf_link_ac_attr_link_res_retain, &hf_link_ac_attr_data_fwd_req, NULL }; static int * const subtype_eth_fields[] = { &hf_link_subtype_eth_10m, &hf_link_subtype_eth_100m, &hf_link_subtype_eth_1000m, NULL }; static int * const subtype_wireless_other_fields[] = { &hf_link_subtype_wireless_other_dvb, &hf_link_subtype_wireless_other_tdmb, &hf_link_subtype_wireless_other_atsc, NULL }; static int * const subtype_ieee80211_fields[] = { &hf_link_subtype_ieee80211_24, &hf_link_subtype_ieee80211_5, &hf_link_subtype_ieee80211_49, &hf_link_subtype_ieee80211_365, &hf_link_subtype_ieee80211_316, NULL }; static int * const subtype_umts_fields[] = { &hf_link_subtype_umts_99, &hf_link_subtype_umts_4, &hf_link_subtype_umts_5, &hf_link_subtype_umts_6, &hf_link_subtype_umts_7, &hf_link_subtype_umts_8, NULL }; static int * const subtype_cdma2000_fields[] = { &hf_link_subtype_cdma2000_0, &hf_link_subtype_cdma2000_a, &hf_link_subtype_cdma2000_b, &hf_link_subtype_cdma2000_c, NULL }; static int * const subtype_ieee80216_fields[] = { &hf_link_subtype_ieee80216_25, &hf_link_subtype_ieee80216_35, NULL }; static const value_string servicevalues[] = { {1, "Service Management"}, {2, "Event Service"}, {3, "Command Service"}, {4, "Information Service"}, {0, NULL} }; static const value_string opcodevalues[] = { {0, "Confirm"}, {1, "Request"}, {2, "Response"}, {3, "Indication"}, {0, NULL}, }; static const value_string link_ac_result_vals[] = { {0, "Success"}, {1, "Failure"}, {2, "Refused"}, {3, "Incapable"}, {0, NULL}, }; static const value_string serv_act_id_values[] = { {1, "MIH_Capability_Discover"}, {2, "MIH_Register"}, {3, "MIH_DeRegister"}, {4, "MIH_Event_Subscribe"}, {5, "MIH_Event_Unsubscribe"}, {0, NULL} }; static const value_string event_act_id_values[] = { {1, "MIH_Link_Detected"}, {2, "MIH_Link_UP"}, {3, "MIH_Link_Down"}, {5, "MIH_Link_Parameter_Report"}, {6, "MIH_Link_Going_down"}, {7, "MIH_Link_Handover_Imminent"}, {8, "MIH_Handover_Complete"}, {0, NULL} }; static const value_string status_types[] = { {0, "Success"}, {1, "Unspecified Failure"}, {2, "Rejected"}, {3, "Authorization Failure"}, {4, "Network Error"}, {0, NULL} }; static const value_string ho_status_vals[] = { {0, "Handover Permitted"}, {1, "Handover Declined"}, {0, NULL} }; static const value_string mbb_ho_supp_vals[] = { {0, "Make before break is not supported."}, {1, "Make before break is supported."}, {0, NULL} }; static const value_string reg_request_code_vals[] = { {0, "Make"}, {1, "Re-Registration"}, {0, NULL} }; static const value_string ip_renewal_vals[] = { {0, "Change Not Required"}, {1, "Change Required"}, {0, NULL} }; static const value_string dev_states_req_vals[] = { {0, "DEVICE_INFO"}, {1, "BATT_LEVEL"}, {0, NULL} }; static const value_string link_addr_types[] ={ {0, "MAC_ADDR"}, {1, "3GPP_3G_CELL_ID"}, {2, "3GPP_2G_CELL_ID"}, {3, "3GPP_ADDR"}, {4, "3GPP2_ADDR"}, {5, "OTHER_L2_ADDR"}, {0, NULL} }; static const value_string threshold_x_dir_vals[] ={ {0, "Above Threshold"}, {1, "Below Threshold"}, {0, NULL} }; static const value_string threshold_action_vals[] ={ {0, "Set Normal Threshold"}, {1, "Set one-shot Threshold"}, {2, "Cancel Threshold"}, {0, NULL} }; static const value_string boolean_types[] ={ {0, "False"}, {1, "True"}, {0, NULL} }; static const value_string command_act_id_values[] = { {1, "MIH_Link_Get_Parameters"}, {2, "MIH_Link_Configure_Thresholds"}, {3, "MIH_Link_Actions"}, {4, "MIH_Net_HO_Candidate_Query"}, {5, "MIH_MN_HO_Candidate_Query"}, {6, "MIH_N2N_HO_Query_Resources"}, {7, "MIH_MN_HO_Commit"}, {8, "MIH_Net_HO-Commit"}, {9, "MN_N2N_HO_Commit"}, {10, "MIH_MN_HO_Complete"}, {11, "MIH_N2N_HO_Complete"}, {12, "MIH_Net_HO_Best_Commit"}, {0, NULL} }; static const value_string info_act_id_values[] = { {1, "MIH_Get_Information"}, {2, "MIH_Push_information"}, {0, NULL} }; static const value_string link_dn_reason_vals[] = { {0, "Explicit Disconnect"}, {1, "Packet Timeout"}, {2, "No resource"}, {3, "No broadcast"}, {4, "Authentication Failure"}, {5, "Billing Failure"}, {0, NULL} }; static const value_string link_gdn_reason_vals[] = { {0, "Explicit Disconnect"}, {1, "Link Parameter Degrading"}, {2, "Low Power"}, {3, "No resource"}, {0, NULL} }; static const value_string link_type_vals[] = { {0, "Reserved"}, {1, "Wireless - GSM"}, {2, "Wireless - GPRS"}, {3, "Wireless - EDGE"}, {15, "Ethernet"}, {18, "Wireless - Other"}, {19, "Wireless - IEEE 802.11"}, {22, "Wireless - CDMA2000"}, {23, "Wireless - UMTS"}, {24, "Wireless - cdma2000-HRPD"}, {27, "Wireless - IEEE 802.16"}, {28, "Wireless - IEEE 802.20"}, {29, "Wireless - IEEE 802.22"}, {40, "DVB"}, {41, "T-DMB"}, {42, "ATSC-M/H"}, {0, NULL} }; static const value_string link_param_gen_vals[] = { {0, "Data Rate"}, {1, "Signal Strength"}, {2, "SINR"}, {3, "Throughput"}, {4, "Packet Error Rate"}, {5, "Channel Frequency"}, {6, "Channel Bandwidth"}, {7, "Channel TX Power"}, {8, "Higher Adjacent Channel Frequency"}, {9, "Higher Adjacent Channel Bandwidth"}, {10, "Higher Adjacent Channel TX Power"}, {11, "Lower Adjacent Channel Frequency"}, {12, "Lower Adjacent Channel Bandwidth"}, {13, "Lower Adjacent Channel TX Power"}, {0, NULL} }; static const value_string link_ac_type_vals[] = { {0, "NONE"}, {1, "LINK_DISCONNECT"}, {2, "LINK_LOW_POWER"}, {3, "LINK_POWER_DOWN"}, {4, "LINK_POWER_UP"}, {5, "LINK_CONFIGURE"}, {0, NULL} }; static const value_string link_param_gg_vals[] = { {0, "Rx Qual"}, {1, "RsLev"}, {2, "Mean BEP"}, {3, "StDev BEP"}, {0, NULL} }; static const value_string link_param_fdd_vals[] = { {0, "CPICH RSCP"}, {1, "PCCPCH RSCP"}, {2, "UTRA carrier RSSI"}, {3, "GSM carrier RSSI"}, {4, "CPICH Ec/No"}, {5, "Transport channel BLER"}, {6, "User equipment (UE) transmitted power"}, {0, NULL} }; static const value_string link_param_802_11_vals[] = { {0, "RSSI"}, {1, "No QoS resource Available"}, {2, "Multicast packet loss rate"}, {0, NULL} }; static const value_string op_mode_vals[] = { {0, "Normal Mode"}, {1, "Power Saving Mode"}, {2, "Powered Down"}, {0, NULL} }; static const value_string link_param_qos_vals[] = { {0, "Max no of differentiable classes"}, {1, "Min Packet transfer delay"}, {2, "Avg packet transfer delay"}, {3, "Max packet transfer delay"}, {4, "delay jitter"}, {5, "Packet loss"}, {0, NULL} }; static const value_string link_param_c2k_hrpd_vals[] = { {0, "Pilot Strength"}, {0, NULL} }; static const value_string typevaluenames[] = { { 1, "Source MIHIF ID" }, { 2, "Destination MIHIF ID" }, { 3, "Status" }, { 4, "Link type" }, { 5, "MIH event list" }, { 6, "MIH command list" }, { 7, "MIIS query type list" }, { 8, "Transport option list" }, { 9, "Link address list" }, { 10, "MBB handover support" }, { 11, "Register request code" }, { 12, "Valid time interval" }, { 13, "Link identifier" }, { 14, "New Link identifier" }, { 15, "Old access router" }, { 16, "New access router" }, { 17, "IP renewal flag" }, { 18, "Mobility management support" }, { 19, "IP address configuration methods" }, { 20, "Link down reason code" }, { 21, "Time interval" }, { 22, "Link going down reason" }, { 23, "Link parameter report list" }, { 24, "Device states request" }, { 25, "Link identifier list" }, { 26, "Device states response list" }, { 27, "Get status request set" }, { 28, "Get status response list" }, { 29, "Configure request list" }, { 30, "Configure response list" }, { 31, "List of link PoA list" }, { 32, "Preferred link list" }, { 33, "Handover resource query list" }, { 34, "Handover status" }, { 35, "Access router address" }, { 36, "DHCP server address" }, { 37, "FA address" }, { 38, "Link actions list" }, { 39, "Link actions result list" }, { 40, "Handover result" }, { 41, "Resource status" }, { 42, "Resource retention status" }, { 43, "Info query binary data list" }, { 44, "Info query RDF data list" }, { 45, "Info query RDF schema URL" }, { 46, "Info query RDF schema list" }, { 47, "Max response size" }, { 48, "Info response binary data list" }, { 49, "Info response RDF data list" }, { 50, "Info response RDF schema URL list" }, { 51, "Info response RDF schema list" }, { 52, "Mobile node MIHF ID" }, { 53, "Query resource report flag" }, { 54, "Event configuration info list" }, { 55, "Target network info" }, { 56, "List of target network info" }, { 57, "Assigned resource set" }, { 58, "Link detected info list" }, { 59, "MN link ID" }, { 60, "PoA" }, { 61, "Unauthenticated information request" }, { 62, "Network type" }, { 63, "Requested resource set" }, {0, NULL} }; static int16_t dissect_mih_list(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree, int16_t (*base_dissect)(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree)) { uint8_t i = 0; uint8_t list_len = tvb_get_uint8(tvb, offset); offset ++; for(i=0; i < list_len; i++) offset = base_dissect(tvb, offset, tlv_tree); return (offset); } static int16_t dissect_ip_addr(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint16_t addr_type = tvb_get_ntohs(tvb, offset); uint8_t len = 0; if(addr_type == 1 ) { /*IPv4 Addr*/ len = tvb_get_uint8(tvb, offset + 3); proto_tree_add_item(tlv_tree, hf_ipv4_addr, tvb, offset+2, len, ENC_BIG_ENDIAN); return (offset+3+len); } if(addr_type == 2) { /*IPv6 Addr*/ len = tvb_get_uint8(tvb, offset + 3); proto_tree_add_item(tlv_tree,hf_ipv6_addr, tvb, offset+2, len, ENC_NA); return (offset+3+len); } else { len = tvb_get_uint8(tvb, offset + 3); return (offset+3+len); } } static int16_t dissect_qos_val(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { proto_tree_add_item(tlv_tree, hf_cos_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++ ; proto_tree_add_item(tlv_tree, hf_cos_value, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; return (offset); } static int16_t dissect_link_addr(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree ) { uint8_t link_addr_choice = tvb_get_uint8(tvb, offset); uint8_t len = 0; proto_tree_add_item(tlv_tree, hf_link_addr_type, tvb, offset, 1, ENC_BIG_ENDIAN); switch (link_addr_choice) { case 0 : /*MAC_ADDR*/ proto_tree_add_item(tlv_tree, hf_link_transport_addr_type, tvb, offset+1, 2, ENC_BIG_ENDIAN); if(tvb_get_ntohs(tvb, offset+1) == 0x06) proto_tree_add_item(tlv_tree, hf_mac_addr, tvb, offset+4, tvb_get_uint8(tvb, offset+3), ENC_NA); return (offset + 10); case 1 :/*3GPP_3G_CELL_ID*/ proto_tree_add_item(tlv_tree, hf_plmn_id, tvb, offset+1, 3, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_cell_id, tvb, offset+4, 4, ENC_BIG_ENDIAN); return (offset + 8); case 2 :/*3GPP_2G_CELL_ID*/ proto_tree_add_item(tlv_tree, hf_plmn_id, tvb, offset+1, 3, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_location_area_id, tvb, offset+4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ci, tvb, offset+6, 2, ENC_BIG_ENDIAN); return (offset + 8); case 3 :/*3GPP_ADDR*/ case 4 :/*3GPP2_ADDR*/ case 5 :/*OTHER_L2_ADDR*/ len = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_link_addr_string, tvb, offset+2, len, ENC_ASCII); return (offset + 2 + len); } return 0; } static int16_t dissect_tsp_container(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; if(tvb_get_uint8(tvb, offset) == 1) { proto_tree_add_item(tlv_tree, hf_predef_cfg_id, tvb, offset+1, 1, ENC_BIG_ENDIAN); return (offset + 2); } else if(tvb_get_uint8(tvb, offset) == 2) { len = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_tsp_carrier, tvb, offset+2, len, ENC_ASCII); return (offset + len + 2); } else return (offset + 1); } static int16_t dissect_iq_rdf_data(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; if(tvb_get_uint8(tvb, offset)) { len = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_rdf_mime_type, tvb, offset+2, len, ENC_ASCII); offset += len + 1; } offset++; len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_rdf_data, tvb, offset+1, len, ENC_ASCII); return (offset+len+1); } static int16_t dissect_qos_list(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { proto_tree *subtree; proto_tree_add_item(tlv_tree, hf_num_cos, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_min_pk_tx_delay, NULL, "MIN_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset, subtree, dissect_qos_val); subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_avg_pk_tx_delay, NULL, "AVG_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset, subtree, dissect_qos_val); subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_max_pk_tx_delay, NULL, "MAX_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset, subtree, dissect_qos_val); subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_pk_delay_jitter, NULL, "PK_DELAY_JITTER"); offset = dissect_mih_list(tvb, offset, subtree, dissect_qos_val); subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_pk_loss_rate, NULL, "PK_LOSS_RATE"); offset = dissect_mih_list(tvb, offset, subtree, dissect_qos_val); return (offset); } static int16_t dissect_dev_states(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; proto_item *item; proto_tree *sub_tree; item = proto_tree_add_item(tlv_tree, hf_dev_states_resp, tvb, offset, 1, ENC_BIG_ENDIAN); sub_tree = proto_item_add_subtree(item, ett_dev_states_resp); if(tvb_get_uint8(tvb, offset)) { /*BATT_LEVEL*/ offset++; proto_tree_add_item(sub_tree, hf_dev_batt_level, tvb, offset, 1, ENC_BIG_ENDIAN); return (offset+1); } else { /*DEVICE INFO*/ offset++; len = tvb_get_uint8(tvb, offset); proto_tree_add_item(sub_tree, hf_dev_info, tvb, offset+1, len, ENC_ASCII); return (offset + len + 1); } } static int16_t dissect_net_type(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; uint8_t type = 0; if(!tvb_get_uint8(tvb, offset)) { /*LINK_TYPE*/ type = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_link_type, tvb, offset+1, 1, ENC_BIG_ENDIAN); offset += 1; } offset += 1; if(!tvb_get_uint8(tvb, offset)) { /*LINK_SUBTYPE*/ switch (type) { /* last 32 bits are not read since proto_tree_add_bitmask only handles bitmasks of length 32 Even though the standard defines a bitmasks of length 64, there are no definitions in the standard that require more than 32 bits 1 (identifier) + 4(bitmask defined values) + 4 (unused bits) = 9 (final offset)*/ case 15 : /*subtype ethernet*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_eth, ett_subtype_eth_bitmap, subtype_eth_fields, ENC_BIG_ENDIAN); break; case 18 : /*subtype wireless other*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_wireless_other, ett_subtype_wireless_other_bitmap, subtype_wireless_other_fields, ENC_BIG_ENDIAN); break; case 19 : /*subtype 802.11*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_ieee80211, ett_subtype_ieee80211_bitmap, subtype_ieee80211_fields, ENC_BIG_ENDIAN); break; case 23 : /*subtype UMTS*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_umts, ett_subtype_umts_bitmap, subtype_umts_fields, ENC_BIG_ENDIAN); break; case 24 : /*subtype cdma2000*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_cdma2000, ett_subtype_cdma2000_bitmap, subtype_cdma2000_fields, ENC_BIG_ENDIAN); break; case 27 : /*subtype 802.16*/ proto_tree_add_bitmask(tlv_tree, tvb, offset+1, hf_link_subtype_ieee80216, ett_subtype_ieee80216_bitmap, subtype_ieee80216_fields, ENC_BIG_ENDIAN); break; default : proto_item_append_text(tlv_tree, "N/A"); } /*4(bitmask defined values) + 4 (unused bits) = 8 bits*/ offset += 8; } /*1 (identifier) = 1 bit*/ offset += 1; if(!tvb_get_uint8(tvb, offset)) { /*TYPE_EXT*/ len = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_link_type_ext, tvb, offset+2, len, ENC_ASCII); offset += len + 2; } return (offset); } static int16_t dissect_net_type_addr(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_net_type(tvb, offset, tlv_tree); offset = dissect_link_addr(tvb, offset, tlv_tree); return (offset) ; } static int16_t dissect_mbb_ho_supp(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_net_type(tvb, offset, tlv_tree); offset = dissect_net_type(tvb, offset, tlv_tree); proto_tree_add_item(tlv_tree, hf_mbb_ho_supp, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; return (offset); } static int16_t dissect_tgt_net_info(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; if(!tvb_get_uint8(tvb, offset)) { offset +=1; /*NETWORK_ID*/ len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_network_id, tvb, offset+1, len, ENC_ASCII); offset += len + 2; if(!tvb_get_uint8(tvb, offset)) { /*NET_AUX_ID*/ offset +=1; len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_net_aux_id, tvb, offset+1, len, ENC_ASCII); return (offset + 1); } return (offset + 2); } else { /*LINK_ADDR*/ offset +=1; offset = dissect_link_addr(tvb, offset, tlv_tree); return (offset); } } static int16_t dissect_link_id(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { int16_t next_offset = 0; /*LINK_TYPE*/ proto_tree_add_item(tlv_tree, hf_link_type, tvb, offset, 1, ENC_BIG_ENDIAN); next_offset = dissect_link_addr(tvb, offset+1, tlv_tree); return (next_offset); } static int16_t dissect_link_poa(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_link_id(tvb, offset, tlv_tree); offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_addr); return (offset); } static int16_t dissect_rq_result(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { proto_tree *subtree; subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_list_prefer_link, NULL, "List of preferred links"); offset = dissect_link_poa(tvb, offset, subtree); offset = dissect_qos_list(tvb, offset, tlv_tree); offset++; switch(tvb_get_uint8(tvb, offset-1)) { case 1: proto_tree_add_item(tlv_tree, hf_ip_methods_supported, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 2: proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_cfg_mthds, ett_cfg_mtd_bitmap, cfg_fields, ENC_BIG_ENDIAN); offset += 2; break; } offset++; switch(tvb_get_uint8(tvb, offset-1)) { case 1: proto_tree_add_item(tlv_tree, hf_ip_dhcp_services, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 2: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_ip_dhcp_server, NULL, "IP DHCP server"); offset = dissect_ip_addr(tvb, offset, subtree); break; } offset++; switch(tvb_get_uint8(tvb, offset-1)) { case 1: proto_tree_add_item(tlv_tree, hf_fn_agent, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 2: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_fn_agent, NULL, "FN Agent"); offset = dissect_ip_addr(tvb, offset, subtree); break; } offset++; switch(tvb_get_uint8(tvb, offset-1)) { case 1: proto_tree_add_item(tlv_tree, hf_access_router, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 2: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 1, ett_access_router, NULL, "Access Router"); offset = dissect_ip_addr(tvb, offset, subtree); break; } return (offset+1); } static int16_t dissect_link_det_info(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; offset = dissect_link_id(tvb, offset, tlv_tree); if(tvb_get_uint8(tvb, offset)) { offset++; offset = dissect_link_addr(tvb, offset, tlv_tree); offset --; } offset++; len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_network_id, tvb, offset+1, len, ENC_ASCII); offset += len + 1; len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_net_aux_id, tvb, offset+1, len, ENC_ASCII); offset += len + 1; if(tvb_get_uint8(tvb, offset)) proto_tree_add_item(tlv_tree, hf_sig_strength_per, tvb, offset+1, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(tlv_tree, hf_sig_strength_dbm, tvb, offset+1, 1, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tlv_tree, hf_sinr, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tlv_tree, hf_link_data_rate, tvb, offset,4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_mihcap, ett_mihcap_bitmap, mihcap_fields, ENC_BIG_ENDIAN); offset++; proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_net_caps, ett_net_caps_bitmap, net_caps_fields, ENC_BIG_ENDIAN); offset += 4; return (offset); } static int16_t dissect_link_scan_rsp(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; offset = dissect_link_addr(tvb, offset, tlv_tree); len = tvb_get_uint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_network_id, tvb, offset+1, len, ENC_ASCII); offset = offset + len + 1; if(tvb_get_uint8(tvb, offset)) proto_tree_add_item(tlv_tree, hf_sig_strength_per, tvb, offset+1, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(tlv_tree, hf_sig_strength_dbm, tvb, offset+1, 1, ENC_BIG_ENDIAN); return offset+2; } static int16_t dissect_link_action_rsp(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_link_id(tvb, offset, tlv_tree); proto_tree_add_item(tlv_tree, hf_link_ac_result, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if(tvb_get_uint8(tvb, offset)) { offset = dissect_mih_list(tvb, offset+1, tlv_tree, dissect_link_scan_rsp); return offset; } else return (offset+1); } static int16_t dissect_link_action_req(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_link_id(tvb, offset, tlv_tree); if(tvb_get_uint8(tvb, offset)) { offset = dissect_link_addr(tvb, offset+1, tlv_tree); } else { offset++; } proto_tree_add_item(tlv_tree, hf_link_ac_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_link_ac_attr, ett_ac_attr_bitmap, ac_attr_fields, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(tlv_tree, hf_link_ac_ext_time, tvb, offset, 2, ENC_BIG_ENDIAN); return (offset+2); } static int16_t dissect_link_states_rsp(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { if(!tvb_get_uint8(tvb, offset)) { proto_tree_add_item(tlv_tree, hf_op_mode, tvb, offset+1, 1, ENC_BIG_ENDIAN); offset += 2; } else { proto_tree_add_item(tlv_tree, hf_channel_id, tvb, offset+1, 2, ENC_BIG_ENDIAN); offset += 3; } return (offset); } static int16_t dissect_link_param_type(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t type = tvb_get_uint8(tvb, offset); offset++; /*LINK_PARAM_TYPE*/ switch (type) { case 0 :/*LINK_PARAM_GEN*/ proto_tree_add_item(tlv_tree, hf_link_param_gen, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 1 :/*LINK_PARAM_QOS*/ proto_tree_add_item(tlv_tree, hf_link_param_qos, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 2 :/*LINK_PARAM_GG*/ proto_tree_add_item(tlv_tree, hf_link_param_gg, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 3 :/*LINK_PARAM_EDGE*/ proto_tree_add_item(tlv_tree, hf_link_param_edge, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 4 :/*LINK_PARAM_ETH*/ proto_tree_add_item(tlv_tree, hf_link_param_eth, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 5 :/*LINK_PARAM_802_11*/ proto_tree_add_item(tlv_tree, hf_link_param_802_11, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 6 :/*LINK_PARAM_C2K*/ proto_tree_add_item(tlv_tree, hf_link_param_c2k, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 7 :/*LINK_PARAM_FDD*/ proto_tree_add_item(tlv_tree, hf_link_param_fdd, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 8 :/*LINK_PARAM_HRPD*/ proto_tree_add_item(tlv_tree, hf_link_param_hrpd, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 9 :/*LINK_PARAM_802_16*/ proto_tree_add_item(tlv_tree, hf_link_param_802_16, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 10 :/*LINK_PARAM_802_20*/ proto_tree_add_item(tlv_tree, hf_link_param_802_20, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 11 :/*LINK_PARAM_802_22*/ proto_tree_add_item(tlv_tree, hf_link_param_802_22, tvb, offset, 1, ENC_BIG_ENDIAN); break; } return (offset+1); } static void dissect_link_status_req(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { proto_tree *subtree; /*LINK_STATES_REQ*/ uint16_t temp = tvb_get_ntohs(tvb, offset); if(!temp) { subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 3, ett_link_states_req, NULL, "LINK_STATES_REQ: "); proto_tree_add_item(subtree, hf_op_mode, tvb, offset+2, 1, ENC_BIG_ENDIAN); offset+=3; } else { subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 4, ett_link_states_req, NULL, "LINK_STATES_REQ: "); proto_tree_add_item(subtree, hf_channel_id, tvb, offset+2, 2, ENC_BIG_ENDIAN); offset+=4; } /*LINK_PARAM_TYPE_LIST*/ offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_param_type); /*LINK_DESC_REQ*/ temp = tvb_get_ntohs(tvb, offset); subtree = proto_tree_add_subtree(tlv_tree, tvb, offset, 3, ett_link_desc_req, NULL, "LINK_DESC_REQ"); offset+=2; if(!temp) proto_tree_add_item(subtree, hf_num_cos, tvb, offset, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(subtree, hf_num_queue, tvb, offset, 1, ENC_BIG_ENDIAN); } static int16_t dissect_link_cfg_status(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_link_param_type(tvb, offset, tlv_tree); proto_tree_add_item(tlv_tree, hf_threshold_val, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tlv_tree, hf_threshold_x_dir, tvb, offset, 1, ENC_BIG_ENDIAN); offset ++; proto_tree_add_item(tlv_tree, hf_config_status, tvb, offset, 1, ENC_BIG_ENDIAN); return (offset+1); } static int16_t dissect_link_param(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { /*LINK_PARAM_TYPE*/ offset = dissect_link_param_type(tvb, offset, tlv_tree); if(!tvb_get_uint8(tvb, offset)) { offset ++; /*LINK_PARAM_VALUE*/ proto_tree_add_item(tlv_tree, hf_link_param_value, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } else { proto_tree *subtree; offset ++; /*QOS_PARAM_VALUE*/ switch(tvb_get_uint8(tvb, offset)) { case 0: proto_tree_add_item(tlv_tree, hf_num_cos, tvb, offset+1, 1, ENC_BIG_ENDIAN); offset += 2; break; case 1: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset+1, 1, ett_min_pk_tx_delay, NULL, "MIN_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset+1, subtree, dissect_qos_val); break; case 2: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset+1, 1, ett_avg_pk_tx_delay, NULL, "AVG_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset+1, subtree, dissect_qos_val); break; case 3: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset+1, 1, ett_max_pk_tx_delay, NULL, "MAX_PK_TX_DELAY"); offset = dissect_mih_list(tvb, offset+1, subtree, dissect_qos_val); break; case 4: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset+1, 1, ett_pk_delay_jitter, NULL, "PK_DELAY_JITTER"); offset = dissect_mih_list(tvb, offset+1, subtree, dissect_qos_val); break; case 5: subtree = proto_tree_add_subtree(tlv_tree, tvb, offset+1, 1, ett_pk_loss_rate, NULL, "PK_LOSS_RATE"); offset = dissect_mih_list(tvb, offset+1, subtree, dissect_qos_val); break; } } return offset; } static int16_t dissect_link_param_rpt(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { /*LINK_PARAM*/ offset = dissect_link_param(tvb, offset, tlv_tree); if(tvb_get_uint8(tvb, offset)) { /*Threshold*/ offset++; proto_tree_add_item(tlv_tree, hf_threshold_val, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tlv_tree, hf_threshold_x_dir, tvb, offset, 1, ENC_BIG_ENDIAN); return (offset+1); } else return (offset+1); } static int16_t dissect_link_desc_rsp(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { if(!tvb_get_uint8(tvb, offset)) proto_tree_add_item(tlv_tree, hf_num_cos, tvb, offset+1, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(tlv_tree, hf_num_queue, tvb, offset+1, 1, ENC_BIG_ENDIAN); return (offset+2); } static int16_t dissect_status_list(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { /*LINK_ID*/ offset = dissect_link_id(tvb, offset, tlv_tree); /*LINK_STATES_RSP*/ offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_states_rsp); /*LINK_PARAM*/ offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_param); /*LINK_DESC_RSP*/ offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_desc_rsp); return offset; } static int16_t dissect_link_det_cfg(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { uint8_t len = 0; if(tvb_get_uint8(tvb, offset)) { len = tvb_get_uint8(tvb, offset+1); proto_tree_add_item(tlv_tree, hf_network_id, tvb, offset+2, len, ENC_ASCII); offset += len + 1; } offset++; if(tvb_get_uint8(tvb, offset)) { if(tvb_get_uint8(tvb, offset+1)) proto_tree_add_item(tlv_tree, hf_sig_strength_per, tvb, offset+2, 1, ENC_BIG_ENDIAN); else proto_tree_add_item(tlv_tree, hf_sig_strength_dbm, tvb, offset+2, 1, ENC_BIG_ENDIAN); offset += 2; } offset++; if(tvb_get_uint8(tvb, offset)) { proto_tree_add_item(tlv_tree, hf_link_data_rate, tvb, offset+1,4, ENC_BIG_ENDIAN); offset += 4; } return (offset+1); } static int16_t dissect_link_cfg_param(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_link_param_type(tvb, offset, tlv_tree); if(tvb_get_uint8(tvb, offset)) { proto_tree_add_item(tlv_tree, hf_time_interval, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } offset++; proto_tree_add_item(tlv_tree, hf_threshold_action, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(tlv_tree, hf_threshold_val, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tlv_tree, hf_threshold_x_dir, tvb, offset, 1, ENC_BIG_ENDIAN); return (offset+1) ; } static int16_t dissect_mih_evt_cfg_info(tvbuff_t *tvb, int16_t offset, proto_tree *tlv_tree) { offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_det_cfg); offset = dissect_mih_list(tvb, offset, tlv_tree, dissect_link_cfg_param); return offset; } static void dissect_mih_tlv(tvbuff_t *tvb,int offset, proto_tree *tlv_tree, uint8_t type, uint32_t length) { uint8_t mihf_id_len = 0; char mihf_id_first_char = 0; uint8_t i = 0; uint8_t len = 0; tvbuff_t *volatile tvb_mihf_id = NULL; tvbuff_t* tvb_temp = NULL; volatile bool composite_error = false; /*For Value fields*/ switch (type) { case SRC_MIHF_ID : case DEST_MIHF_ID : case MN_MIHF_ID : /*MIHF ID*/ mihf_id_len = tvb_get_uint8(tvb, offset); /*taken from the 802.21 standard: If L2 communication is used then MIHF_ID is the NAI-encoded linklayer address (LINK_ADDR) of the entity that hosts the MIH services. In an NAI-encoded IP address or link-layer address, each octet of binary-encoded IP4_ADDR, IP6_ADDR and LINK_ADDR data is encoded in the username part of the NAI as "\" followed by the octet value.*/ mihf_id_first_char = (char)tvb_get_uint8(tvb, offset+1); if(mihf_id_first_char!='\\') proto_tree_add_item(tlv_tree, hf_mihf_id, tvb, offset+1, mihf_id_len, ENC_ASCII); else { if(mihf_id_len 63 && type < 100) proto_tree_add_item(tlv_tree, hf_reserved_tlv, tvb, offset, length, ENC_ASCII); /*EXPERIMENTAL TLVs*/ else if(type > 100 && type < 255) proto_tree_add_item(tlv_tree, hf_experimental_tlv, tvb, offset, length, ENC_ASCII); /*UNKNOWN TLVs*/ else proto_tree_add_item(tlv_tree, hf_unknown_tlv, tvb, offset, length, ENC_ASCII); } return; } static int dissect_mih(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_item *ti = NULL; int offset = 0; proto_item *item = NULL; proto_tree *mih_tree = NULL; proto_tree *ver_flags_tree = NULL; uint8_t serviceid = 0; uint8_t opcode = 0; uint8_t service = 0; uint16_t action = 0; int32_t payload_length = 0; uint64_t len = 0; uint8_t len_of_len = 0; uint8_t type = 0; proto_tree *mid_tree = NULL; proto_tree *tlv_tree = NULL; uint8_t fragment = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "MIH"); col_clear(pinfo->cinfo,COL_INFO); /* we are being asked for details */ ti = proto_tree_add_item(tree, proto_mih, tvb, 0, -1, ENC_NA); mih_tree = proto_item_add_subtree(ti, ett_mih); if(mih_tree) { /* TODO: should have a different hf item for this version root */ item = proto_tree_add_item(mih_tree, hf_mih_version, tvb, offset, 1, ENC_BIG_ENDIAN); ver_flags_tree = proto_item_add_subtree(item, ett_ver_flags); proto_tree_add_item(ver_flags_tree, hf_mih_version, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ver_flags_tree, hf_mih_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ver_flags_tree, hf_mih_ack_resp, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ver_flags_tree, hf_mih_uir, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ver_flags_tree, hf_mih_more_frag, tvb, offset, 1, ENC_BIG_ENDIAN); } fragment = tvb_get_uint8(tvb, offset); fragment = fragment << 7; offset += 1; if(mih_tree) { /*flags and version tree is done.....*/ proto_tree_add_item(mih_tree, hf_mih_frag_no, tvb, offset, 1, ENC_BIG_ENDIAN); /*for MIH message ID*/ item = proto_tree_add_item(mih_tree, hf_mih_mid, tvb, offset + 1, 2, ENC_BIG_ENDIAN); } fragment = fragment + (tvb_get_uint8(tvb, offset)>>1); offset += 1; mid_tree = proto_item_add_subtree(item, ett_mid); serviceid = tvb_get_uint8(tvb, offset); serviceid = serviceid & 0xF0; serviceid >>= 4; proto_tree_add_item(mid_tree, hf_mih_service_id, tvb, offset, 2, ENC_BIG_ENDIAN); /*filling the info column with the service type...*/ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(serviceid, servicevalues, "Unknown")); opcode = tvb_get_uint8(tvb, offset); opcode = opcode & 0x0C; opcode >>= 2; if(mid_tree) proto_tree_add_item(mid_tree, hf_mih_opcode, tvb, offset, 2, ENC_BIG_ENDIAN); /*filling the info column with the opcode type...*/ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(opcode, opcodevalues, "Unknown")); /*check for type of service..*/ service = tvb_get_uint8(tvb, offset); service = service & 0xF0; service >>= 4; /*get the action id.*/ action = tvb_get_ntohs(tvb, offset); action = action & 0x03FF; switch (service) { case 1 :/*for Service Management..*/ proto_tree_add_item(mid_tree, hf_mih_serv_actionid, tvb, offset, 2, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\"", val_to_str_const(action, serv_act_id_values, "Unknown")); break; case 2 :/*for event services..*/ proto_tree_add_item(mid_tree, hf_mih_event_actionid, tvb, offset, 2, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\"", val_to_str_const(action, event_act_id_values, "Unknown")); break; case 3 :/*for Command Services..*/ proto_tree_add_item(mid_tree, hf_mih_command_actionid, tvb, offset, 2, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\"", val_to_str_const(action, command_act_id_values, "Unknown")); break; case 4 :/*for Information Services..*/ proto_tree_add_item(mid_tree, hf_mih_info_actionid, tvb, offset, 2, ENC_BIG_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\"", val_to_str_const(action, info_act_id_values, "Unknown")); break; } offset += 2; if(mih_tree) { /* displaying the transaction id*/ proto_tree_add_item(mih_tree, hf_mih_tid, tvb, offset, 2, ENC_BIG_ENDIAN ); /*displaying the payload length...*/ proto_tree_add_item(mih_tree, hf_mih_pay_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN ); } offset += 2; payload_length = tvb_get_ntohs(tvb, offset); offset += 2; /*now the type length values list is present get them and decode it... loop for showing all the tlvs....*/ while(payload_length > 0 && fragment==0) { /* Adding a third case here since the 802.21 standard defines 3 cases */ /*extract length*/ /*case 1: If the number of octets occupied by the Value field is LESS THAN 128, the size of the Length field is always one octet and the MSB of the octet is set to the value 0. The values of the other seven bits of this octet indicate the actual length of the Value field. */ /*case 2: If the number of octets occupied by the Value field is EXACTLY 128, the size of the Length field is one octet. The MSB of the Length octet is set to the value '1' and the other seven bits of this octet are all set to the value '0'. */ /*case 3: If the number of octets occupied by the Value field is GREATER THAN 128, then the Length field is always greater than one octet. The MSB of the first octet of the Length field is set to the value 1 and the remaining seven bits of the first octet indicate the number of octets that are appended further. The number represented by the second and subsequent octets of the Length field, when added to 128, indicates the total size of the Value field, in octets. */ /*cases 2 and 3 can be logically programmed as the same condition since the whole octet is used to represent the len_of_len parameter. */ /*code for testing if length is less than or equal to 128*/ len = tvb_get_uint8(tvb, offset+1); if(len > 128) { /*length is greater than 128 => len of len is greater than 1 byte*/ /*Expanding conditions where the length values can be from 1- 8 octets long*/ /*TODO: this assumes the maximum value length is 2^64. If larger data types are used, we have to implement our own tvb_get function*/ len_of_len = (uint8_t)len - 128; switch (len_of_len) /*depending on the detected length , we read a different amount of bytes from the tvb buffer*/ { case 1: len = tvb_get_uint8(tvb, offset+2); break; case 2: len = tvb_get_ntohs(tvb, offset+2); break; case 3: len = tvb_get_ntoh24(tvb, offset+2); break; case 4: len = tvb_get_ntohl(tvb, offset+2); break; case 5: len = tvb_get_ntoh40(tvb, offset+2); break; case 6: len = tvb_get_ntoh48(tvb, offset+2); break; case 7: len = tvb_get_ntoh56(tvb, offset+2); break; case 8: len = tvb_get_ntoh64(tvb, offset+2); } len_of_len++; len = 128 + len; } else len_of_len = 1; /*TODO: TLVs greater than the payload_length are fragmented, and currently not parsed*/ if(len <= (uint64_t)payload_length) { /*for type...*/ tlv_tree = proto_tree_add_subtree_format(mih_tree, tvb, offset, 1 + len_of_len + (uint32_t)len, ett_tlv, NULL, "MIH TLV : %s", val_to_str_const(tvb_get_uint8(tvb, offset), typevaluenames, "UNKNOWN")); if(tlv_tree) { proto_tree_add_item(tlv_tree, hf_mih_type, tvb, offset, 1, ENC_BIG_ENDIAN); type = tvb_get_uint8(tvb, offset); /*for length...*/ if(len_of_len == 1) { proto_tree_add_item(tlv_tree, hf_mih_type_length, tvb, offset+1, len_of_len, ENC_BIG_ENDIAN); } else if(len_of_len>1 && len_of_len<=5) { proto_tree_add_item(tlv_tree, hf_mih_type_length_ext, tvb, offset+2, len_of_len-1, ENC_BIG_ENDIAN); } } offset += 1 + len_of_len; /*For Value fields*/ /*TODO: this assumes the maximum value length is 2^32. Dissecting bigger data fields would require breaking the data into chunks*/ if(len < (UINT64_C(1) << 32)){ /* XXX: always true ? see above */ dissect_mih_tlv(tvb, offset, tlv_tree, type, (uint32_t)len); offset += (uint32_t)len; payload_length -= (1 + len_of_len + (uint32_t)len); }else{ return offset; } } else { proto_tree_add_item(mih_tree, hf_fragmented_tlv, tvb, offset, -1, ENC_NA); payload_length = 0; } } if(fragment!=0) proto_tree_add_item(mih_tree, hf_fragmented_tlv, tvb, offset, -1, ENC_NA); return tvb_captured_length(tvb); } /*dissector initialisation*/ void proto_register_mih(void) { static hf_register_info hf[] = { { &hf_mih_version, { "MIH Version", "mih.version", FT_UINT8, BASE_DEC, NULL, VERSION_MASK, NULL, HFILL } }, { &hf_mih_ack_req, { "MIH ACK-Req", "mih.acq_req", FT_BOOLEAN, 8, NULL, ACKREQ_MASK, NULL, HFILL } }, { &hf_mih_ack_resp, { "MIH ACK-Resp", "mih.acq_resp", FT_BOOLEAN, 8, NULL, ACKRESP_MASK, NULL, HFILL } }, { &hf_mih_uir, { "MIH Unauthenticated info request", "mih.uir", FT_BOOLEAN, 8, NULL, UIR_MASK, NULL, HFILL } }, { &hf_mih_more_frag, { "MIH more fragment", "mih.more_frag", FT_BOOLEAN, 8, NULL, MORE_FRAG_MASK, NULL, HFILL } }, { &hf_mih_frag_no, { "Fragment No", "mih.frag_no", FT_UINT8, BASE_DEC, NULL, FRAG_NO_MASK, NULL, HFILL } }, { &hf_mih_mid, { "MIH message ID", "mih.mid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_mih_service_id, { "Service ID", "mih.service_id", FT_UINT16, BASE_HEX, VALS(servicevalues), SID_MASK, NULL, HFILL } }, { &hf_mih_opcode, { "Opcode", "mih.opcode", FT_UINT16, BASE_HEX, VALS(opcodevalues), OPCODE_MASK, NULL, HFILL } }, { &hf_mih_serv_actionid, { "Action ID", "mih.action_id", FT_UINT16, BASE_HEX, VALS(serv_act_id_values), AID_MASK, NULL, HFILL } }, { &hf_mih_event_actionid, { "Action ID", "mih.action_id", FT_UINT16, BASE_HEX, VALS(event_act_id_values), AID_MASK, NULL, HFILL } }, { &hf_mih_command_actionid, { "Action ID", "mih.action_id", FT_UINT16, BASE_HEX, VALS(command_act_id_values), AID_MASK, NULL, HFILL } }, { &hf_mih_info_actionid, { "Action ID", "mih.action_id", FT_UINT16, BASE_HEX, VALS(info_act_id_values), AID_MASK, NULL, HFILL } }, { &hf_mih_tid, { "TID", "mih.tid", FT_UINT16, BASE_DEC, NULL, TRANS_ID_MASK, NULL, HFILL } }, { &hf_mih_pay_len, { "Payload length", "mih.pay_len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_mih_type, { "MIH TLV type", "mih.tlv_type", FT_UINT8, BASE_DEC, VALS(typevaluenames), 0x0, NULL, HFILL } }, { &hf_mih_type_length, { "MIH TLV length", "mih.tlv_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_mih_type_length_ext, { "MIH TLV length", "mih.tlv_length_ext", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_mihf_id, { "MIHF_ID", "mih.mihf_id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_mihf_id_mac, { "MIHF_ID", "mih.mihf_id.mac", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_mihf_id_ipv4, { "MIHF_ID", "mih.mihf_id.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_mihf_id_ipv6, { "MIHF_ID", "mih.mihf_id.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_status, { "STATUS", "mih.status", FT_UINT8, BASE_DEC, VALS(status_types), 0x0, NULL, HFILL } }, { &hf_ip_methods_supported, { "IP methods supported", "mih.ip_methods_supported", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_ip_dhcp_services, { "IP DHCP services", "mih.ip_dhcp_services", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_fn_agent, { "FN Agent", "mih.fn_agent", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_access_router, { "Access Router", "mih.access_router", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_link_type, { "Link Type", "mih.link_type", FT_UINT8, BASE_DEC, VALS(link_type_vals), 0x0, NULL, HFILL } }, { &hf_link_subtype_eth, { "Ethernet - IEEE802.3 Subtype", "mih.link_subtype_eth", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_eth_10m, { "Ethernet 10 Mb", "mih.link_subtype_eth.10mb", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_eth_100m, { "Ethernet 100 Mb", "mih.link_subtype_eth.100mb", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_subtype_eth_1000m, { "Ethernet 1000 Mb", "mih.link_subtype_eth.1000mb", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } }, { &hf_link_subtype_wireless_other, { "Wireless Other Subtype", "mih.link_subtype_wireless_other", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_wireless_other_dvb, { "DVB", "mih.link_subtype_wireless_other.dvb", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_wireless_other_tdmb, { "T-DVB", "mih.link_subtype_wireless_other.tdmb", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_subtype_wireless_other_atsc, { "ATSC-M/H", "mih.link_subtype_wireless_other.atsc", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } }, { &hf_link_subtype_ieee80211, { "Wireless - IEEE 802.11 Subtype", "mih.link_subtype_ieee80211", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_ieee80211_24, { "2.4 GHz", "mih.link_subtype_ieee80211.2_4ghz", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_ieee80211_5, { "5 GHz", "mih.link_subtype_ieee80211.5ghz", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_subtype_ieee80211_49, { "4.9 GHz", "mih.link_subtype_ieee80211.4_9ghz", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } }, { &hf_link_subtype_ieee80211_365, { "3.65 GHz", "mih.link_subtype_ieee80211.3_65ghz", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL } }, { &hf_link_subtype_ieee80211_316, { "316 THz", "mih.link_subtype_ieee80211.316thz", FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL } }, { &hf_link_subtype_umts, { "Wireless - UMTS Subtype", "mih.link_subtype_umts", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_umts_99, { "Rel-99", "mih.link_subtype_umts.rel99", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_umts_4, { "Rel-4", "mih.link_subtype_umts.rel4", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_subtype_umts_5, { "Rel-5 (w/HSDPA)", "mih.link_subtype_umts.rel5", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } }, { &hf_link_subtype_umts_6, { "Rel-6 (w/ HSUPA)", "mih.link_subtype_umts.rel6", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL } }, { &hf_link_subtype_umts_7, { "Rel-7 (MIMO/OFDM)", "mih.link_subtype_umts.rel7", FT_BOOLEAN, 32, NULL, 0x00000010, NULL, HFILL } }, { &hf_link_subtype_umts_8, { "Rel-8", "mih.link_subtype_umts.rel8", FT_BOOLEAN, 32, NULL, 0x00000020, NULL, HFILL } }, { &hf_link_subtype_cdma2000, { "Wireless - cdma2000-HRPD", "mih.link_subtype_cdma2000", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_cdma2000_0, { "Rev-0", "mih.link_subtype_cdma2000.rev0", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_cdma2000_a, { "Rev-A", "mih.link_subtype_cdma2000.reva", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_subtype_cdma2000_b, { "Rev-B", "mih.link_subtype_cdma2000.revb", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } }, { &hf_link_subtype_cdma2000_c, { "Rev-C", "mih.link_subtype_cdma2000.revc", FT_BOOLEAN, 32, NULL, 0x00000008, NULL, HFILL } }, { &hf_link_subtype_ieee80216, { "Wireless - IEEE 802.16", "mih.link_subtype_ieee80216", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_subtype_ieee80216_25, { "2.5 GHz", "mih.link_subtype_ieee80216.2_5ghz", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } }, { &hf_link_subtype_ieee80216_35, { "3.5 GHz", "mih.link_subtype_ieee80216.3_5ghz", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } }, { &hf_link_type_ext, { "LINK_TYPE_EXT", "mih.link_type_ext", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_ipv4_addr, { "IP Address", "mih.ipv4_addr", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_ipv6_addr, { "IP Address", "mih.ipv6_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_link_dn_reason, { "LINK Down Reason", "mih.link_dn_reason", FT_UINT8, BASE_DEC, VALS(link_dn_reason_vals), 0x0, NULL, HFILL } }, { &hf_link_gdn_reason, { "LINK Going Down Reason", "mih.link_gdn_reason", FT_UINT8, BASE_DEC, VALS(link_gdn_reason_vals), 0x0, NULL, HFILL } }, { &hf_mac_addr, { "MAC ADDRESS", "mih.mac_addr", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_gen, { "LINK_PARAM", "mih.link_param_gen", FT_UINT8, BASE_DEC, VALS(link_param_gen_vals), 0x0, NULL, HFILL } }, { &hf_link_param_qos, { "LINK_PARAM", "mih.link_param_qos", FT_UINT8, BASE_DEC, VALS(link_param_qos_vals), 0x0, NULL, HFILL } }, { &hf_link_param_gg, { "LINK_PARAM", "mih.link_param_gg", FT_UINT8, BASE_DEC, VALS(link_param_gg_vals), 0x0, NULL, HFILL } }, { &hf_link_param_edge, { "LINK_PARAM", "mih.link_param_edge", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_eth, { "LINK_PARAM", "mih.link_param_eth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_802_11, { "LINK_PARAM", "mih.link_param_802_11", FT_UINT8, BASE_DEC, VALS(link_param_802_11_vals), 0x0, NULL, HFILL } }, { &hf_link_param_c2k, { "LINK_PARAM", "mih.link_param_c2k", FT_UINT8, BASE_DEC, VALS(link_param_c2k_hrpd_vals), 0x0, NULL, HFILL } }, { &hf_link_param_fdd, { "LINK_PARAM", "mih.link_param_fdd", FT_UINT8, BASE_DEC, VALS(link_param_fdd_vals), 0x0, NULL, HFILL } }, { &hf_link_param_hrpd, { "LINK_PARAM", "mih.link_param_hrpd", FT_UINT8, BASE_DEC, VALS(link_param_c2k_hrpd_vals), 0x0, NULL, HFILL } }, { &hf_link_param_802_16, { "LINK_PARAM", "mih.link_param_802_16", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_802_20, { "LINK_PARAM", "mih.link_param_802_20", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_802_22, { "LINK_PARAM", "mih.link_param_802_22", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_param_value, { "LINK_VALUE", "mih.link_param_value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_op_mode, { "OP_MODE", "mih.op_mode", FT_UINT8, BASE_DEC, VALS(op_mode_vals), 0x0, NULL, HFILL } }, { &hf_link_ac_type, { "LINK_AC_TYPE", "mih.link_ac_type", FT_UINT8, BASE_DEC, VALS(link_ac_type_vals), 0x0, NULL, HFILL } }, { &hf_link_ac_ext_time, { "LINK_AC_ext_time", "mih.link_ac_ext_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_ac_result, { "LINK_AC_RESULT", "mih.link_ac_result", FT_UINT8, BASE_DEC, VALS(link_ac_result_vals), 0x0, NULL, HFILL } }, { &hf_ho_reason, { "HO CAUSE", "mih.ho_reason", FT_UINT8, BASE_DEC, VALS(link_dn_reason_vals), 0x0, NULL, HFILL } }, { &hf_ho_status, { "HO STATUS", "mih.ho_status", FT_UINT8, BASE_DEC, VALS(ho_status_vals), 0x0, NULL, HFILL } }, { &hf_mbb_ho_supp, { "MBB HO SUPP", "mih.mbb_ho_supp", FT_UINT8, BASE_DEC, VALS(mbb_ho_supp_vals), 0x0, NULL, HFILL } }, { &hf_reg_request_code, { "REGISTER REQUEST CODE", "mih.reg_request_code", FT_UINT8, BASE_DEC, VALS(reg_request_code_vals), 0x0, NULL, HFILL } }, { &hf_ip_renewal, { "IP RENEWAL FLAG", "mih.ip_renewal", FT_UINT8, BASE_DEC, VALS(ip_renewal_vals), 0x0, NULL, HFILL } }, { &hf_dev_states_resp, { "SUPPORTED TRANSPORTS", "mih.dev_states_resp", FT_UINT8, BASE_DEC, VALS(dev_states_req_vals), 0x0, NULL, HFILL } }, { &hf_dev_batt_level, { "Battery Level", "mih.dev_states_resp.batt_level", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_dev_info, { "Device Info", "mih.dev_states_resp.dev_info", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_max_resp_size, { "Maximum Response Size", "mih.max_resp_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_time_interval, { "Time Interval", "mih.time_interval", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_valid_time_interval, { "Valid Time Interval", "mih.valid_time_interval", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_tsp_carrier, { "TSP Carrier", "mih.tsp_carrier", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_link_addr_type, { "Link Address Type", "mih.link_addr_type", FT_UINT8, BASE_DEC, VALS(link_addr_types), 0x0, NULL, HFILL } }, { &hf_link_transport_addr_type, { "Link Transport Address Type", "mih.link_transport_addr_type", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_addr_string, { "Link Address String", "mih.link_addr_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cell_id, { "3G Cell ID", "mih.cell_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_ci, { "2G Cell ID", "mih.ci", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_plmn_id, { "Public Land Mobile Network (PLMN) ID", "mih.plmn_id", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_location_area_id, { "Location Area Code (LAC)", "mih.lac", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_threshold_val, { "Threshold Value", "mih.threshold_val", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_threshold_x_dir, { "Threshold Direction", "mih.threshold_x_dir", FT_UINT8, BASE_DEC, VALS(threshold_x_dir_vals), 0x0, NULL, HFILL } }, { &hf_threshold_action, { "Threshold Action", "mih.threshold_action", FT_UINT8, BASE_DEC, VALS(threshold_action_vals), 0x0, NULL, HFILL } }, { &hf_config_status, { "Config Status", "mih.config_status", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_num_cos, { "Number of differentiable classes", "mih.num_cos", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_num_queue, { "Number of transmit queues supported", "mih.num_queue", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_channel_id, { "Channel ID", "mih.channel_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_predef_cfg_id, { "Pre-defined Configuration Identifier", "mih.predef_cfg_id", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_network_id, { "Network ID", "mih.network_id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_net_aux_id, { "Auxiliary Network ID", "mih.net_aux_id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_sig_strength_dbm, { "Signal Strength (dBm)", "mih.sig_strength", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_sig_strength_per, { "Signal Strength (%)", "mih.sig_strength", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cos_id, { "Class of Service ID", "mih.cos_id", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cos_value, { "Class of Service Value", "mih.cos_value", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_sinr, { "SINR", "mih.sinr", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_link_data_rate, { "Link Data Rate (kb/s)", "mih.link_data_rate", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_rdf_data, { "RDF data", "mih.rdf_data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_rdf_mime_type, { "RDF data", "mih.rdf_mime_type", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_link_res_status, { "Resource Status", "mih.res_status", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_res_retention_status, { "Info query RDF schema URL", "mih.res_retention_status", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_res_rpt_flag, { "Query resource report flag", "mih.res_rpt_flag", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_unauth_info_req, { "Unauthenticated information request", "mih.unauth_info_req", FT_UINT8, BASE_DEC, VALS(boolean_types), 0x0, NULL, HFILL } }, { &hf_rdf_sch, { "RDF Schema", "mih.rdf_sch", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_rdf_sch_url, { "RDF Schema URL", "mih.rdf_sch_url", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_ir_bin_data, { "IR Binary Data", "mih.ir_bin_data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_iq_bin_data_x, { "IQ Binary Data", "mih.iq_bin_data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_vendor_specific_tlv, { "Vendor Specific TLV", "mih.vendor_specific_tlv", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_reserved_tlv, { "Reserved TLV", "mih.reserved_tlv", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_experimental_tlv, { "Experimental TLV", "mih.experimental_tlv", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_unknown_tlv, { "UNKNOWN TLV", "mih.unknown_tlv", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_fragmented_tlv, { "FRAGMENTED TLV", "mih.fragmented_tlv", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, /*event related hf fields*/ { &hf_event_list, { "List of Events", "mih.event_list", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_event_link_detect, { "MIH LINK Detected", "mih.event_list.link_detect", FT_BOOLEAN, 32, NULL, LINK_DETECT_MASK, NULL, HFILL } }, { &hf_event_link_up, { "MIH LINK UP", "mih.event_list.link_up", FT_BOOLEAN, 32, NULL, LINK_UP_MASK, NULL, HFILL } }, { &hf_event_link_dn, { "MIH LINK DOWN", "mih.event_list.link_down", FT_BOOLEAN, 32, NULL, LINK_DOWN_MASK, NULL, HFILL } }, { &hf_event_link_param, { "MIH LINK Parameters Report", "mih.event_list.link_param_rpt", FT_BOOLEAN, 32, NULL, LINK_PARAM_MASK, NULL, HFILL } }, { &hf_event_link_gd, { "MIH LINK Going Down", "mih.event_list.link_gd", FT_BOOLEAN, 32, NULL, LINK_GD_MASK, NULL, HFILL } }, { &hf_event_ho_imm, { "Link Handover Imminent", "mih.event_list.link_ho_imm", FT_BOOLEAN, 32, NULL, LINK_HO_IMM_MASK, NULL, HFILL } }, { &hf_event_ho_comp, { "MIH LINK Handover Complete", "mih.event_list.link_ho_comp", FT_BOOLEAN, 32, NULL, LINK_HO_COMP_MASK, NULL, HFILL } }, { &hf_event_pdu_tx_stat, { "MIH LINK PDU Transmit Status", "mih.event_list.link_pdu_tx_stat", FT_BOOLEAN, 32, NULL, LINK_PDU_MASK, NULL, HFILL } }, /* cmd related hf fields */ { &hf_cmd_list, { "List of Commands", "mih.command_list", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cmd_event_subs, { "MIH LINK Event Subscribe", "mih.cmd_list.evt_subs", FT_BOOLEAN, 32, NULL, CMD_EVT_SUBS_MASK, NULL, HFILL } }, { &hf_cmd_event_unsub, { "Link Event Unsubscribe", "mih.cmd_list.evt_unsubs", FT_BOOLEAN, 32, NULL, CMD_EVT_UNSUBS_MASK, NULL, HFILL } }, { &hf_cmd_get_param, { "MIH LINK Get Parameters", "mih.cmd_list.evt_get_param", FT_BOOLEAN, 32, NULL, CMD_GET_PARA_MASK, NULL, HFILL } }, { &hf_cmd_con_thres, { "Link Configure Thresholds", "mih.cmd_list.evt_conf_th", FT_BOOLEAN, 32, NULL, CMD_CONF_TH_MASK, NULL, HFILL } }, { &hf_cmd_link_action, { "MIH LINK Action", "mih.cmd_list.evt_link_action", FT_BOOLEAN, 32, NULL, CMD_LINK_AC_MASK, NULL, HFILL } }, /*header fields for iq type list*/ { &hf_iq_list, { "List of of IS query types", "mih.iq_type_list", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_iq_bin_data, { "Binary data", "mih.iq_type_list.bin_data", FT_BOOLEAN, 32, NULL, IQ_BIN_DATA_MASK, NULL, HFILL } }, { &hf_iq_rdf_data, { "RDF data", "mih.iq_type_list.rdf_data", FT_BOOLEAN, 32, NULL, IQ_RDF_DATA_MASK, NULL, HFILL } }, { &hf_iq_rdf_sch_url, { "RDF schema URL", "mih.iq_type_list.rdf_sch_u", FT_BOOLEAN, 32, NULL, IQ_RDF_SCH_U_MASK, NULL, HFILL } }, { &hf_iq_rdf_sch, { "RDF schema", "mih.iq_type_list.rdf_sch", FT_BOOLEAN, 32, NULL, IQ_RDF_SCH_MASK, NULL, HFILL } }, { &hf_iq_net_type, { "IE_NETWORK_TYPE", "mih.iq_type_list.ie_net_type", FT_BOOLEAN, 32, NULL, IQ_IE_NET_TYPE_MASK, NULL, HFILL } }, { &hf_iq_op_id, { "IE_OPERATOR_ID", "mih.iq_type_list.ie_op_id", FT_BOOLEAN, 32, NULL, IQ_IE_OP_ID_MASK, NULL, HFILL } }, { &hf_iq_serv_pro_id, { "IE_SERVICE_PROVIDER_ID", "mih.iq_type_list.ie_serv_id", FT_BOOLEAN, 32, NULL, IQ_SERV_ID_MASK, NULL, HFILL } }, { &hf_iq_country_code, { "IE_COUNTRY_CODE", "mih.iq_type_list.ie_country_code", FT_BOOLEAN, 32, NULL, IQ_IE_COUN_MASK, NULL, HFILL } }, { &hf_iq_net_id, { "IE_NETWORK_ID", "mih.iq_type_list.ie_net_id", FT_BOOLEAN, 32, NULL, IQ_NET_ID_MASK, NULL, HFILL } }, { &hf_iq_net_aux_id, { "IE_NETWORK_AUX_ID", "mih.iq_type_list.net_aux_id", FT_BOOLEAN, 32, NULL, IQ_NET_AUX_MASK, NULL, HFILL } }, { &hf_iq_roam_part, { "IE_ROAMING_PARTNERS", "mih.iq_type_list.ie_roam_part", FT_BOOLEAN, 32, NULL, IQ_IE_ROAM_MASK, NULL, HFILL } }, { &hf_iq_cost, { "IE_COST", "mih.iq_type_list.ie_cost", FT_BOOLEAN, 32, NULL, IQ_IE_COST_MASK, NULL, HFILL } }, { &hf_iq_net_qos, { "IE_NETWORK_QOS", "mih.iq_type_list.ie_net_qos", FT_BOOLEAN, 32, NULL, IQ_IE_QOS_MASK, NULL, HFILL } }, { &hf_iq_net_dat_rt, { "IE_NETWORK_DATA_RATE", "mih.iq_type_list.ie_net_dat_rt", FT_BOOLEAN, 32, NULL, IQ_IE_DATA_MASK, NULL, HFILL } }, { &hf_iq_net_reg_dom, { "IE_NET_REGULT_DOMAIN", "mih.iq_type_list.ie_net_reg_dom", FT_BOOLEAN, 32, NULL, IQ_IE_REGDOM_MASK, NULL, HFILL } }, { &hf_iq_freq_bands, { "IE_NET_FREQUENCY_BANDS", "mih.iq_type_list.ie_net_freq", FT_BOOLEAN, 32, NULL, IQ_IE_FREQ_MASK, NULL, HFILL } }, { &hf_iq_ip_cfg_mthds, { "IE_NET_IP_CFG_METHODS", "mih.iq_type_list.ie_net_ip_cfg", FT_BOOLEAN, 32, NULL, IQ_IE_IP_CFG_MASK, NULL, HFILL } }, { &hf_iq_net_cap, { "IE_NET_CAPABILITIES", "mih.iq_type_list.ie_net_cap", FT_BOOLEAN, 32, NULL, IQ_IE_CAP_MASK, NULL, HFILL } }, { &hf_iq_supp_lcp, { "IE_NET_SUPPORTED_LCP", "mih.iq_type_list.ie_net_sup_lcp", FT_BOOLEAN, 32, NULL, IQ_IE_SUP_MASK, NULL, HFILL } }, { &hf_iq_net_mob_mg, { "IE_NET_MOB_MGMT_PROT", "mih.iq_type_list.ie_net_mob_mg", FT_BOOLEAN, 32, NULL, IQ_IE_MOB_MG_MASK, NULL, HFILL } }, { &hf_iq_net_emserv, { "IE_NET_EMSERV_PROXY", "mih.iq_type_list.ie_net_emer_serv", FT_BOOLEAN, 32, NULL, IQ_IE_EM_SERV_MASK, NULL, HFILL } }, { &hf_iq_net_ims_pcscf, { "IE_NET_IMS_PROXY_CSCF", "mih.iq_type_list.ie_net_ims_pcscf", FT_BOOLEAN, 32, NULL, IQ_IE_IMS_MASK, NULL, HFILL } }, { &hf_iq_net_mob_net, { "IE_NET_MOBILE_NETWORK", "mih.iq_type_list.ie_net_mob_net", FT_BOOLEAN, 32, NULL, IQ_IE_MOB_NET_MASK, NULL, HFILL } }, { &hf_iq_link_addr, { "IE_POA_LINK_ADDR", "mih.iq_type_list.ie_poa_link", FT_BOOLEAN, 32, NULL, IQ_IE_POA_ADDR_MASK, NULL, HFILL } }, { &hf_iq_poa_loc, { "IE_POA_LOCATION", "mih.iq_type_list.ie_poa_loc", FT_BOOLEAN, 32, NULL, IQ_IE_POA_LOC_MASK, NULL, HFILL } }, { &hf_iq_poa_chan_range, { "IE_POA_CHANNEL_RANGE", "mih.iq_type_list.ie_poa_chan_rg", FT_BOOLEAN, 32, NULL, IQ_IE_POA_CHAN_MASK, NULL, HFILL } }, { &hf_iq_poa_sys_info, { "IE_POA_SYSTEM_INFO", "mih.iq_type_list.ie_poa_syst_info", FT_BOOLEAN, 32, NULL, IQ_IE_POA_SYS_MASK, NULL, HFILL } }, { &hf_iq_poa_sub_info, { "IE_POA_SUBNET_INFO", "mih.iq_type_list.ie_poa_sub_info", FT_BOOLEAN, 32, NULL, IQ_IE_POA_SUB_MASK, NULL, HFILL } }, { &hf_iq_poa_ip, { "IE_POA_IP_ADDR", "mih.iq_type_list.ie_poa_ip", FT_BOOLEAN, 32, NULL, IQ_IE_POA_IP_MASK, NULL, HFILL } }, /*header fields for mob mgmt*/ { &hf_mob_list, { "List of supported mobility management protocols", "mih.mob_list", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_mob_mip4, { "Mobile IPv4", "mih.mob_list.mip4", FT_BOOLEAN, 16, NULL, MOB_MIP4_MASK, NULL, HFILL } }, { &hf_mob_mip4_reg, { "Mobile IPv4 Regional Registration", "mih.mob_list.mip4_reg", FT_BOOLEAN, 16, NULL, MOB_MIP4_REG_MASK, NULL, HFILL } }, { &hf_mob_mip6, { "Mobile IPv6", "mih.mob_list.mip6", FT_BOOLEAN, 16, NULL, MOB_MIP6_MASK, NULL, HFILL } }, { &hf_mob_hmip6, { "Hierarchical Mobile IPv6", "mih.mob_list.hmip6", FT_BOOLEAN, 16, NULL, MOB_HMIP6_MASK, NULL, HFILL } }, { &hf_mob_low_lat, { "Low Latency Handoffs", "mih.mob_list.low_lat", FT_BOOLEAN, 16, NULL, MOB_LOW_LAT_MASK, NULL, HFILL } }, { &hf_mob_fmip6, { "Mobile IPv6 Fast Handovers", "mih.mob_list.fmip6", FT_BOOLEAN, 16, NULL, MOB_FMIP6_MASK, NULL, HFILL } }, { &hf_mob_ike_multi, { "IKEv2 Mobility and Multihoming Protocol", "mih.mob_list.ike_multi", FT_BOOLEAN, 16, NULL, MOB_IKE_MULTI_MASK, NULL, HFILL } }, /*header fields for configure methods*/ { &hf_cfg_mthds, { "A set of IP configuration methods", "mih.cfg_mthds", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cfg_ip4_stat, { "IPv4 static configuration", "mih.ip_cfg_mthds.static", FT_BOOLEAN, 32, NULL, IP_CFG_STAT_MASK, NULL, HFILL } }, { &hf_cfg_dhcp4, { "DHCPv4", "mih.ip_cfg_mthds.dhcp4", FT_BOOLEAN, 32, NULL, IP_CFG_DHCP4_MASK, NULL, HFILL } }, { &hf_cfg_mip_fa, { "Mobile IPv4 with foreign agent", "mih.ip_cfg_mthds.mip4_fa", FT_BOOLEAN, 32, NULL, IP_CFG_MIP4_FA_MASK, NULL, HFILL } }, { &hf_cfg_mip_wo_fa, { "Mobile IPv4 without FA", "mih.ip_cfg_mthds.mip4_wo_fa", FT_BOOLEAN, 32, NULL, IP_CFG_MIP4_NFA_MASK, NULL, HFILL } }, { &hf_cfg_ip6_sac, { "IPv6 stateless address configuration", "mih.ip_cfg_mthds.ip6_state_less", FT_BOOLEAN, 32, NULL, IP_CFG_IP6_SL_MASK, NULL, HFILL } }, { &hf_cfg_dhcp6, { "DHCPv6", "mih.ip_cfg_mthds.dhcp6", FT_BOOLEAN, 32, NULL, IP_CFG_DHCP6_MASK, NULL, HFILL } }, { &hf_cfg_ip6_manual, { "IPv6 manual configuration", "mih.ip_cfg_mthds.ip6_manual", FT_BOOLEAN, 32, NULL, IP_CFG_IP6_MAN_MASK, NULL, HFILL } }, /*header fields for transport lists*/ { &hf_trans_list, { "Supported Transports", "mih.trans_list", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_trans_udp, { "UDP", "mih.trans_list.udp", FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL } }, { &hf_trans_tcp, { "TCP", "mih.trans_list.tcp", FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL } }, /*header fields for device state request*/ { &hf_dev_states_req, { "Device Status Request", "mih.dev_states_req", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_dev_states_req_dev_info, { "Device Info", "mih.dev_states_req.dev_info", FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL } }, { &hf_dev_states_req_batt_lvl, { "Battery Level", "mih.dev_states_req.batt_level", FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL } }, /*header fields for MIH Capabilities*/ { &hf_mihcap, { "Supported MIH Capability", "mih.mihcap", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_mihcap_es, { "Event Service (ES)", "mih.mihcap.event_service", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL } }, { &hf_mihcap_cs, { "Command Service (CS)", "mih.mihcap.command_service", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL } }, { &hf_mihcap_is, { "Information Service (IS)", "mih.mihcap.information_service", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL } }, /*header fields for High Level Network Capabilities*/ { &hf_net_caps, { "High Level Network Capability", "mih.net_caps", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_net_caps_sec, { "Security", "mih.net_caps.sec", FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL } }, { &hf_net_caps_qos0, { "QoS Class 0", "mih.net_caps.qos0", FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL } }, { &hf_net_caps_qos1, { "QoS Class 1", "mih.net_caps.qos1", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL } }, { &hf_net_caps_qos2, { "QoS Class 2", "mih.net_caps.qos2", FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL } }, { &hf_net_caps_qos3, { "QoS Class 3", "mih.net_caps.qos3", FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL } }, { &hf_net_caps_qos4, { "QoS Class 4", "mih.net_caps.qos4", FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL } }, { &hf_net_caps_qos5, { "QoS Class 5", "mih.net_caps.qos5", FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL } }, { &hf_net_caps_ia, { "Internet Access", "mih.net_caps.internet_access", FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL } }, { &hf_net_caps_es, { "Emergency Services", "mih.net_caps.emergency_services", FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL } }, { &hf_net_caps_mihcap, { "MIH Capability", "mih.net_caps.mihcap", FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL } }, /*header fields for Link Action attributes*/ { &hf_link_ac_attr, { "Link Action Attribute", "mih.link_ac_attr", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_link_ac_attr_link_scan, { "Link_Scan", "mih.link_ac_attr.link_scan", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL } }, { &hf_link_ac_attr_link_res_retain, { "Link Resource Retain", "mih.link_ac_attr.link_res_retain", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL } }, { &hf_link_ac_attr_data_fwd_req, { "Forward Data Request", "mih.link_ac_attr.data_fwd_req", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL } } }; /* Setup protocol subtree array */ static int *ett[] = { &ett_mih, &ett_ver_flags, &ett_mid, &ett_tlv, &ett_cmd_bitmap, &ett_event_bitmap, &ett_mob_mgt_bitmap, &ett_cfg_mtd_bitmap, &ett_iq_type_bitmap, &ett_trans_list_bitmap, &ett_dev_states_bitmap, &ett_mihcap_bitmap, &ett_net_caps_bitmap, &ett_ac_attr_bitmap, &ett_subtype_eth_bitmap, &ett_subtype_wireless_other_bitmap, &ett_subtype_ieee80211_bitmap, &ett_subtype_umts_bitmap, &ett_subtype_cdma2000_bitmap, &ett_subtype_ieee80216_bitmap, &ett_min_pk_tx_delay, &ett_avg_pk_tx_delay, &ett_max_pk_tx_delay, &ett_pk_delay_jitter, &ett_pk_loss_rate, &ett_list_prefer_link, &ett_ip_dhcp_server, &ett_fn_agent, &ett_access_router, &ett_link_states_req, &ett_link_desc_req, &ett_dev_states_resp }; proto_mih = proto_register_protocol("Media-Independent Handover", "MIH", "mih"); proto_register_field_array(proto_mih, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); mih_handle = register_dissector("mih", dissect_mih, proto_mih); } /*dissector handoff*/ void proto_reg_handoff_mih(void) { /*Layer 3 handle*/ dissector_add_uint_with_preference("udp.port", MIH_PORT, mih_handle); dissector_add_uint_with_preference("tcp.port", MIH_PORT, mih_handle); /*Layer 2 handle*/ dissector_add_uint("ethertype", ETHERTYPE_MIH, mih_handle); } /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 8 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=8 tabstop=8 expandtab: * :indentSize=8:tabSize=8:noTabs=true: */