static void uadecode(e_ua_direction direction, proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, gint opcode, gint length) { switch (opcode & 0x7f) /* suppression of the CP bit */ { case 0x15: case 0x16: { call_dissector(noe_handle, tvb_new_subset(tvb, offset, length, length), pinfo, tree); break; } case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: /* Only UA NOE */ case 0x08: /* Only UA NOE */ case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x11: case 0x12: case 0x13: case 0x14: case 0x17: case 0x18: case 0x1F: /* case 0x9F */ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: /* Only IP NOE */ case 0x25: /* Only IP NOE */ case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: case 0x2B: /* Only UA NOE */ case 0x2C: case 0x2D: case 0x2E: case 0x30: case 0x31: case 0x32: /* Only UA NOE */ case 0x33: case 0x35: case 0x36: /* IP Phone */ case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F: case 0x50: /* Only UA NOE */ { call_dissector_with_data(ua3g_handle, tvb_new_subset(tvb, offset, length, length), pinfo, tree, &direction); break; } default: { /* add text to the frame "INFO" column */ col_append_str(pinfo->cinfo, COL_INFO, " - UA3G Message ERR: Opcode Unknown"); proto_tree_add_text(tree, tvb, offset, length, "Opcode Unknown 0x%02x", tvb_get_guint8(tvb, (offset + 2))); break; } } }
static void dissect_pw_cesopsn( tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = PWC_PACKET_PROPERTIES_T_INITIALIZER; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC5086: * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN * packet (defined as the size of the CESoPSN header + the payload size) * if it is less than 64 bytes, and MUST be set to zero otherwise. * Note: If fixed RTP header is used in the encapsulation, it is * considered part of the CESoPSN header.] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC5086's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } { guint8 cw_lm; cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/; if (NULL == try_val_to_str(cw_lm, vals_cw_lm)) { properties |= PWC_CW_SUSPECT_LM; } { guint8 l_bit, m_bits; l_bit = (cw_lm & 0x08) >> 3; m_bits = (cw_lm & 0x03) >> 0; if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/ ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ ) { if ((payload_size == 0) || ((payload_size % 8) != 0)) { properties |= PWC_PAY_SIZE_BAD; } } else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/ { /*allow any size of payload*/ } else /*reserved combinations*/ { /*allow any size of payload*/ } } } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } else if (properties & PWC_ANYOF_CW_SUSPECT) { col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, "); } col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } item3 = proto_tree_add_item(tree3, hf_cw_lm, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_SUSPECT_LM) { expert_add_info(pinfo, item3, &ei_cw_lm); } proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be 0 if CESoPSN packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (payload_size == 0) { if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error, "CESoPSN payload: none found. Size of payload must be <> 0"); } else { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded, "CESoPSN payload: omitted to conserve bandwidth"); } } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error, "CESoPSN packet payload size must be multiple of 8"); } tree2 = proto_item_add_subtree(item2, ett); call_dissector(data_handle, tvb, pinfo, tree2); item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
static void dissect_tns_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_tree *tns_tree) { proto_tree *data_tree = NULL, *ti; proto_item *hidden_item; int is_sns = 0; if ( tvb_bytes_exist(tvb, offset+2, 4) ) { if ( tvb_get_guint8(tvb, offset+2) == 0xDE && tvb_get_guint8(tvb, offset+3) == 0xAD && tvb_get_guint8(tvb, offset+4) == 0xBE && tvb_get_guint8(tvb, offset+5) == 0xEF ) { is_sns = 1; } } if ( tree ) { if ( is_sns ) { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Secure Network Services"); } else { ti = proto_tree_add_text(tns_tree, tvb, offset, -1, "Data"); } data_tree = proto_item_add_subtree(ti, ett_tns_data); hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_data, tvb, 0, 0, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); } if ( tree ) { proto_tree *df_tree = NULL; ti = proto_tree_add_item(data_tree, hf_tns_data_flag, tvb, offset, 2, ENC_BIG_ENDIAN); df_tree = proto_item_add_subtree(ti, ett_tns_data_flag); proto_tree_add_item(df_tree, hf_tns_data_flag_send, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_rc, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_c, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_more, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_eof, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_dic, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_rts, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(df_tree, hf_tns_data_flag_sntt, tvb, offset, 2, ENC_BIG_ENDIAN); } offset += 2; if ( check_col(pinfo->cinfo, COL_INFO) ) { if ( is_sns ) { col_append_str(pinfo->cinfo, COL_INFO, ", SNS"); } else { col_append_str(pinfo->cinfo, COL_INFO, ", Data"); } } if ( data_tree ) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, data_tree); } return; }
/* * Dissector that returns: * * The amount of data in the protocol's PDU, if it was able to * dissect all the data; * * 0, if the tvbuff doesn't contain a PDU for that protocol; * * The negative of the amount of additional data needed, if * we need more data (e.g., from subsequent TCP segments) to * dissect the entire PDU. */ static int dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint tvb_size = 0; proto_tree *ccn_tree; proto_item *ti = NULL; const unsigned char *ccnb; struct ccn_skeleton_decoder skel_decoder; struct ccn_skeleton_decoder *sd; struct ccn_charbuf *c; int packet_type = 0; int packet_type_length = 0; /* a couple of basic checks to rule out packets that are definitely not ours */ tvb_size = tvb_length(tvb); if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0) return (0); sd = &skel_decoder; memset(sd, 0, sizeof(*sd)); sd->state |= CCN_DSTATE_PAUSE; ccnb = ep_tvb_memdup(tvb, 0, tvb_size); ccn_skeleton_decode(sd, ccnb, tvb_size); if (sd->state < 0) return (0); if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) { packet_type = sd->numval; packet_type_length = sd->index; } else { return (0); } memset(sd, 0, sizeof(*sd)); ccn_skeleton_decode(sd, ccnb, tvb_size); if (!CCN_FINAL_DSTATE(sd->state)) { pinfo->desegment_offset = 0; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return (-1); /* what should this be? */ } /* Make it visible that we're taking this packet */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN"); } /* Clear out stuff in the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_clear(pinfo->cinfo, COL_INFO); } c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, tvb_size, 1); /* Add the packet type and CCN URI to the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x")); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c)); } if (tree == NULL) { ccn_charbuf_destroy(&c); return (sd->index); } ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1, "Content-centric Networking Protocol, %s, %s", val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"), ccn_charbuf_as_string(c)); ccn_tree = proto_item_add_subtree(ti, ett_ccn); ccn_charbuf_destroy(&c); ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type); switch (packet_type) { case CCN_DTAG_ContentObject: if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; case CCN_DTAG_Interest: if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; } return (sd->index); }
static void dissect_dtp_tlv(packet_info *pinfo, tvbuff_t *tvb, int offset, int length, proto_tree *tree, proto_item *ti, proto_item *tlv_length_item, guint8 type) { switch (type) { case DTP_TLV_DOMAIN: if (length <= 33) { /* VTP domain name is at most 32 bytes long and is null-terminated */ proto_item_append_text(ti, ": %s", tvb_format_text(tvb, offset, length - 1)); proto_tree_add_item(tree, hf_dtp_domain, tvb, offset, length, ENC_ASCII|ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_TRSTATUS: if (length == 1) { /* Value field length must be 1 byte */ proto_item * value_item = NULL; proto_tree * field_tree = NULL; guint8 trunk_status = tvb_get_guint8(tvb, offset); proto_item_append_text(ti, " (Operating/Administrative): %s/%s (0x%02x)", val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"), val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"), trunk_status); value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)", val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"), val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"), trunk_status); field_tree = proto_item_add_subtree(value_item, ett_dtp_status); proto_tree_add_item(field_tree, hf_dtp_tos, tvb, offset, length, ENC_NA); proto_tree_add_item(field_tree, hf_dtp_tas, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_TRTYPE: if (length == 1) { /* Value field length must be 1 byte */ proto_item * value_item = NULL; proto_tree * field_tree = NULL; guint8 trunk_type = tvb_get_guint8(tvb, offset); proto_item_append_text(ti, " (Operating/Administrative): %s/%s (0x%02x)", val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"), val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"), trunk_type); value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)", val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"), val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"), trunk_type); field_tree = proto_item_add_subtree(value_item, ett_dtp_type); proto_tree_add_item(field_tree, hf_dtp_tot, tvb, offset, length, ENC_NA); proto_tree_add_item(field_tree, hf_dtp_tat, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; case DTP_TLV_SENDERID: if (length == 6) { /* Value length must be 6 bytes for a MAC address */ proto_item_append_text(ti, ": %s", tvb_ether_to_str(tvb, offset)); /* XXX - resolve? */ proto_tree_add_item(tree, hf_dtp_senderid, tvb, offset, length, ENC_NA); } else expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid); break; default: proto_tree_add_text(tree, tvb, offset, length, "Data"); break; } }
static void dissect_macctrl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti, *opcode_item; proto_tree *macctrl_tree = NULL; proto_tree *pause_times_tree = NULL; guint16 opcode; guint16 pause_time; int i; col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAC CTRL"); col_clear(pinfo->cinfo, COL_INFO); opcode = tvb_get_ntohs(tvb, 0); ti = proto_tree_add_item(tree, proto_macctrl, tvb, 0, 46, ENC_NA); macctrl_tree = proto_item_add_subtree(ti, ett_macctrl); opcode_item = proto_tree_add_uint(macctrl_tree, hf_macctrl_opcode, tvb, 0, 2, opcode); proto_tree_add_item(macctrl_tree, hf_macctrl_timestamp, tvb, 2, 4, ENC_BIG_ENDIAN); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, opcode_vals, "Unknown")); switch (opcode) { case MACCTRL_PAUSE: if (!addresses_equal(&pinfo->dst, &macctrl_dst_address)) { expert_add_info(pinfo, opcode_item, &ei_macctrl_dst_address); } pause_time = tvb_get_ntohs(tvb, 6); col_append_fstr(pinfo->cinfo, COL_INFO, ": pause_time: %u quanta", pause_time); proto_tree_add_uint(macctrl_tree, hf_macctrl_pause_time, tvb, 6, 2, pause_time); break; case MACCTRL_GATE: break; case MACCTRL_REPORT: break; case MACCTRL_REGISTER_REQ: /* Flags */ proto_tree_add_item(macctrl_tree, hf_reg_flags, tvb, 6, 1, ENC_NA); /* Pending Grants */ proto_tree_add_item(macctrl_tree, hf_reg_req_grants, tvb, 7, 1, ENC_NA); break; case MACCTRL_REGISTER: /* Assigned Port */ proto_tree_add_item(macctrl_tree, hf_reg_port, tvb, 6, 2, ENC_BIG_ENDIAN); /* Flags */ proto_tree_add_item(macctrl_tree, hf_reg_flags, tvb, 8, 1, ENC_NA); /* Synch Time */ proto_tree_add_item(macctrl_tree, hf_reg_time, tvb, 9, 2, ENC_BIG_ENDIAN); /* Echoed Pending Grants */ proto_tree_add_item(macctrl_tree, hf_reg_grants, tvb, 11, 1, ENC_NA); break; case MACCTRL_REGISTER_ACK: /* Flags */ proto_tree_add_item(macctrl_tree, hf_reg_flags, tvb, 6, 1, ENC_NA); /* Echoed Assigned Port */ proto_tree_add_item(macctrl_tree, hf_reg_ack_port, tvb, 7, 2, ENC_BIG_ENDIAN); /* Echoed Synch Time */ proto_tree_add_item(macctrl_tree, hf_reg_ack_time, tvb, 9, 2, ENC_BIG_ENDIAN); break; case MACCTRL_CLASS_BASED_FLOW_CNTRL_PAUSE: if (!addresses_equal(&pinfo->dst, &macctrl_dst_address)) { expert_add_info(pinfo, opcode_item, &ei_macctrl_dst_address); } ti = proto_tree_add_bitmask(macctrl_tree, tvb, 2, hf_macctrl_cbfc_enbv, ett_macctrl_cbfc_enbv, macctrl_cbfc_enbv_list, ENC_BIG_ENDIAN); if (tvb_get_guint8(tvb, 2) != 0) { expert_add_info(pinfo, ti, &ei_macctrl_cbfc_enbv); } pause_times_tree = proto_tree_add_subtree(macctrl_tree, tvb, 4, 8*2, ett_macctrl_cbfc_pause_times, NULL, "CBFC Class Pause Times"); for (i=0; i<8; i++) { proto_tree_add_item(pause_times_tree, *macctrl_cbfc_pause_times_list[i], tvb, 4+i*2, 2, ENC_BIG_ENDIAN); } break; default: expert_add_info(pinfo, opcode_item, &ei_macctrl_opcode); break; } }
/* Code to actually dissect the packets */ static void dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char *szInfo; int offCur = 0; /* current offset from start of WTP data */ gint returned_length, str_index = 0; unsigned char b0; /* continuation flag */ unsigned char fCon; /* Continue flag */ unsigned char fRID; /* Re-transmission indicator*/ unsigned char fTTR = '\0'; /* Transmission trailer */ guint cbHeader = 0; /* Fixed header length */ guint vHeader = 0; /* Variable header length*/ int abortType = 0; /* Set up structures we'll need to add the protocol subtree and manage it */ proto_item *ti = NULL; proto_tree *wtp_tree = NULL; char pdut; char clsTransaction = 3; int numMissing = 0; /* Number of missing packets in a negative ack */ int i; tvbuff_t *wsp_tvb = NULL; guint8 psn = 0; /* Packet sequence number*/ guint16 TID = 0; /* Transaction-Id */ int dataOffset; gint dataLen; #define SZINFO_SIZE 256 szInfo=ep_alloc(SZINFO_SIZE); b0 = tvb_get_guint8 (tvb, offCur + 0); /* Discover Concatenated PDUs */ if (b0 == 0) { guint c_fieldlen = 0; /* Length of length-field */ guint c_pdulen = 0; /* Length of conc. PDU */ if (tree) { ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 1, ENC_NA); wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree); proto_item_append_text(ti, ", PDU concatenation"); } offCur = 1; i = 1; while (offCur < (int) tvb_reported_length(tvb)) { tvbuff_t *wtp_tvb; /* The length of an embedded WTP PDU is coded as either: * - a 7-bit value contained in one octet with highest bit == 0. * - a 15-bit value contained in two octets (little endian) * if the 1st octet has its highest bit == 1. * This means that this is NOT encoded as an uintvar-integer!!! */ b0 = tvb_get_guint8(tvb, offCur + 0); if (b0 & 0x80) { c_fieldlen = 2; c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1); } else { c_fieldlen = 1; c_pdulen = b0; } if (tree) { proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size, tvb, offCur, c_fieldlen, c_pdulen); } if (i > 1) { col_append_str(pinfo->cinfo, COL_INFO, ", "); } /* Skip the length field for the WTP sub-tvb */ wtp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen); dissect_wtp_common(wtp_tvb, pinfo, wtp_tree); offCur += c_fieldlen + c_pdulen; i++; } if (tree) { proto_item_append_text(ti, ", PDU count: %u", i); } return; } /* No concatenation */ fCon = b0 & 0x80; fRID = retransmission_indicator(b0); pdut = pdu_type(b0); #ifdef DEBUG printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n", pinfo->fd->num, tree, val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"), pdut, tvb_length(tvb)); #endif /* Develop the string to put in the Info column */ returned_length = g_snprintf(szInfo, SZINFO_SIZE, "WTP %s", val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x")); str_index += MIN(returned_length, SZINFO_SIZE-str_index); switch (pdut) { case INVOKE: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3)); returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " Class %d", clsTransaction); str_index += MIN(returned_length, SZINFO_SIZE-str_index); cbHeader = 4; break; case SEGMENTED_INVOKE: case SEGMENTED_RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = tvb_get_guint8(tvb, offCur + 3); if (psn != 0) { returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " (%u)", psn); str_index += MIN(returned_length, SZINFO_SIZE-str_index); } cbHeader = 4; break; case ABORT: cbHeader = 4; break; case RESULT: fTTR = transmission_trailer(b0); TID = tvb_get_ntohs(tvb, offCur + 1); psn = 0; cbHeader = 3; break; case ACK: cbHeader = 3; break; case NEGATIVE_ACK: /* Variable number of missing packets */ numMissing = tvb_get_guint8(tvb, offCur + 3); cbHeader = numMissing + 4; break; default: break; }; if (fRID) { returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" ); str_index += MIN(returned_length, SZINFO_SIZE-str_index); }; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); #endif /* NOTE - Length will be set when we process the TPI */ ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA); #ifdef DEBUG fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n"); #endif wtp_tree = proto_item_add_subtree(ti, ett_wtp); /* Code to process the packet goes here */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur); #endif /* Add common items: only CON and PDU Type */ proto_tree_add_item( wtp_tree, /* tree */ hf_wtp_header_flag_continue, /* id */ tvb, offCur, /* start of highlight */ 1, /* length of highlight*/ b0 /* value */ ); proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN); switch(pdut) { case INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Invoke (%u)" ", Transaction Class: %s (%u)", INVOKE, val_to_str(clsTransaction, vals_transaction_classes, "Undefined"), clsTransaction); break; case RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: Result (%u)", RESULT); break; case ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, ", PDU: ACK (%u)", ACK); break; case ABORT: abortType = tvb_get_guint8 (tvb, offCur) & 0x07; proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); if (abortType == PROVIDER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: Provider (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str(reason, vals_abort_reason_provider, "Undefined"), reason); } else if (abortType == USER) { guint8 reason = tvb_get_guint8(tvb, offCur + 3); proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Abort (%u)" ", Type: User (%u)" ", Reason: %s (%u)", ABORT, PROVIDER, val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"), reason); } break; case SEGMENTED_INVOKE: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Invoke (%u)" ", Packet Sequence Number: %u", SEGMENTED_INVOKE, psn); break; case SEGMENTED_RESULT: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", PDU: Segmented Result (%u)" ", Packet Sequence Number: %u", SEGMENTED_RESULT, psn); break; case NEGATIVE_ACK: proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); /* Iterate through missing packets */ for (i = 0; i < numMissing; i++) { proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN); } proto_item_append_text(ti, ", PDU: Negative Ack (%u)" ", Missing Packets: %u", NEGATIVE_ACK, numMissing); break; default: break; }; if (fRID) { proto_item_append_text(ti, ", Retransmission"); } } else { /* tree is NULL */ #ifdef DEBUG fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree); #endif } /* Process the variable part */ if (fCon) { /* Now, analyze variable part */ unsigned char tCon; unsigned char tByte; unsigned char tpiLen; tvbuff_t *tmp_tvb; vHeader = 0; /* Start scan all over */ do { tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader); tCon = tByte & 0x80; if (tByte & 0x04) /* Long TPI */ tpiLen = 2 + tvb_get_guint8(tvb, offCur + cbHeader + vHeader + 1); else tpiLen = 1 + (tByte & 0x03); if (tree) { tmp_tvb = tvb_new_subset(tvb, offCur + cbHeader + vHeader, tpiLen, tpiLen); wtp_handle_tpi(wtp_tree, tmp_tvb); } vHeader += tpiLen; } while (tCon); } else { /* There is no variable part */ } /* End of variable part of header */ /* Set the length of the WTP protocol part now we know the length of the * fixed and variable WTP headers */ if (tree) proto_item_set_len(ti, cbHeader + vHeader); #ifdef DEBUG fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader ); #endif /* * Any remaining data ought to be WSP data (if not WTP ACK, NACK * or ABORT pdu), so, if we have any remaining data, and it's * not an ACK, NACK, or ABORT PDU, hand it off (defragmented) to the * WSP dissector. * Note that the last packet of a fragmented WTP message needn't * contain any data, so we allow payloadless packets to be * reassembled. (XXX - does the reassembly code handle this * for packets other than the last packet?) * * Try calling a subdissector only if: * - The WTP payload is ressembled in this very packet, * - The WTP payload is not fragmented across packets. */ dataOffset = offCur + cbHeader + vHeader; dataLen = tvb_reported_length_remaining(tvb, dataOffset); if ((dataLen >= 0) && ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) { /* Try to reassemble if needed, and hand over to WSP * A fragmented WTP packet is either: * - An INVOKE with fTTR (transmission trailer) not set, * - a SEGMENTED_INVOKE, * - A RESULT with fTTR (transmission trailer) not set, * - a SEGMENTED_RESULT. */ if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) ) ) && tvb_bytes_exist(tvb, dataOffset, dataLen) ) { /* Try reassembling fragments */ fragment_data *fd_wtp = NULL; guint32 reassembled_in = 0; gboolean save_fragmented = pinfo->fragmented; pinfo->fragmented = TRUE; fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID, wtp_fragment_table, psn, dataLen, !fTTR); /* XXX - fragment_add_seq() yields NULL unless Wireshark knows * that the packet is part of a reassembled whole. This means * that fd_wtp will be NULL as long as Wireshark did not encounter * (and process) the packet containing the last fragment. * This implies that Wireshark needs two passes over the data for * correct reassembly. At the first pass, a capture containing * three fragments plus a retransmssion of the last fragment * will progressively show: * * Packet 1: (Unreassembled fragment 1) * Packet 2: (Unreassembled fragment 2) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * However at subsequent evaluation (e.g., by applying a display * filter) the packet summary will show: * * Packet 1: (WTP payload reassembled in packet 3) * Packet 2: (WTP payload reassembled in packet 3) * Packet 3: (Reassembled WTP) * Packet 4: (WTP payload reassembled in packet 3) * * This is important to know, and also affects read filters! */ wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo, "Reassembled WTP", fd_wtp, &wtp_frag_items, NULL, wtp_tree); #ifdef DEBUG printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n", pinfo->fd->num, fd_wtp ? "Reassembled" : "Not reassembled", fd_wtp ? fd_wtp->reassembled_in : -1, wsp_tvb, fd_wtp ); #endif if (fd_wtp) { /* Reassembled */ reassembled_in = fd_wtp->reassembled_in; if (pinfo->fd->num == reassembled_in) { /* Reassembled in this very packet: * We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Not reassembled in this packet */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "%s (WTP payload reassembled in packet %u)", szInfo, fd_wtp->reassembled_in); } if (tree) { proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, "Payload"); } } } else { /* Not reassembled yet, or not reassembled at all */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, "%s (Unreassembled fragment %u)", szInfo, psn); } if (tree) { proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, "Payload"); } } /* Now reset fragmentation information in pinfo */ pinfo->fragmented = save_fragmented; } else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) ) { /* Non-fragmented payload */ wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset); /* We can safely hand the tvb to the WSP dissector */ call_dissector(wsp_handle, wsp_tvb, pinfo, tree); } else { /* Nothing to hand to subdissector */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, szInfo); } } else { /* Nothing to hand to subdissector */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_str(pinfo->cinfo, COL_INFO, szInfo); } }
/* Code to actually dissect the packets */ static void dissect_gvrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *gvrp_tree; guint16 protocol_id; guint8 octet; int msg_index, attr_index, offset = 0, length = tvb_reported_length(tvb); col_set_str(pinfo->cinfo, COL_PROTOCOL, "GVRP"); col_set_str(pinfo->cinfo, COL_INFO, "GVRP"); if (tree) { ti = proto_tree_add_item(tree, proto_gvrp, tvb, 0, length, FALSE); gvrp_tree = proto_item_add_subtree(ti, ett_gvrp); /* Read in GARP protocol ID */ protocol_id = tvb_get_ntohs(tvb, GARP_PROTOCOL_ID); proto_tree_add_uint_format(gvrp_tree, hf_gvrp_proto_id, tvb, GARP_PROTOCOL_ID, sizeof(guint16), protocol_id, "Protocol Identifier: 0x%04x (%s)", protocol_id, protocol_id == GARP_DEFAULT_PROTOCOL_ID ? "GARP VLAN Registration Protocol" : "Unknown Protocol"); /* Currently only one protocol ID is supported */ if (protocol_id != GARP_DEFAULT_PROTOCOL_ID) { proto_tree_add_text(gvrp_tree, tvb, GARP_PROTOCOL_ID, sizeof(guint16), " (Warning: this version of Wireshark only knows about protocol id = 1)"); call_dissector(data_handle, tvb_new_subset(tvb, GARP_PROTOCOL_ID + sizeof(guint16), -1, -1), pinfo, tree); return; } offset += sizeof(guint16); length -= sizeof(guint16); msg_index = 0; /* Begin to parse GARP messages */ while (length) { proto_item *msg_item; int msg_start = offset; /* Read in attribute type. */ octet = tvb_get_guint8(tvb, offset); /* Check for end of mark */ if (octet == GARP_END_OF_MARK) { /* End of GARP PDU */ if (msg_index) { proto_tree_add_text(gvrp_tree, tvb, offset, sizeof(guint8), "End of mark"); break; } else { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); return; } } offset += sizeof(guint8); length -= sizeof(guint8); msg_item = proto_tree_add_text(gvrp_tree, tvb, msg_start, -1, "Message %d", msg_index + 1); proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_type, tvb, msg_start, sizeof(guint8), octet); /* GVRP only supports one attribute type. */ if (octet != GVRP_ATTRIBUTE_TYPE) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); return; } attr_index = 0; while (length) { int attr_start = offset; proto_item *attr_item; /* Read in attribute length. */ octet = tvb_get_guint8(tvb, offset); /* Check for end of mark */ if (octet == GARP_END_OF_MARK) { /* If at least one message has been already read, * check for another end of mark. */ if (attr_index) { proto_tree_add_text(gvrp_tree, tvb, offset, sizeof(guint8), " End of mark"); offset += sizeof(guint8); length -= sizeof(guint8); proto_item_set_len(msg_item, offset - msg_start); break; } else { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); return; } } else { guint8 event; offset += sizeof(guint8); length -= sizeof(guint8); attr_item = proto_tree_add_text(gvrp_tree, tvb, attr_start, -1, " Attribute %d", attr_index + 1); proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_length, tvb, attr_start, sizeof(guint8), octet); /* Read in attribute event */ event = tvb_get_guint8(tvb, offset); proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_event, tvb, offset, sizeof(guint8), event); offset += sizeof(guint8); length -= sizeof(guint8); switch (event) { case GVRP_EVENT_LEAVEALL: if (octet != GVRP_LENGTH_LEAVEALL) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); return; } break; case GVRP_EVENT_JOINEMPTY: case GVRP_EVENT_JOININ: case GVRP_EVENT_LEAVEEMPTY: case GVRP_EVENT_LEAVEIN: case GVRP_EVENT_EMPTY: if (octet != GVRP_LENGTH_NON_LEAVEALL) { call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset),pinfo, tree); return; } /* Show attribute value */ proto_tree_add_item(gvrp_tree, hf_gvrp_attribute_value, tvb, offset, sizeof(guint16), FALSE); offset += sizeof(guint16); length -= sizeof(guint16); break; default: call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree); return; } } proto_item_set_len(attr_item, offset - attr_start); attr_index++; } msg_index++; } } }
static int zebra_route(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len, guint8 family, guint8 version) { guint32 prefix4; guint8 message, prefixlen, buffer6[16]; if (version == 0) { proto_tree_add_item(tree, hf_zebra_type_v0, tvb, offset, 1, ENC_BIG_ENDIAN); } else { proto_tree_add_item(tree, hf_zebra_type_v1, tvb, offset, 1, ENC_BIG_ENDIAN); } offset += 1; proto_tree_add_item(tree, hf_zebra_rtflags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; message = tvb_get_guint8(tvb, offset); offset = zebra_route_message(tree, tvb, offset); if (version > 1) { /* version 2 added safi */ proto_tree_add_item(tree, hf_zebra_route_safi, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } prefixlen = tvb_get_guint8(tvb, offset); proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb, offset, 1, prefixlen); offset += 1; if (family == ZEBRA_FAMILY_IPV6) { memset(buffer6, '\0', sizeof buffer6); tvb_memcpy(tvb, buffer6, offset, MIN((unsigned) PSIZE(prefixlen), sizeof buffer6)); proto_tree_add_ipv6(tree, hf_zebra_prefix6, tvb, offset, PSIZE(prefixlen), (struct e_in6_addr *)buffer6); }else { prefix4 = 0; tvb_memcpy(tvb, (guint8 *)&prefix4, offset, MIN((unsigned) PSIZE(prefixlen), sizeof prefix4)); proto_tree_add_ipv4(tree, hf_zebra_prefix4, tvb, offset, PSIZE(prefixlen), prefix4); } offset += PSIZE(prefixlen); if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) { offset = zebra_route_nexthop(tree, tvb, offset, len); } if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) { offset = zebra_route_ifindex(tree, tvb, offset, len); } if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) { proto_tree_add_item(tree, hf_zebra_distance, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } if (message & ZEBRA_ZAPI_MESSAGE_METRIC) { proto_tree_add_item(tree, hf_zebra_metric, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } return offset; }
static void dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, fcp_conv_data_t *fcp_conv_data) { int offset = 0; int add_len = 0; guint8 flags, rwflags, lun0; guint16 lun = 0xffff; tvbuff_t *cdb_tvb; int tvb_len, tvb_rlen; fcp_request_data_t *request_data = NULL; proto_item *hidden_item; fcp_proto_data_t *proto_data; /* Determine the length of the FCP part of the packet */ flags = tvb_get_guint8(tvb, offset+10); if (flags) { add_len = tvb_get_guint8(tvb, offset+11) & 0x7C; add_len = add_len >> 2; } hidden_item = proto_tree_add_uint(tree, hf_fcp_type, tvb, offset, 0, 0); PROTO_ITEM_SET_HIDDEN(hidden_item); lun0 = tvb_get_guint8(tvb, offset); /* Display single-level LUNs in decimal for clarity */ /* I'm taking a shortcut here by assuming that if the first byte of the * LUN field is 0, it is a single-level LUN. This is not true. For a * real single-level LUN, all 8 bytes except byte 1 must be 0. */ if (lun0) { proto_tree_add_item(tree, hf_fcp_multilun, tvb, offset, 8, ENC_NA); lun = tvb_get_guint8(tvb, offset) & 0x3f; lun <<= 8; lun |= tvb_get_guint8(tvb, offset+1); } else { proto_tree_add_item(tree, hf_fcp_singlelun, tvb, offset+1, 1, ENC_BIG_ENDIAN); lun = tvb_get_guint8(tvb, offset+1); } if (fchdr->itlq) fchdr->itlq->lun = lun; if (!pinfo->fd->flags.visited) { proto_data = se_alloc(sizeof(fcp_proto_data_t)); proto_data->lun = lun; p_add_proto_data(pinfo->fd, proto_fcp, proto_data); } request_data = (fcp_request_data_t*)se_tree_lookup32(fcp_conv_data->luns, lun); if (!request_data) { request_data = se_alloc(sizeof(fcp_request_data_t)); request_data->request_frame = pinfo->fd->num; request_data->response_frame = 0; request_data->request_time = pinfo->fd->abs_ts; request_data->itl = se_alloc(sizeof(itl_nexus_t)); request_data->itl->cmdset = 0xff; request_data->itl->conversation = conversation; se_tree_insert32(fcp_conv_data->luns, lun, request_data); } proto_tree_add_item(tree, hf_fcp_crn, tvb, offset+8, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_taskattr, tvb, offset+9, 1, ENC_BIG_ENDIAN); dissect_task_mgmt_flags(pinfo, tree, tvb, offset+10); proto_tree_add_item(tree, hf_fcp_addlcdblen, tvb, offset+11, 1, ENC_BIG_ENDIAN); rwflags = tvb_get_guint8(tvb, offset+11); if (fchdr->itlq) { if (rwflags & 0x02) { fchdr->itlq->task_flags |= SCSI_DATA_READ; } if (rwflags & 0x01) { fchdr->itlq->task_flags |= SCSI_DATA_WRITE; } } proto_tree_add_item(tree, hf_fcp_rddata, tvb, offset+11, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_wrdata, tvb, offset+11, 1, ENC_BIG_ENDIAN); tvb_len = tvb_length_remaining(tvb, offset+12); if (tvb_len > (16 + add_len)) tvb_len = 16 + add_len; tvb_rlen = tvb_reported_length_remaining(tvb, offset+12); if (tvb_rlen > (16 + add_len)) tvb_rlen = 16 + add_len; cdb_tvb = tvb_new_subset(tvb, offset+12, tvb_len, tvb_rlen); dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, fchdr->itlq, request_data->itl); proto_tree_add_item(tree, hf_fcp_dl, tvb, offset+12+16+add_len, 4, ENC_BIG_ENDIAN); if (fchdr->itlq) { fchdr->itlq->data_length = tvb_get_ntohl(tvb, offset+12+16+add_len); } if ( ((rwflags & 0x03) == 0x03) && tvb_length_remaining(tvb, offset+12+16+add_len+4) >= 4) { proto_tree_add_item(tree, hf_fcp_bidir_dl, tvb, offset+12+16+add_len+4, 4, ENC_BIG_ENDIAN); if (fchdr->itlq) { fchdr->itlq->bidir_data_length = tvb_get_ntohl(tvb, offset+12+16+add_len+4); } } }
static void dissect_dmx_sip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX SIP"); col_clear(pinfo->cinfo, COL_INFO); if (tree != NULL) { guint offset = 0; guint byte_count; guint checksum, checksum_shouldbe; proto_item *item; proto_tree *checksum_tree; proto_tree *ti = proto_tree_add_item(tree, proto_dmx_sip, tvb, offset, -1, ENC_NA); proto_tree *dmx_sip_tree = proto_item_add_subtree(ti, ett_dmx_sip); byte_count = tvb_get_guint8(tvb, offset); proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_byte_count, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_control_bit_field, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_prev_packet_checksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_seq_nr, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_universe_nr, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_proc_level, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_software_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_packet_len, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_nr_packets, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_orig_dev_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_sec_dev_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_third_dev_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_fourth_dev_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_fifth_dev_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (offset < byte_count) { proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_reserved, tvb, offset, byte_count - offset, ENC_NA); offset += (byte_count - offset); } dmx_sip_checksum(tvb, offset); checksum_shouldbe = dmx_sip_checksum(tvb, offset); checksum = tvb_get_guint8(tvb, offset); item = proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_checksum, tvb, offset, 1, ENC_BIG_ENDIAN); if (checksum == checksum_shouldbe) { proto_item_append_text(item, " [correct]"); checksum_tree = proto_item_add_subtree(item, ett_dmx_sip); item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_good, tvb, offset, 1, TRUE); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_bad, tvb, offset, 1, FALSE); PROTO_ITEM_SET_GENERATED(item); } else { proto_item_append_text(item, " [incorrect, should be 0x%02x]", checksum_shouldbe); checksum_tree = proto_item_add_subtree(item, ett_dmx_sip); item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_good, tvb, offset, 1, FALSE); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_bad, tvb, offset, 1, TRUE); PROTO_ITEM_SET_GENERATED(item); } offset += 1; if (offset < tvb_captured_length(tvb)) proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_trailer, tvb, offset, -1, ENC_NA); } }
static void dissect_rsp_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset) { proto_item *item = NULL; proto_tree *tree = NULL; gboolean bidi_resid_present = FALSE; guint8 flags; if (parent_tree) { item = proto_tree_add_item(parent_tree, hf_fcp_rspflags, tvb, offset, 1, ENC_LITTLE_ENDIAN); tree = proto_item_add_subtree(item, ett_fcp_rsp_flags); } flags = tvb_get_guint8(tvb, offset); if (!flags) proto_item_append_text(item, " (No values set)"); /* BIDI RSP */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi, tvb, offset, 1, flags); if (flags & 0x80) { bidi_resid_present = TRUE; proto_item_append_text(item, " BIDI_RSP"); if (flags & (~( 0x80 ))) proto_item_append_text(item, ","); } flags &= (~( 0x80 )); /* these two bits are only defined if the bidi bit is set */ if (bidi_resid_present) { /* BIDI READ RESID UNDER */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi_rru, tvb, offset, 1, flags); if (flags & 0x40) { proto_item_append_text(item, " BIDI_RRU"); if (flags & (~( 0x40 ))) proto_item_append_text(item, ","); } flags &= (~( 0x40 )); /* BIDI READ RESID OVER */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi_rro, tvb, offset, 1, flags); if (flags & 0x20) { proto_item_append_text(item, " BIDI_RRO"); if (flags & (~( 0x20 ))) proto_item_append_text(item, ","); } flags &= (~( 0x20 )); } /* Conf Req */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_conf_req, tvb, offset, 1, flags); if (flags & 0x10) { proto_item_append_text(item, " CONF REQ"); if (flags & (~( 0x10 ))) proto_item_append_text(item, ","); } flags &= (~( 0x10 )); /* Resid Under */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_resid_under, tvb, offset, 1, flags); if (flags & 0x08) { proto_item_append_text(item, " RESID UNDER"); if (flags & (~( 0x08 ))) proto_item_append_text(item, ","); } flags &= (~( 0x08 )); /* Resid Over */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_resid_over, tvb, offset, 1, flags); if (flags & 0x04) { proto_item_append_text(item, " RESID OVER"); if (flags & (~( 0x04 ))) proto_item_append_text(item, ","); } flags &= (~( 0x04 )); /* SNS len valid */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_sns_vld, tvb, offset, 1, flags); if (flags & 0x02) { proto_item_append_text(item, " SNS VLD"); if (flags & (~( 0x02 ))) proto_item_append_text(item, ","); } flags &= (~( 0x02 )); /* rsp len valid */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_res_vld, tvb, offset, 1, flags); if (flags & 0x01) { proto_item_append_text(item, " RES VLD"); if (flags & (~( 0x01 ))) proto_item_append_text(item, ","); } flags &= (~( 0x01 )); if (flags) { proto_item_append_text(item, " Unknown bitmap value 0x%x", flags); } }
static void dissect_task_mgmt_flags(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset) { proto_item *item = NULL; proto_tree *tree = NULL; guint8 flags; if (parent_tree) { item = proto_tree_add_item(parent_tree, hf_fcp_taskmgmt, tvb, offset, 1, ENC_LITTLE_ENDIAN); tree = proto_item_add_subtree(item, ett_fcp_taskmgmt); } flags = tvb_get_guint8(tvb, offset); if (!flags) proto_item_append_text(item, " (No values set)"); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_obsolete, tvb, offset, 1, flags); if (flags & 0x80) { proto_item_append_text(item, " OBSOLETE"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP OBSOLETE] "); } flags &= (~( 0x80 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_clear_aca, tvb, offset, 1, flags); if (flags & 0x40) { proto_item_append_text(item, " CLEAR ACA"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP CLEAR_ACA] "); } flags &= (~( 0x40 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_target_reset, tvb, offset, 1, flags); if (flags & 0x20) { proto_item_append_text(item, " TARGET RESET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP TARGET_RESET] "); } flags &= (~( 0x20 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_lu_reset, tvb, offset, 1, flags); if (flags & 0x10) { proto_item_append_text(item, " LU RESET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP LU_RESET] "); } flags &= (~( 0x10 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_rsvd, tvb, offset, 1, flags); if (flags & 0x08) { proto_item_append_text(item, " RSVD"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP RSVD] "); } flags &= (~( 0x08 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_clear_task_set, tvb, offset, 1, flags); if (flags & 0x04) { proto_item_append_text(item, " CLEAR TASK SET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP CLEAR_TASK_SET] "); } flags &= (~( 0x04 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_abort_task_set, tvb, offset, 1, flags); if (flags & 0x02) { proto_item_append_text(item, " ABORT TASK SET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP ABORT_TASK_SET] "); } flags &= (~( 0x02 )); if (flags) { proto_item_append_text(item, " Unknown bitmap value 0x%x", flags); } }
/* UCD dissector */ void dissect_mac_mgmt_msg_ucd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len, payload_type, length; guint ucd_config_change_count; guint ucd_ranging_backoff_start; guint ucd_ranging_backoff_end; guint ucd_request_backoff_start; guint ucd_request_backoff_end; gint tlv_type, tlv_len, tlv_offset, tlv_value_offset; guint ul_burst_uiuc, utemp; proto_item *ucd_item = NULL; proto_tree *ucd_tree = NULL; proto_item *tlv_item = NULL; proto_tree *tlv_tree = NULL; proto_tree *sub_tree = NULL; tlv_info_t tlv_info; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_UCD) { return; } if(tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type UCD */ ucd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tvb_len, "Uplink Channel Descriptor (UCD) (%u bytes)", tvb_len); /* add MAC UCD subtree */ ucd_tree = proto_item_add_subtree(ucd_item, ett_mac_mgmt_msg_ucd_decoder); /* Decode and display the Uplink Channel Descriptor (UCD) */ /* display the Message Type */ proto_tree_add_item(ucd_tree, hf_ucd_message_type, tvb, offset, 1, FALSE); /* move to next field */ offset++; /* get the Configuration Change Count */ ucd_config_change_count = tvb_get_guint8(tvb, offset); /* display the Configuration Change Count */ proto_tree_add_text(ucd_tree, tvb, offset, 1, "Configuration Change Count: %u", ucd_config_change_count); /* move to next field */ offset++; /* get the ranging backoff start */ ucd_ranging_backoff_start = tvb_get_guint8(tvb, offset); /* display the ranging backoff start */ proto_tree_add_text(ucd_tree, tvb, offset, 1, "Ranging Backoff Start: 2^%u = %u", ucd_ranging_backoff_start, (1 << ucd_ranging_backoff_start)); /* move to next field */ offset++; /* get the ranging backoff end */ ucd_ranging_backoff_end = tvb_get_guint8(tvb, offset); /* display the ranging backoff end */ proto_tree_add_text(ucd_tree, tvb, offset, 1, "Ranging Backoff End: 2^%u = %u", ucd_ranging_backoff_end, (1 << ucd_ranging_backoff_end)); /* move to next field */ offset++; /* get the request backoff start */ ucd_request_backoff_start = tvb_get_guint8(tvb, offset); /* display the request backoff start */ proto_tree_add_text(ucd_tree, tvb, offset, 1, "Request Backoff Start: 2^%u = %u", ucd_request_backoff_start, (1 << ucd_request_backoff_start)); /* move to next field */ offset++; /* get the request backoff end */ ucd_request_backoff_end = tvb_get_guint8(tvb, offset); /* display the request backoff end */ proto_tree_add_text(ucd_tree, tvb, offset, 1, "Request Backoff End: 2^%u = %u", ucd_request_backoff_end, (1 << ucd_request_backoff_end)); /* move to next field */ offset++; while(offset < tvb_len) { /* get the TLV information */ 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 */ if(check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "UCD TLV error"); } proto_tree_add_item(ucd_tree,hf_ucd_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the TLV value offset */ tlv_value_offset = get_tlv_value_offset(&tlv_info); #ifdef DEBUG /* for debug only */ tlv_item = proto_tree_add_protocol_format(ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, (tlv_len + tlv_value_offset), "UCD Type: %u (%u bytes, offset=%u, tvb_len=%u)", tlv_type, tlv_len, offset, tvb_len); #endif /* update the offset */ offset += tlv_value_offset; /* process UCD TLV Encoded information */ if (include_cor2_changes) { switch (tlv_type) { case UCD_TLV_T_203_UL_PUSC_SUBCHANNEL_ROTATION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_203_ul_pusc_subchannel_rotation, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_203_ul_pusc_subchannel_rotation, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_205_RELATIVE_POWER_OFFSET_UL_HARQ_BURST: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_205_relative_power_offset_ul_harq_burst, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_205_relative_power_offset_ul_harq_burst, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_206_RELATIVE_POWER_OFFSET_UL_BURST_CONTAINING_MAC_MGMT_MSG: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_206_relative_power_offset_ul_burst_containing_mac_mgmt_msg, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_206_relative_power_offset_ul_burst_containing_mac_mgmt_msg, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_207_UL_INITIAL_TRANSMIT_TIMING: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_207_ul_initial_transmit_timing, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_207_ul_initial_transmit_timing, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_210_FAST_FEEDBACK_REGION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_210_fast_feedback_region, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_210_fast_feedback_region, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_211_HARQ_ACK_REGION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_211_harq_ack_region, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_211_harq_ack_region, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_212_RANGING_REGION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_212_ranging_region, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_212_ranging_region, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_213_SOUNDING_REGION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_213_sounding_region, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_213_sounding_region, tvb, offset, tlv_len, FALSE); break; } } } switch (tlv_type) { case UCD_UPLINK_BURST_PROFILE: { /* get the UIUC */ ul_burst_uiuc = tvb_get_guint8(tvb, offset) & 0x0F; /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Uplink Burst Profile (UIUC = %u) (%u bytes)", ul_burst_uiuc, tlv_len); proto_tree_add_item(tlv_tree, hf_ucd_ul_burst_reserved, tvb, offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_ul_burst_uiuc, tvb, offset, 1, FALSE); for (tlv_offset = 1; tlv_offset < tlv_len;) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, (offset+tlv_offset)); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); if(tlv_type == -1) { /* invalid tlv info */ if(check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "UL Burst Profile error"); } proto_tree_add_item(tlv_tree, hf_ucd_invalid_tlv, tvb, offset, (tlv_len - offset - tlv_offset), FALSE); break; } /* get the TLV length */ length = get_tlv_length(&tlv_info); /* update the offset */ tlv_offset += get_tlv_value_offset(&tlv_info); switch (tlv_type) { case UCD_BURST_FEC: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, tlv_tree, hf_ucd_burst_fec, tvb, (offset+tlv_offset), 1, FALSE); tlv_item = proto_tree_add_item(sub_tree, hf_ucd_burst_fec, tvb, (offset+tlv_offset), 1, FALSE); break; } case UCD_BURST_RANGING_DATA_RATIO: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, tlv_tree, hf_ucd_burst_ranging_data_ratio, tvb, (offset+tlv_offset), 1, FALSE); tlv_item = proto_tree_add_item(sub_tree, hf_ucd_burst_ranging_data_ratio, tvb, (offset+tlv_offset), 1, FALSE); proto_item_append_text(tlv_item, " dB"); break; } #if 0 /* for OFDM */ case UCD_BURST_POWER_BOOST: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, tlv_tree, hf_ucd_burst_power_boost, tvb, (offset+tlv_offset), 1, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_burst_power_boost, tvb, (offset+tlv_offset), length, FALSE); proto_item_append_text(tlv_item, " dB"); break; } case UCD_BURST_TCS_ENABLE: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, tlv_tree, hf_ucd_burst_tcs_enable, tvb, (offset+tlv_offset), 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_burst_tcs_enable, tvb, (offset+tlv_offset), 1, FALSE); break; } #endif default: /* ??? */ break; } tlv_offset += length; } break; } case UCD_RESERVATION_TIMEOUT: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_res_timeout, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_res_timeout, tvb, offset, tlv_len, FALSE); break; } case UCD_BW_REQ_SIZE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_bw_req_size, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_bw_req_size, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " PS"); break; } case UCD_RANGING_REQ_SIZE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_ranging_req_size, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_ranging_req_size, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " PS"); break; } case UCD_FREQUENCY: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_freq, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_freq, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " kHz"); break; } case UCD_TLV_T_7_HO_RANGING_START: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "HO ranging start (SCa, OFDM, OFDMA (mobile only)) (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Initial Backoff Window Size for MS Performing Initial During Handover Process: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_8_RANGING_HO_END: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "HO ranging end (SCa, OFDM, OFDMA (mobile only)) (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Final Backoff Window Size for MS Performing Initial During Handover Process: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_158_OPTIONAL_PERMUTATION_UL_ALLOCATED_SUBCHANNELS_BITMAP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_158_optional_permutation_ul_allocated_subchannels_bitmap, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_158_optional_permutation_ul_allocated_subchannels_bitmap, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_159_BAND_AMC_ALLOCATION_THRESHHOLD: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_159_band_amc_allocation_threshold, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_159_band_amc_allocation_threshold, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " dB"); break; } case UCD_TLV_T_160_BAND_AMC_RELEASE_THRESHOLD: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_160_band_amc_release_threshold, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_160_band_amc_release_threshold, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " dB"); break; } case UCD_TLV_T_161_BAND_AMC_ALLOCATION_TIMER: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_161_band_amc_allocation_timer, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_161_band_amc_allocation_timer, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_162_BAND_AMC_RELEASE_TIMER: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_161_band_amc_allocation_timer, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_162_band_amc_release_timer, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_163_BAND_STATUS_REPORT_MAX_PERIOD: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_163_band_status_report_max_period, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_163_band_status_report_max_period, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_164_BAND_AMC_RETRY_TIMER: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_164_band_amc_retry_timer, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_164_band_amc_retry_timer, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_170_SAFETY_CHANNEL_RETRY_TIMER: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_170_safety_channel_retry_timer, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_170_safety_channel_retry_timer, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_171_HARQ_ACK_DELAY_FOR_DL_BURST: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_171_harq_ack_delay_dl_burst, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_171_harq_ack_delay_dl_burst, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames offset"); break; } case UCD_TLV_T_172_CQICH_BAND_AMC_TRANSITION_DELAY: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_172_cqich_band_amc_transition_delay, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_172_cqich_band_amc_transition_delay, tvb, offset, tlv_len, FALSE); proto_item_append_text(tlv_item, " frames"); break; } case UCD_TLV_T_174_MAXIMUM_RETRANSMISSION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_174_maximum_retransmission, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_174_maximum_retransmission, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_176_SIZE_OF_CQICH_ID_FIELD: { utemp = tvb_get_guint8(tvb, offset); cqich_id_size = 0; /* Default is 0 */ if (utemp && utemp < 8) { /* Set for CQICH_Alloc_IE */ cqich_id_size = utemp + 2; } tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_176_size_of_cqich_id_field, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_176_size_of_cqich_id_field, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_177_NORMALIZED_CN_OVERRIDE_2: { /* add TLV subtree */ tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_177_normalized_cn_override2, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_177_normalized_cn_override2_first_line, tvb, offset + 2, 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_177_normalized_cn_override2_list, tvb, offset + 3, 7, FALSE); break; } case UCD_TLV_T_186_UPPER_BOUND__AAS_PREAMBLE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_186_upper_bound_aas_preamble, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_186_upper_bound_aas_preamble, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_187_LOWER_BOUND_AAS_PREAMBLE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_187_lower_bound_aas_preamble, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_187_lower_bound_aas_preamble, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_188_ALLOW_AAS_BEAM_SELECT_MESSAGE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_188_allow_aas_beam_select_message, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_188_allow_aas_beam_select_message, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_189_USE_CQICH_INDICATION_FLAG: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_189_use_cqich_indication_flag, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_189_use_cqich_indication_flag, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_190_MS_SPECIFIC_UP_POWER_OFFSET_ADJUSTMENT_STEP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_190_ms_specific_up_power_addjustment_step, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_190_ms_specific_up_power_addjustment_step, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_191_MS_SPECIFIC_DOWN_POWER_OFSET_ADJUSTMENT_STEP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_191_ms_specific_down_power_addjustment_step, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_191_ms_specific_down_power_addjustment_step, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_192_MIN_LEVEL_POWER_OFFSET_ADJUSTMENT: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_192_min_level_power_offset_adjustment, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_192_min_level_power_offset_adjustment, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_193_MAX_LEVEL_POWER_OFFSETR_ADJUSTMENT: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_193_max_level_power_offset_adjustment, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_193_max_level_power_offset_adjustment, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_194_HANDOVER_RANGING_CODES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_194_handover_ranging_codes, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_194_handover_ranging_codes, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_195_INITIAL_RANGING_INTERVAL: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_195_initial_ranging_interval, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_195_initial_ranging_interval, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_196_TX_POWER_REPORT: { /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Tx Power Report (%u bytes)", tlv_len); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_threshold, tvb, offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_interval, tvb , offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_a_p_avg, tvb, (offset + 1), 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_threshold_icqch, tvb, (offset + 1), 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_interval_icqch, tvb, (offset + 2), 1, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_a_p_avg_icqch, tvb, (offset + 2), 1, FALSE); break; } case UCD_TLV_T_197_NORMALIZED_CN_FOR_CHANNEL_SOUNDING: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_195_initial_ranging_interval, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_197_normalized_cn_channel_sounding, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_198_INTIAL_RANGING_BACKOFF_START: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Initial ranging backoff start (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Initial Ranging Backoff Start: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_199_INITIAL_RANGING_BACKOFF_END: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Initial ranging backoff end (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Initial Ranging Backoff End: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_200_BANDWIDTH_REQUESET_BACKOFF_START: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Bandwidth request backoff start (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Bandwidth Request Backoff Start: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_201_BANDWIDTH_REQUEST_BACKOFF_END: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Bandwidth request backoff end (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tvb_len, "Bandwidth Request Backoff End: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_202_UPLINK_BURST_PROFILE_FOR_MULTIPLE_FEC_TYPES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_202_uplink_burst_profile_for_multiple_fec_types, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_202_uplink_burst_profile_for_multiple_fec_types, tvb, offset, tlv_len, FALSE); break; } case UCD_INITIAL_RANGING_CODES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_150_initial_ranging_codes, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree,hf_ucd_tlv_t_150_initial_ranging_codes, tvb, offset, tlv_len, FALSE); break; } case UCD_PERIODIC_RANGING_CODES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_151_periodic_ranging_codes, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree,hf_ucd_tlv_t_151_periodic_ranging_codes, tvb, offset, tlv_len, FALSE); break; } case UCD_BANDWIDTH_REQUEST_CODES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_152_bandwidth_request_codes, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree,hf_ucd_tlv_t_152_bandwidth_request_codes, tvb, offset, tlv_len, FALSE); break; } case UCD_PERIODIC_RANGING_BACKOFF_START: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Periodic ranging backoff start (%u byte(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tlv_len, "Periodic Ranging Backoff Start: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_PERIODIC_RANGING_BACKOFF_END: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Periodic ranging backoff end (%u bytes(s))", tlv_len); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_text(tlv_tree, tvb, offset, tlv_len, "Periodic Ranging Backoff End: 2^%u = %u", utemp, (1 << utemp)); break; } case UCD_START_OF_RANGING_CODES_GROUP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_155_start_of_ranging_codes_group, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree,hf_ucd_tlv_t_155_start_of_ranging_codes_group, tvb, offset, tlv_len, FALSE); break; } case UCD_PERMUTATION_BASE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_tlv_t_156_permutation_base, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree,hf_ucd_tlv_t_156_permutation_base, tvb, offset, tlv_len, FALSE); break; } case UCD_UL_ALLOCATED_SUBCHANNELS_BITMAP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, hf_ucd_ul_allocated_subchannles_bitmap, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_ucd_ul_allocated_subchannles_bitmap, tvb, offset, tlv_len, FALSE); break; } case UCD_TLV_T_203_UL_PUSC_SUBCHANNEL_ROTATION: case UCD_TLV_T_205_RELATIVE_POWER_OFFSET_UL_HARQ_BURST: case UCD_TLV_T_206_RELATIVE_POWER_OFFSET_UL_BURST_CONTAINING_MAC_MGMT_MSG: case UCD_TLV_T_207_UL_INITIAL_TRANSMIT_TIMING: case UCD_TLV_T_210_FAST_FEEDBACK_REGION: case UCD_TLV_T_211_HARQ_ACK_REGION: case UCD_TLV_T_212_RANGING_REGION: case UCD_TLV_T_213_SOUNDING_REGION: { /* Unknown TLV type if cor2 not enabled. */ if (!include_cor2_changes) { proto_tree_add_protocol_format(ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Unknown TLV Type"); } break; } default: { proto_tree_add_protocol_format(ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, tlv_len, "Unknown TLV Type"); } } /* end of switch */ offset += tlv_len; } /* end of TLV process while loop */ } }
} } } static int dissect_djiuav_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { proto_item *ti; proto_tree *djiuav_tree = NULL; guint32 offset = 0; guint32 pdu_length; guint8 packet_type; gboolean is_cmd; is_cmd = (pinfo->match_uint == pinfo->destport); packet_type = tvb_get_guint8(tvb, 6); col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME); col_add_str(pinfo->cinfo, COL_INFO, is_cmd?"C: ":"R: "); col_append_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, djiuav_pdu_type, "Type 0x%02x")); ti = proto_tree_add_item(tree, proto_djiuav, tvb, offset, -1, ENC_NA); djiuav_tree = proto_item_add_subtree(ti, ett_djiuav); request_response_handling(tvb, pinfo, djiuav_tree, offset); if (tree) { proto_tree_add_item(djiuav_tree, hf_djiuav_magic, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
/* Initialize the subtree pointers */ static gint ett_docsis_bpkmreq = -1; static dissector_handle_t attrs_handle; /* Dissection */ static int dissect_bpkmreq (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_) { proto_item *it; proto_tree *bpkmreq_tree; guint8 code; tvbuff_t *attrs_tvb; code = tvb_get_guint8 (tvb, 0); col_add_fstr (pinfo->cinfo, COL_INFO, "BPKM Request (%s)", val_to_str (code, code_field_vals, "%d")); if (tree) { it = proto_tree_add_protocol_format (tree, proto_docsis_bpkmreq, tvb, 0, -1, "BPKM Request Message"); bpkmreq_tree = proto_item_add_subtree (it, ett_docsis_bpkmreq); proto_tree_add_item (bpkmreq_tree, hf_docsis_bpkmreq_code, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item (bpkmreq_tree, hf_docsis_bpkmreq_ident, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item (bpkmreq_tree, hf_docsis_bpkmreq_length, tvb, 2, 2,
static void request_response_handling(tvbuff_t *tvb, packet_info *pinfo, proto_tree *djiuav_tree, guint32 offset) { conversation_t *conversation; djiuav_conv_info_t *djiuav_info; djiuav_transaction_t *djiuav_trans; guint16 seq_no; gboolean is_cmd; guint8 packet_type; is_cmd = (pinfo->match_uint == pinfo->destport); seq_no = tvb_get_letohs(tvb, offset + 4); packet_type = tvb_get_guint8(tvb, offset + 6); conversation = find_or_create_conversation(pinfo); djiuav_info = (djiuav_conv_info_t *)conversation_get_proto_data(conversation, proto_djiuav); if (!djiuav_info) { djiuav_info = wmem_new(wmem_file_scope(), djiuav_conv_info_t); djiuav_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_djiuav, djiuav_info); } if (!pinfo->fd->flags.visited) { if (is_cmd) { djiuav_trans=wmem_new(wmem_file_scope(), djiuav_transaction_t); djiuav_trans->request_frame=pinfo->fd->num; djiuav_trans->reply_frame=0; djiuav_trans->request_time=pinfo->fd->abs_ts; djiuav_trans->seqno=seq_no; djiuav_trans->command=packet_type; wmem_map_insert(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no), (void *)djiuav_trans); } else { djiuav_trans=(djiuav_transaction_t *)wmem_map_lookup(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no)); if (djiuav_trans) { /* Special case: djiuav seems to send 0x24 replies with seqno 0 and without a request */ if (djiuav_trans->reply_frame == 0) djiuav_trans->reply_frame=pinfo->fd->num; } } } else { djiuav_trans=(djiuav_transaction_t *)wmem_map_lookup(djiuav_info->pdus, GUINT_TO_POINTER((guint)seq_no)); } /* djiuav_trans may be 0 in case it's a reply without a matching request */ if (djiuav_tree && djiuav_trans) { if (is_cmd) { if (djiuav_trans->reply_frame) { proto_item *it; it = proto_tree_add_uint(djiuav_tree, hf_djiuav_response_in, tvb, 0, 0, djiuav_trans->reply_frame); PROTO_ITEM_SET_GENERATED(it); } } else { if (djiuav_trans->request_frame) { proto_item *it; nstime_t ns; it = proto_tree_add_uint(djiuav_tree, hf_djiuav_response_to, tvb, 0, 0, djiuav_trans->request_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &djiuav_trans->request_time); it = proto_tree_add_time(djiuav_tree, hf_djiuav_response_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } } }
static int hf_wow_realm_num_characters = -1; static int hf_wow_realm_timezone = -1; static gboolean wow_preference_desegment = TRUE; static gint ett_wow = -1; static gint ett_wow_realms = -1; static guint get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data _U_) { gint8 size_field_offset = -1; guint8 cmd; guint16 pkt_len; cmd = tvb_get_guint8(tvb, offset); if(WOW_SERVER_TO_CLIENT && cmd == REALM_LIST) size_field_offset = 1; if(WOW_CLIENT_TO_SERVER && cmd == AUTH_LOGON_CHALLENGE) size_field_offset = 2; pkt_len = tvb_get_letohs(tvb, size_field_offset); return pkt_len + size_field_offset + 2; } static int dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
static int dissect_btsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { int offset = 0; proto_item *ti; proto_tree *st; guint8 opcode; guint32 interface_id; guint32 adapter_id; gint previous_proto; interface_id = HCI_INTERFACE_DEFAULT; adapter_id = HCI_ADAPTER_DEFAULT; previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers))))); if (data && previous_proto == proto_btl2cap) { btl2cap_data_t *l2cap_data; l2cap_data = (btl2cap_data_t *) data; if (l2cap_data) { interface_id = l2cap_data->interface_id; adapter_id = l2cap_data->adapter_id; } } ti = proto_tree_add_item(tree, proto_btsmp, tvb, 0, tvb_captured_length(tvb), ENC_NA); st = proto_item_add_subtree(ti, ett_btsmp); col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMP"); switch (pinfo->p2p_dir) { case P2P_DIR_SENT: col_set_str(pinfo->cinfo, COL_INFO, "Sent "); break; case P2P_DIR_RECV: col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); break; default: col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection "); break; } if (tvb_reported_length(tvb) < 1) return FALSE; proto_tree_add_item(st, hf_btsmp_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN); opcode = tvb_get_guint8(tvb, 0); offset++; col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(opcode, opcode_vals, "<unknown>")); switch (opcode) { case 0x01: /* Pairing Request */ case 0x02: /* Pairing Response */ { col_append_str(pinfo->cinfo, COL_INFO, ": "); proto_tree_add_item(st, hf_btsmp_io_capabilities, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(st, hf_btsmp_oob_data_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st); proto_tree_add_item(st, hf_btsmp_max_enc_key_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, TRUE); offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, FALSE); break; } case 0x03: /* Pairing Confirm */ proto_tree_add_item(st, hf_btsmp_cfm_value, tvb, offset, 16, ENC_NA); offset += 16; break; case 0x04: /* Pairing Random */ proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 16, ENC_NA); offset += 16; break; case 0x05: /* Pairing Failed */ proto_tree_add_item(st, hf_btsmp_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(tvb_get_guint8(tvb, offset), reason_vals, "<unknown>")); offset++; break; case 0x06: /* Encryption Information */ proto_tree_add_item(st, hf_btsmp_long_term_key, tvb, offset, 16, ENC_NA); offset += 16; break; case 0x07: /* Master Identification */ proto_tree_add_item(st, hf_btsmp_ediv, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 8, ENC_NA); offset += 8; break; case 0x08: /* Identity Information */ proto_tree_add_item(st, hf_btsmp_id_resolving_key, tvb, offset, 16, ENC_NA); offset += 16; break; case 0x09: /* Identity Address Information */ proto_tree_add_item(st, hf_address_type, tvb, offset, 1, ENC_NA); offset += 1; offset = dissect_bd_addr(hf_bd_addr, pinfo, st, tvb, offset, FALSE, interface_id, adapter_id, NULL); break; case 0x0a: /* Signing Information */ proto_tree_add_item(st, hf_btsmp_signature_key, tvb, offset, 16, ENC_NA); offset += 16; break; case 0x0b: /* Security Request */ col_append_str(pinfo->cinfo, COL_INFO, ": "); offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st); break; default: break; } return offset; }
/* dissect a UHD header and hand payload off to respective dissector */ static void dissect_uhd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int ind; proto_item *ti; proto_tree *uhd_tree; guint32 id; guint8 i2c_bytes; col_set_str(pinfo->cinfo, COL_PROTOCOL, "UHD"); col_clear(pinfo->cinfo, COL_INFO); id = tvb_get_ntohl(tvb, 4); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(id, uhd_ids, "Unknown UHD message type '%c'")); if (tree == NULL) return; ti = proto_tree_add_protocol_format(tree, proto_uhd, tvb, 0, 34, "UHD id = %c ", id); uhd_tree = proto_item_add_subtree(ti, ett_uhd); proto_tree_add_item(uhd_tree, hf_uhd_version, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_id, tvb, 4, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_seq, tvb, 8, 4, ENC_BIG_ENDIAN); switch (id) { case UMTRX_CTRL_ID_REQUEST: case UMTRX_CTRL_ID_RESPONSE: case USRP2_CTRL_ID_WAZZUP_BRO: case USRP2_CTRL_ID_WAZZUP_DUDE: proto_tree_add_item(uhd_tree, hf_uhd_ip_addr, tvb, 12, 4, ENC_BIG_ENDIAN); break; case USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO: case USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE: proto_tree_add_item(uhd_tree, hf_uhd_spi_dev, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_spi_data, tvb, 16, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_spi_miso_edge, tvb, 20, 1, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_spi_mosi_edge, tvb, 21, 1, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_spi_num_bits, tvb, 22, 1, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_spi_readback, tvb, 23, 1, ENC_BIG_ENDIAN); break; case USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO: case USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE: case USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO: case USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE: proto_tree_add_item(uhd_tree, hf_uhd_i2c_addr, tvb, 12, 1, ENC_BIG_ENDIAN); i2c_bytes = tvb_get_guint8(tvb, 13); proto_tree_add_item(uhd_tree, hf_uhd_i2c_bytes, tvb, 13, 1, ENC_BIG_ENDIAN); for (ind = 0; ind < i2c_bytes; ind++) { proto_tree_add_item(uhd_tree, hf_uhd_i2c_data, tvb, 14 + ind, 1, ENC_BIG_ENDIAN); } break; case USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO: case USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE: proto_tree_add_item(uhd_tree, hf_uhd_reg_addr, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_reg_data, tvb, 16, 4, ENC_BIG_ENDIAN); proto_tree_add_item(uhd_tree, hf_uhd_reg_action, tvb, 20, 1, ENC_BIG_ENDIAN); break; case USRP2_CTRL_ID_HOLLER_AT_ME_BRO: case USRP2_CTRL_ID_HOLLER_BACK_DUDE: case USRP2_CTRL_ID_HUH_WHAT: case USRP2_CTRL_ID_PEACE_OUT: proto_tree_add_item(uhd_tree, hf_uhd_echo_len, tvb, 12, 4, ENC_BIG_ENDIAN); break; } }
static guint16 dissect_channel_send(tvbuff_t *tvb, proto_tree *tree, int offset) { guint16 send_type, awareness; guint na; send_type = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(send_type, sendtypenames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_send_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; switch (send_type) { case SAMETIME_SENDTYPE_AWARE_ADD: offset += 8; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case SAMETIME_SENDTYPE_OPT_DO_SET: offset += 20; na = tvb_get_ntohl(tvb, offset); offset += 4; if (na == 0x33) { offset += add_text_item(tvb, tree, offset, hf_sametime_location_country); offset += add_text_item(tvb, tree, offset, hf_sametime_location_postalcode); offset += add_text_item(tvb, tree, offset, hf_sametime_location_province); offset += add_text_item(tvb, tree, offset, hf_sametime_location_city); offset += add_text_item(tvb, tree, offset, hf_sametime_location_phone); offset += 1; offset += add_text_item(tvb, tree, offset, hf_sametime_location_name); add_text_item(tvb, tree, offset, hf_sametime_location_timezone); } else { add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case SAMETIME_SENDTYPE_OPT_GOT_SET: offset += 8; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; while (tvb_reported_length_remaining(tvb, offset) > 2) { int n = add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += (n) ? n : 1; } break; case SAMETIME_SENDTYPE_AWARE_SNAPSHOT: offset += 12; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case SAMETIME_SENDTYPE_AWARE_UPDATE: offset += 4; offset += 4; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 4; if (tvb_get_guint8(tvb, offset)) { offset += 1; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); dissect_set_user_status(tvb, tree, offset); } break; case 0x0000: offset += 14; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case 0x0002: offset += 8; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 3; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case 0x0005: /* XML */ if (26 <= tvb_reported_length_remaining(tvb, offset + 2)) { offset += 26; add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case 0x0007: offset += 8; if (4 <= tvb_reported_length_remaining(tvb, offset + 2)) { offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 3; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case 0x025a: offset += 10; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; default: break; } return send_type; }
static void dissect_ppi_antenna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* The fixed values up front */ guint32 version; guint length; gint length_remaining; proto_tree *ppi_antenna_tree = NULL; proto_tree *antennaflags_tree = NULL; proto_tree *pt, *my_pt; proto_item *ti = NULL; proto_item *antenna_line = NULL; /* bits */ int bit; guint32 present, next_present; /* values actually read out, for displaying */ guint8 gaindb; guint16 beamid; guint32 t_hbw, t_vbw, t_pgain, t_appspecific_num; /* temporary conversions */ gdouble horizbw, vertbw, pgain; guint32 flags; gchar *curr_str; int offset = 0; static const int * ppi_antenna_present_flags[] = { &hf_ppi_antenna_present_flags, &hf_ppi_antenna_present_gaindb, &hf_ppi_antenna_present_horizbw, &hf_ppi_antenna_present_vertbw, &hf_ppi_antenna_present_pgain, &hf_ppi_antenna_present_beamid, &hf_ppi_antenna_present_serialnum, &hf_ppi_antenna_present_modelname, &hf_ppi_antenna_present_descstr, &hf_ppi_antenna_present_appspecific_num, &hf_ppi_antenna_present_appspecific_data, &hf_ppi_antenna_present_ext, NULL }; /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); /* pull out the first three fields of the BASE-GEOTAG-HEADER */ version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); /* Setup basic column info */ col_add_fstr(pinfo->cinfo, COL_INFO, "PPI Antenna info v%u, Length %u", version, length); /* Create the basic dissection tree*/ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_ppi_antenna, tvb, 0, length, "Antenna: "); antenna_line = ti; /* save this for later, we will fill it in with more detail */ ppi_antenna_tree= proto_item_add_subtree(ti, ett_ppi_antenna); proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_version, tvb, offset, 1, version); proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_pad, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN); ti = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_length, tvb, offset + 2, 2, length); } /* We support v1 and v2 of Antenna tags (identical) */ if (! (version == 1 || version == 2) ) { if (tree) proto_item_append_text(ti, "invalid version (got %d, expected 1 or 2)", version); return; } length_remaining = length; /* minimum length check, should atleast be a fixed-size geotagging-base header*/ if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { /* * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion * plus one "present" bitset. */ proto_item_append_text(ti, " (invalid - minimum length is 8)"); return; } /* perform max length sanity checking */ if (length > PPI_ANTENNA_MAXTAGLEN ) { proto_item_append_text(ti, "Invalid PPI-Antenna length (got %d, %d max\n)", length, PPI_ANTENNA_MAXTAGLEN); return; } /* Subtree for the "present flags" bitfield. */ pt = proto_tree_add_bitmask(ppi_antenna_tree, tvb, offset + 4, hf_ppi_antenna_present, ett_ppi_antenna_present, ppi_antenna_present_flags, ENC_LITTLE_ENDIAN); offset += PPI_GEOBASE_MIN_HEADER_LEN; length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */ for (; present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = BITNO_32(present ^ next_present); switch (bit) { case PPI_ANTENNA_ANTFLAGS: if (length_remaining < 4) break; flags = tvb_get_letohl(tvb, offset); if (tree) { my_pt = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_flags, tvb, offset , 4, flags); /*Add antenna_flags bitfields here */ antennaflags_tree= proto_item_add_subtree(my_pt, ett_ppi_antennaflags); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_mimo, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_horizpol, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_vertpol, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_l, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_r, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_elec, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_mech, tvb, offset, 4, ENC_LITTLE_ENDIAN); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_GAINDB: if (length_remaining < 1) break; gaindb= tvb_get_guint8(tvb, offset); if (tree) { proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_gaindb, tvb, offset, 1, gaindb); proto_item_append_text(antenna_line, " Gain: %d", gaindb); } offset+=1; length_remaining-=1; break; case PPI_ANTENNA_HORIZBW: if (length_remaining < 4) break; t_hbw = tvb_get_letohl(tvb, offset); horizbw = ppi_fixed3_6_to_gdouble(t_hbw); if (tree) { proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_horizbw, tvb, offset, 4, horizbw); proto_item_append_text(antenna_line, " HorizBw: %f", horizbw); } offset+=4; length_remaining-=4; break; case PPI_ANTENNA_VERTBW: if (length_remaining < 4) break; t_vbw = tvb_get_letohl(tvb, offset); vertbw = ppi_fixed3_6_to_gdouble(t_vbw); proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_vertbw, tvb, offset, 4, vertbw); offset+=4; length_remaining-=4; break; case PPI_ANTENNA_PGAIN: if (length_remaining < 4) break; t_pgain = tvb_get_letohl(tvb, offset); pgain = ppi_fixed3_6_to_gdouble(t_pgain); proto_tree_add_double(ppi_antenna_tree, hf_ppi_antenna_pgain, tvb, offset, 4, pgain); offset+=4; length_remaining-=4; break; case PPI_ANTENNA_BEAMID: if (length_remaining < 2) break; beamid= tvb_get_letohs(tvb, offset); /* convert endianess */ proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_beamid, tvb, offset, 2, beamid); offset+=2; length_remaining-=2; break; case PPI_ANTENNA_SERIALNUM: if (length_remaining < 32) break; proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_serialnum, tvb, offset, 32, ENC_ASCII|ENC_NA); offset+=32; length_remaining-=32; break; case PPI_ANTENNA_MODELSTR: if (length_remaining < 32) break; if (tree) { /* proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_modelname, tvb, offset, 32, ENC_ASCII|ENC_NA); */ curr_str = tvb_format_stringzpad(tvb, offset, 32); proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_modelname, tvb, offset, 32, curr_str); proto_item_append_text(antenna_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_ANTENNA_DESCSTR: if (length_remaining < 32) break; if (tree) { /*proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_descstr, tvb, offset, 32, ENC_ASCII|ENC_NA);*/ curr_str = tvb_format_stringzpad(tvb, offset, 32); proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_descstr, tvb, offset, 32, curr_str); proto_item_append_text(antenna_line, " (%s)", curr_str); } offset+=32; length_remaining-=32; break; case PPI_ANTENNA_APPID: if (length_remaining < 4) break; t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_appspecific_num, tvb, offset, 4, t_appspecific_num); offset+=4; length_remaining-=4; break; case PPI_ANTENNA_APPDATA: if (length_remaining < 60) break; proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_appspecific_data, tvb, offset, 60, ENC_NA); offset+=60; length_remaining-=60; break; default: /* * This indicates a field whose size we do not * know, so we cannot proceed. */ expert_add_info_format(pinfo, pt, &ei_ppi_antenna_present_bit, "Error: PPI-ANTENNA: unknown bit (%d) set in present field.", bit); next_present = 0; continue; } }; return; }
static void dissect_msproxy_request(tvbuff_t *tvb, proto_tree *tree, hash_entry_t *conv_info) { int offset = 0; int cmd; if ( tree) { proto_tree_add_text( tree, tvb, offset, 4, "Client id: 0x%0x", tvb_get_letohl( tvb, offset)); offset += 4; proto_tree_add_text( tree, tvb, offset, 4, "Version: 0x%04x", tvb_get_letohl( tvb, offset)); offset += 4; proto_tree_add_text( tree, tvb, offset, 4, "Server id: 0x%0x", tvb_get_letohl( tvb, offset)); offset += 4; proto_tree_add_text( tree, tvb, offset, 1, "Server ack: %u", tvb_get_guint8( tvb, offset)); offset += 4; proto_tree_add_text( tree, tvb, offset, 1, "Sequence Number: %u", tvb_get_guint8( tvb, offset)); offset += 8; proto_tree_add_text( tree, tvb, offset, 4, "RWSP signature: %.4s", tvb_get_ephemeral_string( tvb, offset, 4)); offset += 12; } else /* no tree */ offset += 36; cmd = tvb_get_ntohs( tvb, offset); if ( tree) proto_tree_add_uint_format( tree, hf_msproxy_cmd, tvb, offset, 2, cmd, "Command: 0x%02x (%s)", cmd, get_msproxy_cmd_name( cmd, FROM_CLIENT)); offset += 2; switch (cmd){ case MSPROXY_AUTH: dissect_auth( tvb, offset, tree); break; case MSPROXY_BIND: dissect_bind( tvb, offset, tree, conv_info); break; case MSPROXY_UDP_BIND_REQ: dissect_udp_bind( tvb, offset, tree, conv_info); break; case MSPROXY_AUTH_2: /*$$ this is probably wrong place for this */ case MSPROXY_TCP_BIND: dissect_tcp_bind( tvb, offset, tree, conv_info); break; case MSPROXY_RESOLVE: dissect_request_resolve( tvb, offset, tree); break; case MSPROXY_CONNECT: case MSPROXY_LISTEN: dissect_request_connect( tvb, offset, tree, conv_info); break; case MSPROXY_BINDINFO_ACK: dissect_bind_info_ack( tvb, offset, tree); break; case MSPROXY_HELLO: case MSPROXY_HELLO_2: dissect_msproxy_request_1( tvb, offset, tree); break; case MSPROXY_UDPASSOCIATE: dissect_udp_assoc( tvb, offset, tree, conv_info); break; default: if ( tree) proto_tree_add_text( tree, tvb, offset, 0, "Unhandled request command (report this, please)"); } }
static void dissect_fefd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *fefd_tree = NULL; int offset = 0; guint16 type; guint16 length; proto_item *tlvi; proto_tree *tlv_tree; int real_length; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FEFD"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *flags_ti; proto_tree *flags_tree; ti = proto_tree_add_item(tree, proto_fefd, tvb, offset, -1, FALSE); fefd_tree = proto_item_add_subtree(ti, ett_fefd); /* FEFD header */ proto_tree_add_item(fefd_tree, hf_fefd_version, tvb, offset, 1, FALSE); proto_tree_add_item(fefd_tree, hf_fefd_opcode, tvb, offset, 1, FALSE); offset += 1; flags_ti = proto_tree_add_item(fefd_tree, hf_fefd_flags, tvb, offset, 1, FALSE); flags_tree = proto_item_add_subtree(ti, ett_fefd_flags); proto_tree_add_item(flags_tree, hf_fefd_flags_rt, tvb, offset, 1, FALSE); proto_tree_add_item(flags_tree, hf_fefd_flags_rsy, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(fefd_tree, hf_fefd_checksum, tvb, offset, 2, FALSE); offset += 2; } else { offset += 4; /* The version/opcode/flags/checksum fields from above */ } while (tvb_reported_length_remaining(tvb, offset) != 0) { type = tvb_get_ntohs(tvb, offset + TLV_TYPE); length = tvb_get_ntohs(tvb, offset + TLV_LENGTH); if (length < 4) { if (tree) { tlvi = proto_tree_add_text(fefd_tree, tvb, offset, 4, "TLV with invalid length %u (< 4)", length); tlv_tree = proto_item_add_subtree(tlvi, ett_fefd_tlv); proto_tree_add_uint(tlv_tree, hf_fefd_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_fefd_tlvlength, tvb, offset + TLV_LENGTH, 2, length); } offset += 4; break; } switch (type) { case TYPE_DEVICE_ID: /* Device ID */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Device ID: %s", tvb_format_stringzpad(tvb, offset + 4, length - 4)); if (tree) { tlvi = proto_tree_add_text(fefd_tree, tvb, offset, length, "Device ID: %s", tvb_format_stringzpad(tvb, offset + 4, length - 4)); tlv_tree = proto_item_add_subtree(tlvi, ett_fefd_tlv); proto_tree_add_uint(tlv_tree, hf_fefd_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_fefd_tlvlength, tvb, offset + TLV_LENGTH, 2, length); proto_tree_add_text(tlv_tree, tvb, offset + 4, length - 4, "Device ID: %s", tvb_format_stringzpad(tvb, offset + 4, length - 4)); } offset += length; break; case TYPE_PORT_ID: real_length = length; if (tvb_get_guint8(tvb, offset + real_length) != 0x00) { /* The length in the TLV doesn't appear to be the length of the TLV, as the byte just past it isn't the first byte of a 2-byte big-endian small integer; make the length of the TLV the length in the TLV, plus 4 bytes for the TLV type and length, minus 1 because that's what makes one capture work. */ real_length = length + 3; } if (check_col(pinfo->cinfo, COL_INFO)) col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Port ID: %s", tvb_format_stringzpad(tvb, offset + 4, real_length - 4)); if (tree) { tlvi = proto_tree_add_text(fefd_tree, tvb, offset, real_length, "Port ID: %s", tvb_format_text(tvb, offset + 4, real_length - 4)); tlv_tree = proto_item_add_subtree(tlvi, ett_fefd_tlv); proto_tree_add_uint(tlv_tree, hf_fefd_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_fefd_tlvlength, tvb, offset + TLV_LENGTH, 2, length); proto_tree_add_text(tlv_tree, tvb, offset + 4, real_length - 4, "Sent through Interface: %s", tvb_format_text(tvb, offset + 4, real_length - 4)); } offset += real_length; break; case TYPE_ECHO: case TYPE_MESSAGE_INTERVAL: case TYPE_TIMEOUT_INTERVAL: case TYPE_DEVICE_NAME: case TYPE_SEQUENCE_NUMBER: default: tlvi = proto_tree_add_text(fefd_tree, tvb, offset, length, "Type: %s, length: %u", val_to_str(type, type_vals, "Unknown (0x%04x)"), length); tlv_tree = proto_item_add_subtree(tlvi, ett_fefd_tlv); proto_tree_add_uint(tlv_tree, hf_fefd_tlvtype, tvb, offset + TLV_TYPE, 2, type); proto_tree_add_uint(tlv_tree, hf_fefd_tlvlength, tvb, offset + TLV_LENGTH, 2, length); if (length > 4) { proto_tree_add_text(tlv_tree, tvb, offset + 4, length - 4, "Data"); } else { return; } offset += length; } } call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, fefd_tree); }
/* * Name: isis_dissect_isis_hello() * * Description: * This procedure rips apart the various types of ISIS hellos. L1H and * L2H's are identical for the most part, while the PTP hello has * a shorter header. * * Input: * tvbuff_t * : tvbuffer for packet data * proto_tree * : protocol display tree to add to. May be NULL. * int offset : our offset into packet data. * int : hello type, a la packet-isis.h ISIS_TYPE_* values * int : header length of packet. * int : length of IDs in packet. * * Output: * void, will modify proto_tree if not NULL. */ void isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hello_type, int header_length, int id_length) { proto_item *ti; proto_tree *hello_tree = NULL; int len; guint8 octet; const guint8 *source_id; guint16 pdu_length; const guint8 *lan_id; if (tree) { ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO"); hello_tree = proto_item_add_subtree(ti, ett_isis_hello); octet = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format(hello_tree, hf_isis_hello_circuit_reserved, tvb, offset, 1, octet, "Circuit type : %s, reserved(0x%02x == 0)", val_to_str(octet&ISIS_HELLO_CTYPE_MASK, isis_hello_circuit_type_vals, "Unknown (0x%x)"), octet&ISIS_HELLO_CT_RESERVED_MASK ); } offset += 1; if (tree) { source_id = tvb_get_ptr(tvb, offset, id_length); proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb, offset, id_length, source_id, "System-ID {Sender of PDU} : %s", print_system_id( source_id, id_length ) ); } if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) ); } offset += id_length; if (tree) { proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb, offset, 2, FALSE); } offset += 2; pdu_length = tvb_get_ntohs(tvb, offset); if (tree) { proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb, offset, 2, pdu_length); } offset += 2; if (hello_type == ISIS_TYPE_PTP_HELLO) { if (tree) { proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb, offset, 1, FALSE ); } offset += 1; } else { if (tree) { octet = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb, offset, 1, octet, "Priority : %d, reserved(0x%02x == 0)", octet&ISIS_HELLO_PRIORITY_MASK, octet&ISIS_HELLO_P_RESERVED_MASK ); } offset += 1; if (tree) { lan_id = tvb_get_ptr(tvb, offset, id_length+1); proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb, offset, id_length + 1, lan_id, "System-ID {Designated IS} : %s", print_system_id( lan_id, id_length + 1 ) ); } offset += id_length + 1; } len = pdu_length; len -= header_length; if (len < 0) { isis_dissect_unknown(tvb, tree, offset, "Packet header length %d went beyond packet", header_length ); return; } /* * Now, we need to decode our CLVs. We need to pass in * our list of valid ones! */ if (hello_type == ISIS_TYPE_L1_HELLO){ isis_dissect_clvs(tvb, hello_tree, offset, clv_l1_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } else if (hello_type == ISIS_TYPE_L2_HELLO) { isis_dissect_clvs(tvb, hello_tree, offset, clv_l2_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } else { isis_dissect_clvs(tvb, hello_tree, offset, clv_ptp_hello_opts, len, id_length, ett_isis_hello_clv_unknown); } }
/* Decode LSC over UDP */ static void dissect_lsc_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { dissect_lsc_common(tvb, pinfo, tree); } /* Determine length of LSC message */ static guint get_lsc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) { guint8 op_code; guint pdu_len; /* Get the op code */ op_code = tvb_get_guint8(tvb, offset + 2); switch (op_code) { case LSC_PAUSE: pdu_len = LSC_PAUSE_LEN; break; case LSC_RESUME: pdu_len = LSC_RESUME_LEN; break; case LSC_STATUS: pdu_len = LSC_STATUS_LEN; break; case LSC_RESET: pdu_len = LSC_RESET_LEN; break;
/* Code to actually dissect the packets */ static int dissect_csm_encaps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { proto_item *ti; proto_tree *csm_encaps_tree = NULL; guint16 function_code, channel, class_type; guint control, type, sequence, length; guint i; gboolean show_error_param= FALSE; const gchar *str_function_name; function_code = tvb_get_letohs(tvb, 10); control = tvb_get_guint8(tvb, 3); class_type = tvb_get_guint8(tvb, 9); class_type = class_type<<8; class_type|= tvb_get_guint8(tvb, 8); type = tvb_get_guint8(tvb, 8); sequence = tvb_get_guint8(tvb, 2); length = tvb_get_guint8(tvb, 6); channel = tvb_get_ntohs(tvb, 4); if (CSM_ENCAPS_CTRL_ACK&control) show_error_param= FALSE; else { if (csm_to_host(function_code, class_type)) /* exclusive messages to host */
/* Code to actually dissect the packets */ static void dissect_lsc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *lsc_tree; guint8 op_code; guint32 stream; guint expected_len; /* Protocol is LSC, packet summary is not yet known */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LSC"); col_clear(pinfo->cinfo, COL_INFO); /* Too little data? */ if (tvb_length(tvb) < LSC_MIN_LEN) { col_set_str(pinfo->cinfo, COL_INFO, "[Too short]"); return; } /* Get the op code */ op_code = tvb_get_guint8(tvb, 2); /* And the stream handle */ stream = tvb_get_ntohl(tvb, 4); /* Check the data length against what we actually received */ switch (op_code) { case LSC_PAUSE: expected_len = LSC_PAUSE_LEN; break; case LSC_RESUME: expected_len = LSC_RESUME_LEN; break; case LSC_STATUS: expected_len = LSC_STATUS_LEN; break; case LSC_RESET: expected_len = LSC_RESET_LEN; break; case LSC_JUMP: expected_len = LSC_JUMP_LEN; break; case LSC_PLAY: expected_len = LSC_PLAY_LEN; break; case LSC_DONE: case LSC_PAUSE_REPLY: case LSC_RESUME_REPLY: case LSC_STATUS_REPLY: case LSC_RESET_REPLY: case LSC_JUMP_REPLY: case LSC_PLAY_REPLY: expected_len = LSC_REPLY_LEN; break; default: /* Unrecognized op code */ expected_len = LSC_MIN_LEN; break; } /* Display the op code in the summary */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s, session %.8u", val_to_str(op_code, op_code_vals, "Unknown op code (0x%x)"), stream); if (tvb_length(tvb) < expected_len) col_append_str(pinfo->cinfo, COL_INFO, " [Too short]"); else if (tvb_length(tvb) > expected_len) col_append_str(pinfo->cinfo, COL_INFO, " [Too long]"); if (tree) { /* Create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_lsc, tvb, 0, -1, ENC_NA); lsc_tree = proto_item_add_subtree(ti, ett_lsc); /* Add already fetched items to the tree */ proto_tree_add_uint(lsc_tree, hf_lsc_op_code, tvb, 2, 1, op_code); proto_tree_add_uint_format_value(lsc_tree, hf_lsc_stream_handle, tvb, 4, 4, stream, "%.8u", stream); /* Add rest of LSC header */ proto_tree_add_uint(lsc_tree, hf_lsc_version, tvb, 0, 1, tvb_get_guint8(tvb, 0)); proto_tree_add_uint(lsc_tree, hf_lsc_trans_id, tvb, 1, 1, tvb_get_guint8(tvb, 1)); /* Only replies contain a status code */ if (isReply(op_code)) proto_tree_add_uint(lsc_tree, hf_lsc_status_code, tvb, 3, 1, tvb_get_guint8(tvb, 3)); /* Add op code specific parts */ switch (op_code) { case LSC_PAUSE: proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); break; case LSC_RESUME: proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2, tvb_get_ntohs(tvb, 12)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2, tvb_get_ntohs(tvb, 14)); break; case LSC_JUMP: case LSC_PLAY: proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 12, 4, tvb_get_ntohl(tvb, 12)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 16, 2, tvb_get_ntohs(tvb, 16)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 18, 2, tvb_get_ntohs(tvb, 18)); break; case LSC_DONE: case LSC_PAUSE_REPLY: case LSC_RESUME_REPLY: case LSC_STATUS_REPLY: case LSC_RESET_REPLY: case LSC_JUMP_REPLY: case LSC_PLAY_REPLY: proto_tree_add_int(lsc_tree, hf_lsc_current_npt, tvb, 8, 4, tvb_get_ntohl(tvb, 8)); proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2, tvb_get_ntohs(tvb, 12)); proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2, tvb_get_ntohs(tvb, 14)); proto_tree_add_uint(lsc_tree, hf_lsc_mode, tvb, 16, 1, tvb_get_guint8(tvb, 16)); break; default: break; } } }
static void dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *usb_audio_tree, proto_tree *parent_tree, gint offset) { guint8 code; guint8 cable; gboolean save_fragmented; proto_tree *tree = NULL; col_set_str(pinfo->cinfo, COL_INFO, "USB-MIDI Event Packets"); code = tvb_get_guint8(tvb, offset); cable = (code & 0xF0) >> 4; code &= 0x0F; if (parent_tree) { proto_item *ti; ti = proto_tree_add_protocol_format(usb_audio_tree, proto_usb_audio, tvb, offset, 4, "USB Midi Event Packet"); tree = proto_item_add_subtree(ti, ett_usb_audio); proto_tree_add_item(tree, hf_midi_cable_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_code_index, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_midi_event, tvb, offset+1, 3, ENC_BIG_ENDIAN); } save_fragmented = pinfo->fragmented; /* Reassemble SysEx commands */ if (is_sysex_code(code)) { tvbuff_t* new_tvb = NULL; fragment_head *frag_sysex_msg = NULL; pinfo->fragmented = TRUE; if (code == 0x04) { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, 3, TRUE); } else { frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table, tvb, offset+1, pinfo, cable, /* ID for fragments belonging together */ NULL, (gint)(code - 4), FALSE); } if (is_last_sysex_packet_in_tvb(tvb, offset)) { new_tvb = process_reassembled_data(tvb, offset+1, pinfo, "Reassembled Message", frag_sysex_msg, &sysex_msg_frag_items, NULL, usb_audio_tree); if (code != 0x04) { /* Reassembled */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx Reassembled)"); } else { /* Not last packet of reassembled Short Message */ col_append_str(pinfo->cinfo, COL_INFO, " (SysEx fragment)"); } if (new_tvb) { call_dissector(sysex_handle, new_tvb, pinfo, parent_tree); } } } pinfo->fragmented = save_fragmented; }
/*----------------------------------------------------------------------------- UA DISSECTOR ---------------------------------------------------------------------------*/ static void _dissect_ua_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, e_ua_direction direction) { gint offset = 0; proto_item *ua_msg_item; proto_tree *ua_msg_tree; ua_msg_item = proto_tree_add_protocol_format(tree, proto_ua_msg, tvb, 0, -1, "Universal Alcatel Protocol, %s", ((direction == SYS_TO_TERM) ? "System -> Terminal" : "Terminal -> System")); ua_msg_tree = proto_item_add_subtree(ua_msg_item, ett_ua_msg); while (tvb_offset_exists(tvb, offset)) { gint length; gint opcode; length = tvb_get_letohs(tvb, offset) + 2; opcode = tvb_get_guint8(tvb, offset+2); /* RTP/RTCP conversation setup */ if (setup_conversations_enabled && (opcode==0x13) && (tvb_get_guint8(tvb, offset+3)==0x01)) { address remote_rtp_addr; guint32 remote_rtp_port; gint suboffset; remote_rtp_addr.data = NULL; remote_rtp_port = 0; /* StartRTP */ suboffset = offset + 5; while (suboffset < offset+length) { switch (tvb_get_guint8(tvb, suboffset)) { case 0x00: /* local port */ { /*local_rtp_port = tvb_get_ntohs(tvb, suboffset+2);*/ break; } case 0x01: /* remote IP */ { remote_rtp_addr.type = AT_IPv4; remote_rtp_addr.len = 4; remote_rtp_addr.data = tvb_get_ptr(tvb, suboffset+2, 4); break; } case 0x02: /* remote port */ { remote_rtp_port = tvb_get_ntohs(tvb, suboffset+2); break; } } suboffset += tvb_get_guint8(tvb, suboffset+1) + 2; } if ((remote_rtp_addr.data != NULL) && (remote_rtp_port != 0)) { rtp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port, 0, "UA", pinfo->fd->num, 0, NULL); rtcp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port+1, 0, "UA", pinfo->fd->num); } } uadecode(direction, ua_msg_tree, pinfo, tvb, offset, opcode, length); offset += length; } }