/** * dissect_content_length is a utility function which * calculates how long is the payload section of the message * in bytes. Used only by the UDP dissector. * * @see dissect_packetid() * @see dissect_reliable_message_index_base() * @see dissect_reliable_message_number() * @see dissect_messageid() * @see dissect_payload() * @param buffer the buffer to the data * @param offset the offset where to start reading the data * @param tree the parent tree where the dissected data is going to be inserted * @return int returns the content length of the packet * */ static int dissect_content_length(tvbuff_t *buffer, int offset, proto_tree *tree) { proto_item *msgflags_ti; proto_tree *msgflags_tree; guint32 length; length = tvb_get_bits8(buffer, offset * 8 + 12, 4) << 8; length += tvb_get_bits8(buffer, offset * 8, 8); if(tree != NULL) { msgflags_ti = proto_tree_add_item(tree, hf_knet_msg_flags, buffer, offset + 1, 1, ENC_NA); msgflags_tree = proto_item_add_subtree(msgflags_ti, ett_knet_message_flags); proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_fs, buffer, offset * 8 + 8, 1, ENC_LITTLE_ENDIAN); /* Fragment start flag */ proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_ff, buffer, offset * 8 + 9, 1, ENC_LITTLE_ENDIAN); /* Fragment flag */ proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_inorder, buffer, offset * 8 + 10, 1, ENC_LITTLE_ENDIAN); /* Inorder flag */ proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_reliable, buffer, offset * 8 + 11, 1, ENC_LITTLE_ENDIAN); /* Reliable flag */ proto_tree_add_uint(tree, hf_knet_content_length, buffer, offset, 2, length); } return length; }
static gboolean dissect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 flags; gboolean crcok, dir, encrypted, micok; gboolean bad_length = FALSE; gboolean bad_mic = FALSE; gboolean bad_crc = FALSE; proto_item *flags_item, *item; flags = tvb_get_guint8(tvb, get_flags_index()); crcok = !!(flags & 1); dir = !!(flags & 2); encrypted = !!(flags & 4); micok = !!(flags & 8); if (dir) { SET_ADDRESS(&pinfo->src, AT_STRINGZ, 7, "Master"); SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 6, "Slave"); } else { SET_ADDRESS(&pinfo->src, AT_STRINGZ, 6, "Slave"); SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 7, "Master"); } flags_item = proto_tree_add_item(tree, hf_nordic_ble_flags, tvb, get_flags_index(), 1, ENC_BIG_ENDIAN); //flags_tree = proto_item_add_subtree(flags_item, ett_flags); if (encrypted) // if encrypted, add MIC status { item = proto_tree_add_bits_item(tree, hf_nordic_ble_micok, tvb, get_flags_index()*8+4, 1, ENC_LITTLE_ENDIAN); if (!micok) { // /* MIC is bad */ #if IS_VERSION_1_11 expert_add_info(pinfo, item, &ei_nordic_ble_bad_mic); #elif IS_VERSION_1_10 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_WARN, "MIC is bad"); expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Decryption failed (wrong key?)"); #endif bad_mic = TRUE; } } proto_tree_add_bits_item(tree, hf_nordic_ble_encrypted, tvb, get_flags_index()*8+5, 1, ENC_LITTLE_ENDIAN); proto_tree_add_bits_item(tree, hf_nordic_ble_direction, tvb, get_flags_index()*8+6, 1, ENC_LITTLE_ENDIAN); item = proto_tree_add_bits_item(tree, hf_nordic_ble_crcok, tvb, get_flags_index()*8+7, 1, ENC_LITTLE_ENDIAN); if(!crcok) { /* CRC is bad */ #if IS_VERSION_1_11 expert_add_info(pinfo, item, &ei_nordic_ble_bad_crc); #elif IS_VERSION_1_10 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "CRC is bad"); #endif bad_crc =TRUE; } return bad_mic; }
static void gcsna_message_GCSNAL2Ack(proto_item *item, tvbuff_t *tvb, proto_tree *tree, guint *offset) { proto_tree *subtree = NULL; item = proto_tree_add_item(tree, hf_gcsna_l2ack, tvb, *offset, 1, ENC_NA); subtree = proto_item_add_subtree(item, ett_gcsna_subtree); proto_tree_add_bits_item(subtree, hf_gcsna_ackSequence, tvb, *offset * 8, 6, ENC_BIG_ENDIAN); *offset += 1; }
void dissect_fhs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset) { proto_item *fhs_item, *psmode_item; proto_tree *fhs_tree; const gchar *description; guint8 psmode; if(tvb_reported_length_remaining(tvb, offset) != 20) { col_add_str(pinfo->cinfo, COL_INFO, "Encrypted or malformed payload data"); return; } fhs_item = proto_tree_add_item(tree, hf_btbredr_payload, tvb, offset, -1, ENC_NA); fhs_tree = proto_item_add_subtree(fhs_item, ett_btbredr_payload); /* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */ proto_tree_add_bits_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN); /* proto_tree_add_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */ offset += 4; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 3; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_eir, tvb, offset, 1, ENC_NA); /* skipping 1 undefined bit */ proto_tree_add_item(fhs_tree, hf_btbredr_fhs_sr, tvb, offset, 1, ENC_NA); /* skipping 2 reserved bits */ offset += 1; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_uap, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN); offset += 3; proto_tree_add_item(fhs_tree, hf_btbredr_fhs_ltaddr, tvb, offset, 1, ENC_NA); proto_tree_add_item(fhs_tree, hf_btbredr_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 3; psmode = tvb_get_guint8(tvb, offset); description = try_rval_to_str(psmode, ps_modes); psmode_item = proto_tree_add_item(fhs_tree, hf_btbredr_fhs_psmode, tvb, offset, 1, ENC_NA); if (description) proto_item_append_text(psmode_item, " (%s)", description); offset += 1; proto_tree_add_item(fhs_tree, hf_btbredr_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; }
void dissect_fhs(proto_tree *tree, tvbuff_t *tvb, int offset) { proto_item *fhs_item, *psmode_item; proto_tree *fhs_tree; const gchar *description; guint8 psmode; DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) == 20); fhs_item = proto_tree_add_item(tree, hf_btbb_payload, tvb, offset, -1, ENC_NA); fhs_tree = proto_item_add_subtree(fhs_item, ett_btbb_payload); /* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */ proto_tree_add_bits_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN); /* proto_tree_add_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */ offset += 4; proto_tree_add_item(fhs_tree, hf_btbb_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 3; proto_tree_add_item(fhs_tree, hf_btbb_fhs_eir, tvb, offset, 1, ENC_NA); /* skipping 1 undefined bit */ proto_tree_add_item(fhs_tree, hf_btbb_fhs_sr, tvb, offset, 1, ENC_NA); /* skipping 2 reserved bits */ offset += 1; proto_tree_add_item(fhs_tree, hf_btbb_fhs_uap, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(fhs_tree, hf_btbb_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(fhs_tree, hf_btbb_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN); offset += 3; proto_tree_add_item(fhs_tree, hf_btbb_fhs_ltaddr, tvb, offset, 1, ENC_NA); proto_tree_add_item(fhs_tree, hf_btbb_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 3; psmode = tvb_get_guint8(tvb, offset); description = try_rval_to_str(psmode, ps_modes); psmode_item = proto_tree_add_item(fhs_tree, hf_btbb_fhs_psmode, tvb, offset, 1, ENC_NA); if (description) proto_item_append_text(psmode_item, " (%s)", description); offset += 1; proto_tree_add_item(fhs_tree, hf_btbb_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; }
int dissect_h263_group_of_blocks_layer( tvbuff_t *tvb, proto_tree *tree, gint offset, gboolean is_rfc4626) { unsigned int offset_in_bits = offset << 3; if(is_rfc4626){ /* GBSC 1xxx xxxx */ proto_tree_add_bits_item(tree, hf_h263_gbsc, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; }else{ /* Group of Block Start Code (GBSC) (17 bits) * A word of 17 bits. Its value is 0000 0000 0000 0000 1. */ proto_tree_add_bits_item(tree, hf_h263_gbsc, tvb, offset_in_bits, 17, FALSE); offset_in_bits = offset_in_bits +17; } /* * Group Number (GN) (5 bits) */ proto_tree_add_bits_item(tree, hf_h263_GN, tvb, offset_in_bits, 5, FALSE); offset_in_bits = offset_in_bits +5; /* 5.2.4 GOB Sub-Bitstream Indicator (GSBI) (2 bits) * A fixed length codeword of 2 bits that is only present if CPM is "1" in the picture header. */ /* * 5.2.5 GOB Frame ID (GFID) (2 bits) */ /* * 5.2.6 Quantizer Information (GQUANT) (5 bits) */ /* * 5.3 Macroblock layer */ return offset_in_bits>>3; }
static void dissect_ayiya(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ayiya_tree; int offset = 0; int idlen, siglen, ayiya_len; guint8 next_header, opcode; tvbuff_t *payload; idlen = 1 << tvb_get_bits8(tvb, 0, 4); siglen = tvb_get_bits8(tvb, 8, 4) * 4; opcode = tvb_get_bits8(tvb, 20, 4); next_header = tvb_get_guint8(tvb, 3); ayiya_len = 8+idlen+siglen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AYIYA"); if (tree) { proto_item *ti; nstime_t tv; ti = proto_tree_add_protocol_format( tree, proto_ayiya, tvb, offset, ayiya_len, "AYIYA" ); ayiya_tree = proto_item_add_subtree(ti, ett_ayiya); proto_tree_add_bits_item(ayiya_tree, hf_id_len, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_id_type, tvb, 4, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_sig_len, tvb, 8, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_hash_method, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_auth_method, tvb, 16, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(ayiya_tree, hf_opcode, tvb, 20, 4, ENC_BIG_ENDIAN); proto_tree_add_uint_format(ayiya_tree, hf_next_header, tvb, 3, 1, next_header, "Next header: %s (0x%02x)", ipprotostr(next_header), next_header); tv.secs = tvb_get_ntohl(tvb, 4); tv.nsecs = 0; proto_tree_add_time(ayiya_tree, hf_epoch, tvb, 4, 4, &tv); proto_tree_add_item(ayiya_tree, hf_identity, tvb, 8, idlen, ENC_NA); proto_tree_add_item(ayiya_tree, hf_signature, tvb, 8+idlen, siglen, ENC_NA); } offset = ayiya_len; switch (opcode) { case OPCODE_FORWARD: payload = tvb_new_subset_remaining(tvb, offset); dissector_try_uint(ip_dissector_table, next_header, payload, pinfo, tree); break; } }
static void dissect_pairing_request(tvbuff_t *tvb, proto_tree *tree) { proto_item *auth_req_item; proto_tree *auth_req_tree; proto_tree_add_item(tree, hf_btsm_pairing_request_io_capability, tvb, 1, 1, TRUE); proto_tree_add_item(tree, hf_btsm_pairing_request_oob_data, tvb, 2, 1, TRUE); auth_req_item = proto_tree_add_item(tree, hf_btsm_pairing_request_auth_req, tvb, 3, 1, TRUE); auth_req_tree = proto_item_add_subtree(auth_req_item, ett_auth_req); proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_reserved, tvb, 3, 1, TRUE); proto_tree_add_bits_item(auth_req_tree, hf_btsm_pairing_request_mitm, tvb, 3 * 8 + 5, 1, TRUE); proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_bonding_flags, tvb, 3, 1, TRUE); // TODO: check that max key size iswithin [7,16] proto_tree_add_item(tree, hf_btsm_pairing_request_max_key_size, tvb, 4, 1, TRUE); proto_tree_add_item(tree, hf_btsm_pairing_request_initiator_key_distribution, tvb, 5, 1, TRUE); proto_tree_add_item(tree, hf_btsm_pairing_request_responder_key_distribution, tvb, 6, 1, TRUE); }
/* add information for an LI to 'tree' */ static proto_tree *tree_add_li(struct rlc_li *li, guint8 li_idx, guint8 hdr_offs, tvbuff_t *tvb, proto_tree *tree) { proto_item *ti; proto_tree *li_tree; guint8 li_offs; if (!tree) return NULL; li_offs = hdr_offs + li_idx; ti = proto_tree_add_item(tree, hf_rlc_li, tvb, li_offs, 1, FALSE); li_tree = proto_item_add_subtree(ti, ett_rlc_frag); proto_tree_add_bits_item(li_tree, hf_rlc_li_value, tvb, li_offs*8, 7, FALSE); proto_tree_add_item(li_tree, hf_rlc_li_ext, tvb, li_offs, 1, FALSE); if (li->len > 0) { if (li->li > tvb_length_remaining(tvb, hdr_offs)) return li_tree; if (li->len > li->li) return li_tree; proto_tree_add_item(li_tree, hf_rlc_li_data, tvb, hdr_offs + li->li - li->len, li->len, FALSE); } return li_tree; }
/* * Length is used for the "Extra header" otherwise set to -1. */ int dissect_h263_picture_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint length _U_, gboolean is_rfc4626) { proto_tree *h263_opptype_tree = NULL; proto_item *opptype_item = NULL; unsigned int offset_in_bits = offset << 3; unsigned int saved_bit_offset; guint64 source_format; guint64 ufep; guint64 picture_coding_type; guint64 PB_frames_mode = 0; guint64 custom_pcf = 0; guint64 picture_type_code =0; guint64 cpm; guint64 pei; if(is_rfc4626){ /* PC 1000 00xx */ proto_tree_add_bits_item(tree, hf_h263_psc, tvb, offset_in_bits, 6, FALSE); offset_in_bits = offset_in_bits +6; }else{ /* Check for PSC, PSC is a word of 22 bits. * Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */ proto_tree_add_bits_item(tree, hf_h263_psc, tvb, offset_in_bits, 22, FALSE); offset_in_bits = offset_in_bits +22; } proto_tree_add_bits_item(tree, hf_h263_TR, tvb, offset_in_bits, 8, FALSE); offset_in_bits = offset_in_bits +8; /* * Bit 1: Always "1", in order to avoid start code emulation. * Bit 2: Always "0", for distinction with Recommendation H.261. */ offset_in_bits = offset_in_bits +2; /* Bit 3: Split screen indicator, "0" off, "1" on. */ proto_tree_add_bits_item( tree, hf_h263_split_screen_indicator, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bit 4: Document camera indicator, */ proto_tree_add_bits_item( tree, hf_h263_document_camera_indicator, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bit 5: Full Picture Freeze Release, "0" off, "1" on. */ proto_tree_add_bits_item( tree, hf_h263_full_picture_freeze_release, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF, * "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE. */ proto_tree_add_bits_ret_val( tree, hf_h263_source_format, tvb, offset_in_bits, 3 ,&source_format, FALSE); offset_in_bits = offset_in_bits +3; if (source_format != H263_PLUSPTYPE){ /* Not extended PTYPE */ /* Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture). */ proto_tree_add_bits_ret_val( tree, hf_h263_payload_picture_coding_type, tvb, offset_in_bits, 1, &picture_coding_type, FALSE); if ( check_col( pinfo->cinfo, COL_INFO) ) col_append_str(pinfo->cinfo, COL_INFO, val_to_str((guint32)picture_coding_type, picture_coding_type_vals, "Unknown (%u)")); offset_in_bits++; /* Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on. */ proto_tree_add_bits_item( tree, hf_h263_opt_unres_motion_vector_mode, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.*/ proto_tree_add_bits_item( tree, hf_h263_syntax_based_arithmetic_coding_mode, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.*/ proto_tree_add_bits_item( tree, hf_h263_optional_advanced_prediction_mode, tvb, offset_in_bits, 1, FALSE); offset_in_bits++; /* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/ proto_tree_add_bits_ret_val( tree, hf_h263_PB_frames_mode, tvb, offset_in_bits, 1, &PB_frames_mode, FALSE); offset_in_bits++; }else{ /* Extended PTYPE * Update Full Extended PTYPE (UFEP) (3 bits) */ /* .... ..xx x... .... */ proto_tree_add_bits_ret_val( tree, hf_h263_UFEP, tvb, offset_in_bits, 3, &ufep, FALSE); offset_in_bits = offset_in_bits +3; if(ufep==1){ /* The Optional Part of PLUSPTYPE (OPPTYPE) (18 bits) */ /* .xxx xxxx xxxx xxxx xxx. .... */ opptype_item = proto_tree_add_bits_item( tree, hf_h263_opptype, tvb, offset_in_bits, 18, FALSE); h263_opptype_tree = proto_item_add_subtree( opptype_item, ett_h263_optype ); /* * If UFEP is "001", then the following bits are present in PLUSPTYPE: * Bits 1-3 Source Format, "000" reserved, "001" sub-QCIF, "010" QCIF, "011" CIF, * "100" 4CIF, "101" 16CIF, "110" custom source format, "111" reserved; */ proto_tree_add_bits_item( h263_opptype_tree, hf_h263_ext_source_format, tvb, offset_in_bits, 3, FALSE); offset_in_bits+=3; /* * Bit 4 Optional Custom PCF, "0" CIF PCF, "1" custom PCF; */ proto_tree_add_bits_ret_val( h263_opptype_tree, hf_h263_custom_pcf, tvb, offset_in_bits, 1, &custom_pcf, FALSE); offset_in_bits++; saved_bit_offset=offset_in_bits; /* * Bit 5 Optional Unrestricted Motion Vector (UMV) mode (see Annex D), "0" off, "1" on; */ offset_in_bits++; /* * Bit 6 Optional Syntax-based Arithmetic Coding (SAC) mode (see Annex E), "0" off, "1" on; */ offset_in_bits++; /* * Bit 7 Optional Advanced Prediction (AP) mode (see Annex F), "0" off, "1" on; */ offset_in_bits++; /* * Bit 8 Optional Advanced INTRA Coding (AIC) mode (see Annex I), "0" off, "1" on; */ offset_in_bits++; /* * Bit 9 Optional Deblocking Filter (DF) mode (see Annex J), "0" off, "1" on; */ offset_in_bits++; /* * Bit 10 Optional Slice Structured (SS) mode (see Annex K), "0" off, "1" on; */ offset_in_bits++; /* * Bit 11 Optional Reference Picture Selection (RPS) mode (see Annex N), "0" off, "1" on; */ offset_in_bits++; /* * Bit 12 Optional Independent Segment Decoding (ISD) mode (see Annex R), "0" off,"1" on; */ offset_in_bits++; /* * Bit 13 Optional Alternative INTER VLC (AIV) mode (see Annex S), "0" off, "1" on; */ offset_in_bits++; /* * Bit 14 Optional Modified Quantization (MQ) mode (see Annex T), "0" off, "1" on; */ offset_in_bits++; /* * Bit 15 Equal to "1" to prevent start code emulation; */ offset_in_bits++; /* * Bit 16 Reserved, shall be equal to "0"; */ offset_in_bits++; /* * Bit 17 Reserved, shall be equal to "0"; */ offset_in_bits++; /* * Bit 18 Reserved, shall be equal to "0". */ offset_in_bits++; proto_tree_add_bits_item( h263_opptype_tree, hf_h263_not_dissected, tvb, saved_bit_offset, offset_in_bits-saved_bit_offset, FALSE); } /* * 5.1.4.3 The mandatory part of PLUSPTYPE when PLUSPTYPE present (MPPTYPE) (9 bits) * Regardless of the value of UFEP, the following 9 bits are also present in PLUSPTYPE: * - Bits 1-3 Picture Type Code: * "000" I-picture (INTRA); * "001" P-picture (INTER); * "010" Improved PB-frame (see Annex M); * "011" B-picture (see Annex O); * "100" EI-picture (see Annex O); * "101" EP-picture (see Annex O); * "110" Reserved; * "111" Reserved; */ proto_tree_add_bits_ret_val( tree, hf_h263_picture_type_code, tvb, offset_in_bits, 3, &picture_type_code, FALSE); offset_in_bits+=3; saved_bit_offset=offset_in_bits; /* * Bit 4 Optional Reference Picture Resampling (RPR) mode (see Annex P), "0" off, "1" on; */ offset_in_bits++; /* * Bit 5 Optional Reduced-Resolution Update (RRU) mode (see Annex Q), "0" off, "1" on; */ offset_in_bits++; /* * Bit 6 Rounding Type (RTYPE) (see 6.1.2); */ offset_in_bits++; /* * Bit 7 Reserved, shall be equal to "0"; */ offset_in_bits++; /* * Bit 8 Reserved, shall be equal to "0"; */ offset_in_bits++; /* * Bit 9 Equal to "1" to prevent start code emulation. */ offset_in_bits++; proto_tree_add_bits_item( tree, hf_h263_not_dissected, tvb, saved_bit_offset, offset_in_bits-saved_bit_offset, FALSE); /* The picture header location of CPM (1 bit) and PSBI (2 bits) * the picture header depends on whether or not PLUSPTYPE is present * (see 5.1.20 and 5.1.21). If PLUSPTYPE is present, then CPM follows * immediately after PLUSPTYPE in the picture header. */ proto_tree_add_bits_ret_val( tree, hf_h263_cpm, tvb, offset_in_bits, 1, &cpm, FALSE); offset_in_bits++; /* 5.1.21 Picture Sub-Bitstream Indicator (PSBI) (2 bits) * only present if Continuous Presence Multipoint and Video * Multiplex mode is indicated by CPM. */ if(cpm==1){ proto_tree_add_bits_item( tree, hf_h263_psbi, tvb, offset_in_bits, 2, FALSE); offset_in_bits+=2; } return offset_in_bits>>3; /* TODO Add the rest of the fields */ /* 5.1.5 Custom Picture Format (CPFMT) (23 bits) * present only if the use of a custom picture format is * signalled in PLUSPTYPE and UFEP is '001'. When present, CPFMT consists of: * Bits 1-4 Pixel Aspect Ratio Code: A 4-bit index to the PAR value in Table 5. For * extended PAR, the exact pixel aspect ratio shall be specified in EPAR * (see 5.1.6); * Bits 5-13 Picture Width Indication: Range [0, ... , 511]; Number of pixels per * line = (PWI + 1) * 4; * Bit 14 Equal to "1" to prevent start code emulation; * Bits 15-23 Picture Height Indication: Range [1, ... , 288]; Number of lines = PHI * 4. */ /* 5.1.6 Extended Pixel Aspect Ratio (EPAR) (16 bits) * A fixed length codeword of 16 bits that is present only if CPFMT is present and extended PAR is * indicated therein. When present, EPAR consists of: * Bits 1-8 PAR Width: "0" is forbidden. The natural binary representation of the PAR * width; * Bits 9-16 PAR Height: "0" is forbidden. The natural binary representation of the PAR * height. */ /* 5.1.7 Custom Picture Clock Frequency Code (CPCFC) (8 bits) * A fixed length codeword of 8 bits that is present only if PLUSPTYPE is present and UFEP is 001 * and a custom picture clock frequency is signalled in PLUSPTYPE. When present, CPCFC consists of: * Bit 1 Clock Conversion Code: "0" indicates a clock conversion factor of 1000 and * "1" indicates 1001; * Bits 2-8 Clock Divisor: "0" is forbidden. The natural binary representation of the value * of the clock divisor. */ /* 5.1.8 Extended Temporal Reference (ETR) (2 bits) * A fixed length codeword of 2 bits which is present only if a custom picture clock frequency is in * use (regardless of the value of UFEP). It is the two MSBs of the 10-bit number defined in 5.1.2. */ /* 5.1.9 Unlimited Unrestricted Motion Vectors Indicator (UUI) (Variable length) * A variable length codeword of 1 or 2 bits that is present only if the optional Unrestricted Motion * Vector mode is indicated in PLUSPTYPE and UFEP is 001. When UUI is present it indicates the * effective limitation of the range of the motion vectors being used. * UUI = "1" The motion vector range is limited according to Tables D.1 and D.2. * UUI = "01" The motion vector range is not limited except by the picture size. */ /* * 5.1.10 Slice Structured Submode bits (SSS) (2 bits) * A fixed length codeword of 2 bits which is present only if the optional Slice Structured mode * (see Annex K) is indicated in PLUSPTYPE and UFEP is 001. If the Slice Structured mode is in use * but UFEP is not 001, the last values sent for SSS shall remain in effect. * - Bit 1 Rectangular Slices, "0" indicates free-running slices, "1" indicates rectangular * slices; * - Bit 2 Arbitrary Slice Ordering, "0" indicates sequential order, "1" indicates arbitrary * order. * 5.1.11 Enhancement Layer Number (ELNUM) (4 bits) * A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR, and Spatial * Scalability mode is in use (regardless of the value of UFEP). The particular enhancement layer is * identified by an enhancement layer number, ELNUM. Picture correspondence between layers is * achieved via the temporal reference. Picture size is either indicated within each enhancement layer * using the existing source format fields or is inferred by the relationship to the reference layer. The * first enhancement layer above the base layer is designated as Enhancement Layer Number 2, and * the base layer has number 1. * 5.1.12 Reference Layer Number (RLNUM) (4 bits) * A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR, and Spatial * Scalability mode is in use (see Annex O) and UFEP is 001. The layer number for the pictures used * as reference anchors is identified by a Reference Layer Number (RLNUM). Time correspondence * between layers is achieved via the temporal reference. * Note that for B-pictures in an enhancement layer having temporally surrounding EI- or EP-pictures * which are present in the same enhancement layer, RLNUM shall be equal to ELNUM * (see Annex O). * 5.1.13 Reference Picture Selection Mode Flags (RPSMF) (3 bits) * A fixed length codeword of 3 bits that is present only if the Reference Picture Selection mode is in * use and UFEP is 001. When present, RPSMF indicates which type of back-channel messages are * needed by the encoder. If the Reference Picture Selection mode is in use but RPSMF is not present, * the last value of RPSMF that was sent shall remain in effect. * - 100: neither ACK nor NACK signals needed; * - 101: need ACK signals to be returned; * - 110: need NACK signals to be returned; * - 111: need both ACK and NACK signals to be returned; * - 000-011: Reserved. * 5.1.14 Temporal Reference for Prediction Indication (TRPI) (1 bit) * A fixed length codeword of 1 bit that is present only if the optional Reference Picture Selection * mode is in use (regardless of the value of UFEP). When present, TRPI indicates the presence of the * following TRP field: * - 0: TRP field is not present; * - 1: TRP field is present. * TRPI shall be 0 whenever the picture header indicates an I- or EI-picture. * 5.1.15 Temporal Reference for Prediction (TRP) (10 bits) * When present (as indicated in TRPI), TRP indicates the Temporal Reference which is used for * prediction of the encoding, except for in the case of B-pictures. For B-pictures, the picture having * the temporal reference TRP is used for the prediction in the forward direction. (Prediction in the * reverse-temporal direction always uses the immediately temporally subsequent picture.) TRP is a * ten-bit number. If a custom picture clock frequency was not in use for the reference picture, the two * MSBs of TRP are zero and the LSBs contain the eight-bit TR found in the picture header of the * reference picture. If a custom picture clock frequency was in use for the reference picture, TRP is a * ten-bit number consisting of the concatenation of ETR and TR from the reference picture header. * When TRP is not present, the most recent temporally previous anchor picture shall be used for * prediction, as when not in the Reference Picture Selection mode. TRP is valid until the next PSC, * GSC, or SSC. * 5.1.16 Back-Channel message Indication (BCI) (Variable length) * A variable length field of one or two bits that is present only if the optional Reference Picture * Selection mode is in use. When set to "1", this signals the presence of the following optional video * Back-Channel Message (BCM) field. "01" indicates the absence or the end of the video backchannel * message field. Combinations of BCM and BCI may not be present, and may be repeated * when present. BCI shall be set to "01" if the videomux submode of the optional Reference Picture * Selection mode is not in use. * 5.1.17 Back-Channel Message (BCM) (Variable length) * The Back-Channel message with syntax as specified in N.4.2, which is present only if the preceding * BCI field is present and is set to "1". * 5.1.18 Reference Picture Resampling Parameters (RPRP) (Variable length) * A variable length field that is present only if the optional Reference Picture Resampling mode bit is * set in PLUSPTYPE. This field carries the parameters of the Reference Picture Resampling mode * (see Annex P). Note that the Reference Picture Resampling mode can also be invoked implicitly by * the occurrence of a picture header for an INTER coded picture having a picture size which differs * from that of the previous encoded picture, in which case the RPRP field is not present and the * Reference Picture Resampling mode bit is not set. */ } /* 5.1.19 Quantizer Information (PQUANT) (5 bits) */ proto_tree_add_bits_item( tree, hf_h263_pquant, tvb, offset_in_bits, 5, FALSE); offset_in_bits = offset_in_bits +5; if (source_format != H263_PLUSPTYPE){ proto_tree_add_bits_ret_val( tree, hf_h263_cpm, tvb, offset_in_bits, 1, &cpm, FALSE); offset_in_bits++; /* 5.1.21 Picture Sub-Bitstream Indicator (PSBI) (2 bits) * only present if Continuous Presence Multipoint and Video * Multiplex mode is indicated by CPM. */ if(cpm==1){ proto_tree_add_bits_item( tree, hf_h263_psbi, tvb, offset_in_bits, 2, FALSE); offset_in_bits = offset_in_bits +2; } } /* 5.1.22 Temporal Reference for B-pictures in PB-frames (TRB) (3/5 bits) * TRB is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame" * It is 3 bits long for standard CIF picture clock frequency and is * extended to 5 bits when a custom picture clock frequency is in use. */ if((PB_frames_mode == 1)||(picture_type_code == 2 )){ if(custom_pcf == 0){ proto_tree_add_bits_item( tree, hf_h263_trb, tvb, offset_in_bits, 3, FALSE); offset_in_bits = offset_in_bits +3; }else{ proto_tree_add_bits_item( tree, hf_h263_trb, tvb, offset_in_bits, 5, FALSE); offset_in_bits = offset_in_bits +5; } } /* 5.1.23 Quantization information for B-pictures in PB-frames (DBQUANT) (2 bits) * DBQUANT is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame" */ if((PB_frames_mode == 1)||(picture_type_code == 2 )){ offset_in_bits = offset_in_bits +2; } /* 5.1.24 Extra Insertion Information (PEI) (1 bit) * A bit which when set to "1" signals the presence of the following optional data field. */ proto_tree_add_bits_ret_val( tree, hf_h263_pei, tvb, offset_in_bits, 1, &pei, FALSE); offset_in_bits++; while(pei==1) { /*5.1.25 Supplemental Enhancement Information (PSUPP) (0/8/16 ... bits) * If PEI is set to "1", then 9 bits follow consisting of 8 bits of data (PSUPP) and then another PEI bit * to indicate if a further 9 bits follow and so on. Encoders shall use PSUPP as specified in Annex L. */ proto_tree_add_bits_item( tree, hf_h263_psupp, tvb, offset_in_bits, 8, FALSE); offset_in_bits+=8; proto_tree_add_bits_ret_val( tree, hf_h263_pei, tvb, offset_in_bits, 1, &pei, FALSE); offset_in_bits++; } /* For the first GOB in each picture (with number 0), no GOB header shall be transmitted. * For all other GOBs, the GOB header may be empty, depending on the encoder strategy. */ /* * 5.3 Macroblock layer * dissect_h263_macroblock_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) */ return offset_in_bits>>3; }
static void gcsna_message_GCSNAServiceReject(proto_item *item, tvbuff_t *tvb, proto_tree *tree, guint *offset) { guint16 cause_val = -1, num_fields = -1, l_offset = -1; proto_tree *subtree = NULL; item = proto_tree_add_item(tree, hf_gcsna_servicereject, tvb, *offset, 1, ENC_NA); subtree = proto_item_add_subtree(item, ett_gcsna_subtree); l_offset = *offset * 8; proto_tree_add_bits_item(subtree, hf_gcsna_rejSequence, tvb, l_offset, 6, ENC_BIG_ENDIAN); l_offset += 6; proto_tree_add_bits_item(subtree, hf_gcsna_cause, tvb, l_offset, 8, ENC_BIG_ENDIAN); cause_val = tvb_get_bits8(tvb, *offset * 8 + 6, 8); l_offset += 8; switch (cause_val) { case 0: case 2: { num_fields = tvb_get_bits8(tvb, l_offset, 8); l_offset += 8; while (num_fields > 0) { proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, l_offset, 5, ENC_BIG_ENDIAN); l_offset += 5; proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, l_offset, 3, ENC_BIG_ENDIAN); l_offset += 3; num_fields--; } if (cause_val == 2) { proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN); l_offset += 8; } break; } case 1: { proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN); l_offset += 8; break; } case 3: { proto_tree_add_bits_item(subtree, hf_gcsna_invalidMessageId, tvb, l_offset, 8, ENC_BIG_ENDIAN); l_offset += 8; break; } /*This Cause Value is not supported in IWS Stack*/ case 5: { num_fields = tvb_get_bits8(tvb, l_offset, 8); l_offset += 8; while (num_fields > 0) { proto_tree_add_bits_item(subtree, hf_gcsna_recordType, tvb, l_offset, 8, ENC_BIG_ENDIAN); l_offset += 8; num_fields--; } break; } default: { proto_tree_add_item(subtree, hf_gcsna_unsupported_reject_seq, tvb, l_offset, -1, ENC_NA); break; } } if (l_offset % 8 == 0) { *offset = (l_offset / 8); } else { *offset = (l_offset / 8) + 1; } }
static void gcsna_message_GCSNA1xCircuitService(proto_item *item, tvbuff_t *tvb, packet_info *pinfo, proto_tree *mainTree, proto_tree *tree, guint *offset) { guint16 alt_gcsna_incl = 0, num_alt_gcsna_opt = -1, iws_incl = 0; guint8 num_res; guint bit_offset = *offset * 8; proto_tree *subtree = NULL; tvbuff_t *new_tvb; /* GCSNAOption 8 bits */ item = proto_tree_add_item(tree, hf_gcsna_gcsna_option, tvb, *offset, 1, ENC_BIG_ENDIAN); subtree = proto_item_add_subtree(item, ett_gcsna_option); proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, bit_offset, 5, ENC_BIG_ENDIAN); bit_offset += 5; proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, bit_offset, 3, ENC_BIG_ENDIAN); bit_offset += 3; alt_gcsna_incl = tvb_get_bits8(tvb, bit_offset, 1); proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOptionIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN); bit_offset += 1; if (alt_gcsna_incl) { num_alt_gcsna_opt = tvb_get_bits8(tvb, bit_offset, 8); proto_tree_add_bits_item(subtree, hf_gcsna_NumaltGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN); bit_offset += 8; while (num_alt_gcsna_opt != 0) { proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN); bit_offset += 8; num_alt_gcsna_opt--; } } iws_incl = tvb_get_bits8(tvb, bit_offset, 1); proto_tree_add_bits_item(subtree, hf_gcsna_iwsidIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN); bit_offset++; if (iws_incl) { proto_tree_add_bits_item(subtree, hf_gcsna_iwsidValue, tvb, bit_offset, 16, ENC_BIG_ENDIAN); bit_offset += 16; } proto_tree_add_bits_item(subtree, hf_gcsna_ackRequired, tvb, bit_offset, 1, ENC_BIG_ENDIAN); bit_offset++; proto_tree_add_bits_item(subtree, hf_gcsna_stopDupDetect, tvb, bit_offset, 1, ENC_BIG_ENDIAN); bit_offset++; proto_tree_add_bits_item(subtree, hf_gcsna_msgSequence, tvb, bit_offset, 6, ENC_BIG_ENDIAN); bit_offset += 6; proto_tree_add_bits_item(subtree, hf_gcsna_NumTLACEncapsulated1xL3PDU, tvb, bit_offset, 2, ENC_BIG_ENDIAN); bit_offset += 2; /* The sender shall include reserved bits to make this message integral number of octets up to TLACEncapsulated1xL3PDU field. * The sender 5 shall set all bits in this field to '0'. The receiver shall ignore this field. */ /* calculate number of reserved bits */ num_res = 8 - (bit_offset & 0x3); proto_tree_add_bits_item(subtree, hf_gcsna_tlacReserved, tvb, bit_offset, num_res, ENC_BIG_ENDIAN); bit_offset = bit_offset + num_res; *offset = bit_offset >> 3; proto_tree_add_item(subtree, hf_gcsna_tlacEncapsulated, tvb, *offset, -1, ENC_NA); if (cdma2k_handle) { new_tvb = tvb_new_subset_length_caplen(tvb, *offset, -1, -1); call_dissector(cdma2k_handle, new_tvb, pinfo, mainTree); } /* set the offset to the end of the message */ *offset += tvb_reported_length_remaining(tvb, *offset); }
/* AU Header dissection */ static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo, proto_tree *ismacryp_tree, guint set_version ) { proto_item *ismacryp_item; proto_tree *ismacryp_header_tree; proto_tree *ismacryp_header_byte_tree; guint16 header_len_bytes = 0; /* total length of non-first AU header in bytes (rounded up) */ gint header_len = 0; /* length of AU headers in bits */ gint cts_flag =0; gint dts_flag =0; gboolean first_au_flag=FALSE; gint bit_offset = 0; /*first determine total AU header length */ /* calculate each AU header length in bits first */ switch (set_version) { case V11: if (selective_encryption) header_len+=8; /* add one byte to header length */ break; case V20: if (selective_encryption || slice_indication || padding_indication) header_len+=8; /* add one byte to header length */ break; default: DISSECTOR_ASSERT_NOT_REACHED(); break; } /* end switch */ header_len+=au_size_length; /* add au size length */ if (poffset->offset_bytes==AU_HEADERS_LENGTH_SIZE){ /*first AU */ header_len+=8*(iv_length); /* add IV length */ header_len+=8*key_indicator_length; /* add key indicator length */ header_len+=au_index_length; /* add AU index length */ first_au_flag = TRUE; } else { /* not the first AU */ if (key_indicator_per_au_flag == TRUE) header_len+=8*key_indicator_length; /* add key indicator length */ header_len+=8*(delta_iv_length); /* add delta IV length */ header_len+=au_index_delta_length; /* add AU delta index length */ } /* CTS flag is present? */ if (cts_delta_length != 0){ /* need to test whether cts_delta_flag is TRUE or FALSE */ cts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit CTS flag */ header_len+=1; /* add CTS flag bit */ if (cts_flag==1) header_len+=cts_delta_length; /* add CTS delta length bits if CTS flag SET */ } /* DTS flag is present? */ if (dts_delta_length != 0){ /* need to test whether dts_delta_flag is TRUE or FALSE */ dts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit DTS flag */ header_len+=1; /* add DTS flag bit */ if (dts_flag==1) header_len+=dts_delta_length; /* add DTS delta length bits if DTS flag SET */ } /* RAP flag present? */ if (random_access_indication != FALSE) header_len+=1; /* add 1 bit RAP flag */ /* stream state indication present */ if (stream_state_indication !=0) header_len+=stream_state_indication; /* add stream state indication bits */ /* convert header_len to bytes (rounded up) */ if (header_len% 8!=0) { header_len_bytes=((header_len)/8)+1; /*add 1 */ } else header_len_bytes=((header_len)/8); /* add AU header tree */ ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_header, tvb, poffset->offset_bytes, header_len_bytes, ENC_NA ); proto_item_append_text(ismacryp_item, ": Length=%d bits", header_len); /* add text to Header tree indicating length */ /* sanity check if actual AU header length is zero bits, which indicates an error */ if ( header_len == 0) /* something wrong */ { proto_item_append_text(ismacryp_item, " Error - zero bit AU header size - check parameters!"); } ismacryp_header_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header); /* ismacryp header analysis */ /* we are being asked for details */ /* Extra 1 Byte Header? */ if ((set_version==V20 && (selective_encryption || slice_indication || padding_indication)) || (set_version==V11 && selective_encryption)){ /* add header byte tree */ ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_header_byte, tvb, poffset->offset_bytes, 1, ENC_NA ); proto_item_append_text(ismacryp_item, ": Length=8 bits"); /* add text to Header byte tree indicating length */ ismacryp_header_byte_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header_byte); /*ismacryp_header_byte_tree */ /* we are being asked for details */ /* tvb is network order, so get MSB bits first, so shift 8 bits and work "backwards" */ add_bits(poffset,7); /*shift 7 bits to get correct bit */ /* AU_is_encrypted bit */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ if (selective_encryption){ /* bit used */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_au_is_encrypted, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit AU_is_encrypted */ } else { /* bit unused */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ } switch (set_version){ /* ISMACryp version? */ case V11: /* Reserved bits */ add_bits(poffset, -7); /* move back 7 bits for reserved bits */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits, tvb, bit_offset, 7, ENC_BIG_ENDIAN); /*fetch 7 bits reserved */ add_bits(poffset,8); /* offset to next byte */ break; case V20: /* Slice_start bit */ add_bits(poffset, -1); /* move back 1 bit for slice_start */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ if (slice_indication){ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_start, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit slice_start */ } else { /* bit unused */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ } add_bits(poffset, -1); /* move back 1 bit for slice_end */ /* Slice_end bit */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ if (slice_indication){ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_end, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit Slice_end */ } else { /* bit unused */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */ } add_bits(poffset, -3); /* move back 3 bits for padding_bitcount */ /* Padding_bitcount bits */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ if (padding_indication){ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_padding_bitcount, tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits padding_bitcount */ } else { /* bits unused */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits, tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits unused */ } add_bits(poffset, -2); /* move back 2 bits for reserved bits */ /* Reserved bits */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits, tvb, bit_offset, 2, ENC_BIG_ENDIAN); /*fetch 2 bits reserved */ add_bits(poffset,8); /* offset to next byte */ break; default: DISSECTOR_ASSERT_NOT_REACHED(); break; } /* end switch set_version */ } /* end selective encryption */ /* IV */ if (first_au_flag == TRUE && iv_length != 0) { ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_iv, tvb, poffset->offset_bytes, iv_length, ENC_NA); proto_item_append_text(ismacryp_item, ": Length=%d bytes",iv_length); /* add IV info */ col_append_fstr( pinfo->cinfo, COL_INFO, ", IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, iv_length,' ')); poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */ } /*Delta IV */ if (first_au_flag == FALSE && delta_iv_length != 0) { ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_delta_iv, tvb, poffset->offset_bytes, delta_iv_length, ENC_NA); proto_item_append_text(ismacryp_item, ": Length=%d bytes",delta_iv_length); /* add delta IV info */ col_append_fstr( pinfo->cinfo, COL_INFO, ", Delta IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, delta_iv_length,' ')); poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */ } /* Key Indicator */ if ( key_indicator_length != 0 && ( first_au_flag == TRUE || key_indicator_per_au_flag == TRUE) ) { /* (first AU or KI for each AU) and non-zero KeyIndicator size */ ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_key_indicator, tvb, poffset->offset_bytes, key_indicator_length, ENC_NA); proto_item_append_text(ismacryp_item,": Length=%d bytes",key_indicator_length); /* add KI info */ col_append_fstr( pinfo->cinfo, COL_INFO, ", KI=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, key_indicator_length,' ')); poffset->offset_bytes+=key_indicator_length; /* add KI length to offset_bytes */ } /* AU size */ if (au_size_length != 0) /* in bits */ { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_size, tvb, bit_offset, au_size_length, ENC_BIG_ENDIAN); proto_item_append_text(ismacryp_item, " bytes: Length=%d bits",au_size_length); /* add AU size info */ /*bit_offset+=au_size_length;*/ add_bits(poffset, au_size_length); } /* AU Index */ if (first_au_flag == TRUE && au_index_length != 0) /* first AU and non-zero AU size */ { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index, tvb, bit_offset, au_index_length, ENC_BIG_ENDIAN); proto_item_append_text(ismacryp_item, " bits: Length=%d bits",au_index_length); /* add AU index info */ /*bit_offset+=au_index_length;*/ add_bits(poffset, au_index_length); } /* AU index delta */ if (first_au_flag == FALSE && au_index_delta_length != 0) /* not first AU and non-zero AU delta size */ { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index_delta, tvb, bit_offset, au_index_delta_length, ENC_BIG_ENDIAN); proto_item_append_text(ismacryp_item, ": Length=%d bits", au_index_delta_length); /* add AU index info */ /*bit_offset+=au_index_delta_length;*/ add_bits(poffset, au_index_delta_length); } /* CTS delta value */ if (cts_delta_length != 0) { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_flag, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read CTS flag */ add_bits(poffset, 1); if (cts_flag==1) { /* now fetch CTS delta value (remember offset 1 bit due to CTS flag) */ bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_delta, tvb, bit_offset, cts_delta_length, ENC_BIG_ENDIAN); /* read CTS delta value */ proto_item_append_text(ismacryp_item, ": Length=%d bits",cts_delta_length); /* add CTS delta info */ add_bits(poffset, cts_delta_length); } } /* DTS delta value */ if (dts_delta_length != 0) { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_flag, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read DTS flag */ add_bits(poffset, 1); /* now fetch DTS delta value (remember offset x bits due to DTS flag) */ if (dts_flag ==1) { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_delta, tvb, bit_offset, dts_delta_length, ENC_BIG_ENDIAN); /* read DTS delta value */ proto_item_append_text(ismacryp_item, ": Length=%d bits",dts_delta_length); /* add DTS delta info */ add_bits(poffset, dts_delta_length); } } /* RAP */ if (random_access_indication != FALSE) { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_rap_flag, tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read RAP flag */ add_bits(poffset, 1); } /*STREAM STATE */ if (stream_state_indication != 0) { bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_stream_state, tvb, bit_offset, stream_state_indication, ENC_BIG_ENDIAN); /* read stream state */ add_bits(poffset, stream_state_indication); } /* end header details */ return poffset; }
static void dissect_ismacryp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint ismacryp_version) { guint set_version; /* ISMACryp version used during dissection */ proto_item *ismacryp_item; proto_tree *ismacryp_tree; proto_tree *ismacryp_message_tree; /* select and display ISMACryp version */ if ((ismacryp_version!=version_type) && override_flag){ /* override -> use manual preference setting */ col_append_str(pinfo->cinfo, COL_INFO, " Manual version"); set_version = version_type; /* set to preference value */ } else { set_version = ismacryp_version; } if (set_version == V11){ col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11); /* display mode */ if (pref_user_mode == FALSE){ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",val_to_str_const(mode, modetypenames, "user mode")); } else { col_append_str(pinfo->cinfo, COL_INFO, ", user mode"); } user_mode = pref_user_mode; } if (set_version == V20){ col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20); user_mode = TRUE; /* display mode */ col_append_str(pinfo->cinfo, COL_INFO, ", user mode"); } /* select correct AU values depending on version & selected mode in preferences menu if not in user_mode */ if (user_mode == TRUE){ /* use values set in preference menu */ au_size_length = pref_au_size_length; au_index_length = pref_au_index_length; au_index_delta_length = pref_au_index_delta_length; cts_delta_length = pref_cts_delta_length; dts_delta_length = pref_dts_delta_length; random_access_indication = pref_random_access_indication; stream_state_indication = pref_stream_state_indication; } /* end if user_mode == TRUE */ if (user_mode == FALSE){ switch (mode){ case AAC_HBR_MODE: au_size_length = 13; au_index_length = 3; au_index_delta_length = 3; cts_delta_length = 0; dts_delta_length = 0; random_access_indication = FALSE; stream_state_indication = 0; break; case MPEG4_VIDEO_MODE: au_size_length = 0; au_index_length = 0; au_index_delta_length = 0; cts_delta_length = 0; dts_delta_length = 22; random_access_indication = TRUE; stream_state_indication = 0; break; case AVC_VIDEO_MODE: au_size_length = 0; au_index_length = 0; au_index_delta_length = 0; cts_delta_length = 0; dts_delta_length = 22; random_access_indication = TRUE; stream_state_indication = 0; break; default: DISSECTOR_ASSERT_NOT_REACHED(); break; } /* end switch */ } /* end if user_mode == FALSE */ /* navigate through buffer */ if (tree) { /* we are being asked for details */ guint16 au_headers_length = 0; /* total length of AU headers */ guint16 totalbits =0; /* keeps track of total number of AU header bits treated (used to determine end of AU headers) */ int deltabits = -1; /* keeps track of extra bits per AU header treated (used to determine end of AU heafers ) */ guint16 totalbit_offset = 0; /* total offset in bits*/ int nbpadding_bits = 0; /* number of padding bits*/ offset_struct s_offset; offset_struct* poffset; guint16 nbmessage_bytes = 0; /*nb of message data bytes */ s_offset.offset_bytes = 0; /* initialise byte offset */ s_offset.offset_bits = 0; /* initialise bit offset */ poffset = &s_offset; ismacryp_item = proto_tree_add_item(tree, proto_ismacryp, tvb, 0, -1, ENC_NA); ismacryp_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp); proto_item_append_text(tree, ", %s", "ismacryp packet"); /* add text to tree */ /* ismacryp_tree analysis */ /* we are being asked for details */ /* get total length of AU headers (first 2 bytes) */ ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_au_headers_length, tvb, poffset->offset_bytes, AU_HEADERS_LENGTH_SIZE, ENC_BIG_ENDIAN ); proto_item_append_text(ismacryp_item, " (bits)"); /* add text to AU Header tree indicating length */ au_headers_length=tvb_get_ntohs(tvb,poffset->offset_bytes); /* 2 byte au headers length */ poffset->offset_bytes+=AU_HEADERS_LENGTH_SIZE; /* ADD HEADER(S) BRANCH */ /* AU Header loop */ totalbits=(poffset->offset_bytes*8)+poffset->offset_bits; while( ((totalbits-8*AU_HEADERS_LENGTH_SIZE)<au_headers_length) && deltabits!=0 ) /* subtract AU headers length bits*/ { poffset=dissect_auheader( tvb, poffset, pinfo, ismacryp_tree, set_version); deltabits=(poffset->offset_bytes*8)+poffset->offset_bits - totalbits; /* if zero this means no actual AU header so exit while loop */ totalbits+=deltabits; } /* reached end of AU Header(s) */ /* sanity check if actual total AU headers length in bits i.e. totalbits is */ /* the same as expected AU headers length from 2 bytes at start of buffer */ if ( (totalbits-8*AU_HEADERS_LENGTH_SIZE) != au_headers_length) /* something wrong */ { proto_item_append_text(ismacryp_item, " Error - expected total AU headers size (%d bits) " "does not match calculated size (%d bits) - check parameters!", au_headers_length,(totalbits-8*AU_HEADERS_LENGTH_SIZE)); } /* add padding if need to byte align */ if (poffset->offset_bits!=0) { totalbit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */ nbpadding_bits = (8-poffset->offset_bits); /* number of padding bits for byte alignment */ ismacryp_item = proto_tree_add_bits_item(ismacryp_tree, hf_ismacryp_padding, tvb, totalbit_offset, nbpadding_bits , ENC_BIG_ENDIAN); /* padding bits */ proto_item_append_text(ismacryp_item, ": Length=%d bits",nbpadding_bits); /* add padding info */ add_bits(poffset, nbpadding_bits); } /* ADD MESSAGE BRANCH */ ismacryp_item = proto_tree_add_item( ismacryp_tree, hf_ismacryp_message, tvb, poffset->offset_bytes, -1, ENC_NA ); ismacryp_message_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_message); proto_item_append_text(ismacryp_item, ", %s", "Encrypted data"); /* add text to Message tree */ nbmessage_bytes = tvb_reported_length_remaining(tvb, poffset->offset_bytes); proto_item_append_text(ismacryp_item, ", Length= %d bytes", nbmessage_bytes ); /* add length of message */ /* ismacryp message tree analysis (encrypted AUs) */ if (ismacryp_message_tree) { /* we are being asked for details */ poffset->offset_bytes+= nbmessage_bytes; /* */ } /* end message details */ /* end ismacryp tree details */ } /* end if tree */ }
// content format static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { // your variable definitions go here int bitoffset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors"); // Clear out stuff in the info column col_clear(pinfo->cinfo,COL_INFO); if (tree) { // in case that someone wants to know some details of our protocol // spawn a subtree and cut the sequence in readable parts proto_item *pi = NULL; proto_item *ti = NULL; proto_tree *mysensors_tree = NULL; tvbuff_t* tvb_next; guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack; MySensors_Command commandType; gchar* info; ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA); mysensors_tree = proto_item_add_subtree(ti, ett_mysensors); proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding); last = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding); sender = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding); dest = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding); payloadLen = tvb_get_bits8(tvb, bitoffset, 5); bitoffset += 5; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding); bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding); dataType = tvb_get_bits8(tvb, bitoffset, 3); // Type of payload bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding); isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding); reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding); commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3); bitoffset += 3; type = tvb_get_guint8(tvb, bitoffset>>3); proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding); sensor = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; // Create tvb for the payload. tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen); info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next ); col_add_str(pinfo->cinfo, COL_INFO, info); proto_item_append_text(ti, " - %s", info); col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender); col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest); // Pass payload to generic data dissector call_dissector(data_handle, tvb_next, pinfo, mysensors_tree); } }
/* common dissector function for dissecting TFP payloads */ static void dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint byte_offset = 0; gint bit_offset = 48; guint8 hv_tfp_len; guint8 hv_tfp_fid; guint8 hv_tfp_seq; gchar tfp_uid_string[BASE58_MAX_STR_SIZE]; base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]); hv_tfp_len = tvb_get_guint8(tvb, byte_offset_len); hv_tfp_fid = tvb_get_guint8(tvb, byte_offset_fid); hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq); col_add_fstr(pinfo->cinfo, COL_INFO, "UID: %s, Len: %d, FID: %d, Seq: %d", &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq); /* call for details */ if (tree) { proto_tree *tfp_tree; proto_item *ti; ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1, "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d", &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq); tfp_tree = proto_item_add_subtree(ti, ett_tfp); /* Use ...string_format_value() so we can show the complete generated string but specify */ /* the field length as being just the 4 bytes from which the string is generated. */ ti = proto_tree_add_string_format_value(tfp_tree, hf_tfp_uid, tvb, byte_offset, byte_count_tfp_uid, &tfp_uid_string[0], "%s", &tfp_uid_string[0]); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(tfp_tree, hf_tfp_uid_numeric, tvb, byte_offset, byte_count_tfp_uid, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_uid; proto_tree_add_item(tfp_tree, hf_tfp_len, tvb, byte_offset, byte_count_tfp_len, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_len; proto_tree_add_item(tfp_tree, hf_tfp_fid, tvb, byte_offset, byte_count_tfp_fid, ENC_LITTLE_ENDIAN); byte_offset += byte_count_tfp_fid; proto_tree_add_bits_item(tfp_tree, hf_tfp_seq, tvb, bit_offset, bit_count_tfp_seq, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_seq; proto_tree_add_bits_item(tfp_tree, hf_tfp_r, tvb, bit_offset, bit_count_tfp_r, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_r; proto_tree_add_bits_item(tfp_tree, hf_tfp_a, tvb, bit_offset, bit_count_tfp_a, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_a; proto_tree_add_bits_item(tfp_tree, hf_tfp_oo, tvb, bit_offset, bit_count_tfp_oo, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_oo; proto_tree_add_bits_item(tfp_tree, hf_tfp_e, tvb, bit_offset, bit_count_tfp_e, ENC_LITTLE_ENDIAN); bit_offset += bit_count_tfp_e; proto_tree_add_bits_item(tfp_tree, hf_tfp_future_use, tvb, bit_offset, bit_count_tfp_future_use, ENC_LITTLE_ENDIAN); /*bit_offset += bit_count_tfp_future_use;*/ if ((tvb_reported_length(tvb)) > 8) { byte_offset += byte_count_tfp_flags; proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA); } } }