wireshark/epan/dissectors/packet-iuup.c

1014 lines
44 KiB
C
Raw Normal View History

/* packet-iuup.c
* IuUP Protocol 3GPP TS 25.415 V6.2.0 (2005-03)
*
* (c) 2005 Luis E. Garcia Ontanon <luis@ontanon.org>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/*
Patch by Polystar (Peter Vestman, Petter Edblom):
Corrected rfci handling in rate control messages
Added crc6 and crc10 checks for header and payload
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/conversation.h>
#include <epan/crc10-tvb.h>
#include <wsutil/crc10.h>
#include <wsutil/crc6.h>
void proto_reg_handoff_iuup(void);
void proto_register_iuup(void);
typedef struct _iuup_rfci_t {
guint id;
guint sum_len;
guint num_of_subflows;
struct {
guint len;
} subflow[8];
struct _iuup_rfci_t* next;
} iuup_rfci_t;
typedef struct {
guint32 id;
guint num_of_subflows;
iuup_rfci_t* rfcis;
iuup_rfci_t* last_rfci;
} iuup_circuit_t;
static int proto_iuup = -1;
static int hf_iuup_direction = -1;
static int hf_iuup_circuit_id = -1;
static int hf_iuup_pdu_type = -1;
static int hf_iuup_frame_number = -1;
static int hf_iuup_fqc = -1;
static int hf_iuup_rfci = -1;
static int hf_iuup_hdr_crc = -1;
static int hf_iuup_payload_crc = -1;
static int hf_iuup_ack_nack = -1;
static int hf_iuup_frame_number_t14 = -1;
static int hf_iuup_mode_version = -1;
static int hf_iuup_procedure_indicator = -1;
static int hf_iuup_error_cause_val = -1;
static int hf_iuup_init_ti = -1;
static int hf_iuup_init_subflows_per_rfci = -1;
static int hf_iuup_init_chain_ind = -1;
static int hf_iuup_error_distance = -1;
static int hf_iuup_errorevt_cause_val = -1;
static int hf_iuup_time_align = -1;
static int hf_iuup_spare_bytes = -1;
static int hf_iuup_spare_03 = -1;
/* static int hf_iuup_spare_0f = -1; */
/* static int hf_iuup_spare_c0 = -1; */
static int hf_iuup_spare_e0 = -1;
static int hf_iuup_spare_ff = -1;
static int hf_iuup_delay = -1;
static int hf_iuup_advance = -1;
static int hf_iuup_delta = -1;
static int hf_iuup_mode_versions = -1;
static int hf_iuup_mode_versions_a[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int hf_iuup_data_pdu_type = -1;
static int hf_iuup_num_rfci_ind = -1;
static int hf_iuup_payload = -1;
static int hf_iuup_init_rfci_ind = -1;
static int hf_iuup_init_rfci[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int hf_iuup_init_rfci_flow_len[64][8] = {
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1}
};
static int hf_iuup_init_rfci_li[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int hf_iuup_init_rfci_lri[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int hf_iuup_init_ipti[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static int hf_iuup_rfci_subflow[64][8] = {
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1}
};
static int hf_iuup_rfci_ratectl[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
static gint ett_iuup = -1;
static gint ett_rfci = -1;
static gint ett_ipti = -1;
static gint ett_support = -1;
static gint ett_time = -1;
static gint ett_rfciinds = -1;
static gint ett_payload = -1;
static gint ett_payload_subflows = -1;
static expert_field ei_iuup_hdr_crc_bad = EI_INIT;
static expert_field ei_iuup_payload_crc_bad = EI_INIT;
static expert_field ei_iuup_payload_undecoded = EI_INIT;
static expert_field ei_iuup_error_response = EI_INIT;
static expert_field ei_iuup_ack_nack = EI_INIT;
static expert_field ei_iuup_time_align = EI_INIT;
static expert_field ei_iuup_procedure_indicator = EI_INIT;
static expert_field ei_iuup_pdu_type = EI_INIT;
static wmem_map_t* circuits = NULL;
static dissector_handle_t iuup_handle;
static gboolean dissect_fields = FALSE;
static gboolean two_byte_pseudoheader = FALSE;
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
static range_t *global_dynamic_payload_type_range = 0;
#define PDUTYPE_DATA_WITH_CRC 0
#define PDUTYPE_DATA_NO_CRC 1
#define PDUTYPE_DATA_CONTROL_PROC 14
static const value_string iuup_pdu_types[] = {
{PDUTYPE_DATA_WITH_CRC,"Data with CRC"},
{PDUTYPE_DATA_NO_CRC,"Data without CRC"},
{PDUTYPE_DATA_CONTROL_PROC,"Control Procedure"},
{0,NULL}
};
static const value_string iuup_colinfo_pdu_types[] = {
{PDUTYPE_DATA_WITH_CRC,"Data (CRC)"},
{PDUTYPE_DATA_NO_CRC,"Data (no CRC)"},
{PDUTYPE_DATA_CONTROL_PROC,""},
{0,NULL}
};
#define ACKNACK_ACK 0x4
#define ACKNACK_NACK 0x8
#define ACKNACK_RESERVED 0xc
#define ACKNACK_PROC 0x0
static const value_string iuup_acknack_vals[] = {
{ACKNACK_PROC >> 2,"Procedure"},
{ACKNACK_ACK >> 2,"ACK"},
{ACKNACK_NACK >> 2,"NACK"},
{ACKNACK_RESERVED >> 2,"Reserved"},
{0,NULL}
};
static const value_string iuup_colinfo_acknack_vals[] = {
{ACKNACK_PROC,""},
{ACKNACK_ACK,"ACK "},
{ACKNACK_NACK,"NACK "},
{ACKNACK_RESERVED,"Reserved "},
{0,NULL}
};
#define PROC_INIT 0
#define PROC_RATE 1
#define PROC_TIME 2
#define PROC_ERROR 3
static const value_string iuup_procedures[] = {
{PROC_INIT,"Initialization"},
{PROC_RATE,"Rate Control"},
{PROC_TIME,"Time Alignment"},
{PROC_ERROR,"Error Event"},
{4,"Reserved(4)"},
{5,"Reserved(5)"},
{6,"Reserved(6)"},
{7,"Reserved(7)"},
{8,"Reserved(8)"},
{9,"Reserved(9)"},
{10,"Reserved(10)"},
{11,"Reserved(11)"},
{12,"Reserved(12)"},
{13,"Reserved(13)"},
{14,"Reserved(14)"},
{15,"Reserved(15)"},
{0,NULL}
};
static const value_string iuup_colinfo_procedures[] = {
{PROC_INIT,"Initialization "},
{PROC_RATE,"Rate Control "},
{PROC_TIME,"Time Alignment "},
{PROC_ERROR,"Error Event "},
{0,NULL}
};
static const value_string iuup_error_distances[] = {
{0, "Reporting local error"},
{1, "First forwarding of error event report"},
{2, "Second forwarding of error event report"},
{3, "Reserved"},
{0,NULL}
};
static const value_string iuup_error_causes[] = {
{0, "CRC error of frame header"},
{1, "CRC error of frame payload"},
{2, "Unexpected frame number"},
{3, "Frame loss"},
{4, "PDU type unknown"},
{5, "Unknown procedure"},
{6, "Unknown reserved value"},
{7, "Unknown field"},
{8, "Frame too short"},
{9, "Missing fields"},
{16, "Unexpected PDU type"},
{18, "Unexpected procedure"},
{19, "Unexpected RFCI"},
{20, "Unexpected value"},
{42, "Initialisation failure"},
{43, "Initialisation failure (network error, timer expiry)"},
{44, "Initialisation failure (Iu UP function error, repeated NACK)"},
{45, "Rate control failure"},
{46, "Error event failure"},
{47, "Time Alignment not supported"},
{48, "Requested Time Alignment not possible"},
{49, "Iu UP Mode version not supported"},
{0,NULL}
};
static const value_string iuup_rfci_indicator[] = {
{0, "RFCI allowed"},
{1, "RFCI barred"},
{0,NULL}
};
static const value_string iuup_ti_vals[] = {
{0, "IPTIs not present"},
{1, "IPTIs present in frame"},
{0,NULL}
};
static const value_string iuup_mode_version_support[] = {
{0, "not supported"},
{1, "supported"},
{0,NULL}
};
static const value_string iuup_init_rfci_li_vals[] = {
{0, "one octet used"},
{1, "two octets used"},
{0,NULL}
};
static const value_string iuup_init_chain_ind_vals[] = {
{0, "this frame is the last frame for the procedure"},
{1, "additional frames will be sent for the procedure"},
{0,NULL}
};
static const value_string iuup_init_lri_vals[] = {
{0, "Not last RFCI"},
{1, "Last RFCI in current frame"},
{0,NULL}
};
static const value_string iuup_payload_pdu_type[] = {
{0, "PDU type 0"},
{1, "PDU type 1"},
{0,NULL}
};
static const value_string iuup_fqcs[] = {
{0, "Frame Good"},
{1, "Frame BAD"},
{2, "Frame bad due to radio"},
{3, "spare"},
{0,NULL}
};
static proto_item*
iuup_proto_tree_add_bits(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int bit_offset, guint bits, guint8** buf) {
static const guint8 masks[] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
int len = (bits + bit_offset)/8 + (((bits + bit_offset)%8) ? 0 : 1);
guint8* shifted_buffer;
proto_item* pi;
int i;
DISSECTOR_ASSERT(bit_offset < 8);
shifted_buffer = (guint8 *)tvb_memdup(wmem_packet_scope(),tvb,offset,len+1);
for(i = 0; i < len; i++) {
shifted_buffer[i] <<= bit_offset;
shifted_buffer[i] |= (shifted_buffer[i+1] & masks[bit_offset]) >> (8 - bit_offset);
}
shifted_buffer[len] <<= bit_offset;
shifted_buffer[len] &= masks[(bits + bit_offset)%8];
if (buf)
*buf = shifted_buffer;
pi = proto_tree_add_bytes(tree, hf, tvb, offset, len + (((bits + bit_offset)%8) ? 1 : 0) , shifted_buffer);
proto_item_append_text(pi, " (%i Bits)", bits);
return pi;
}
static void dissect_iuup_payload(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint rfci_id _U_, int offset, guint32 circuit_id) {
iuup_circuit_t* iuup_circuit;
iuup_rfci_t *rfci;
int last_offset = tvb_reported_length(tvb) - 1;
guint bit_offset = 0;
proto_item* pi;
pi = proto_tree_add_item(tree,hf_iuup_payload,tvb,offset,-1,ENC_NA);
if ( ! dissect_fields ) {
return;
} else if ( ! circuit_id
|| ! ( iuup_circuit = (iuup_circuit_t *)wmem_map_lookup(circuits,GUINT_TO_POINTER(circuit_id)) ) ) {
expert_add_info(pinfo, pi, &ei_iuup_payload_undecoded);
return;
}
for(rfci = iuup_circuit->rfcis; rfci; rfci = rfci->next)
if ( rfci->id == rfci_id )
break;
if (!rfci) {
expert_add_info(pinfo, pi, &ei_iuup_payload_undecoded);
return;
}
tree = proto_item_add_subtree(pi,ett_payload);
do {
guint i;
guint subflows = rfci->num_of_subflows;
proto_tree* flow_tree;
flow_tree = proto_tree_add_subtree(tree,tvb,offset,-1,ett_payload_subflows,NULL,"Payload Frame");
bit_offset = 0;
for(i = 0; i < subflows; i++) {
if (! rfci->subflow[i].len)
continue;
iuup_proto_tree_add_bits(flow_tree, hf_iuup_rfci_subflow[rfci->id][i], tvb,
offset + (bit_offset/8),
bit_offset % 8,
rfci->subflow[i].len,
NULL);
bit_offset += rfci->subflow[i].len;
}
offset += (bit_offset / 8) + ((bit_offset % 8) ? 1 : 0);
} while (offset <= last_offset);
}
static guint dissect_rfcis(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, int* offset, iuup_circuit_t* iuup_circuit) {
proto_item* pi;
proto_tree* pt;
guint8 oct;
guint c = 0;
guint i;
do {
iuup_rfci_t *rfci = wmem_new0(wmem_file_scope(), iuup_rfci_t);
guint len = 0;
DISSECTOR_ASSERT(c < 64);
pi = proto_tree_add_item(tree,hf_iuup_init_rfci_ind,tvb,*offset,-1,ENC_NA);
pt = proto_item_add_subtree(pi,ett_rfci);
proto_tree_add_item(pt,hf_iuup_init_rfci_lri[c],tvb,*offset,1,ENC_BIG_ENDIAN);
proto_tree_add_item(pt,hf_iuup_init_rfci_li[c],tvb,*offset,1,ENC_BIG_ENDIAN);
proto_tree_add_item(pt,hf_iuup_init_rfci[c],tvb,*offset,1,ENC_BIG_ENDIAN);
oct = tvb_get_guint8(tvb,*offset);
rfci->id = oct & 0x3f;
rfci->num_of_subflows = iuup_circuit->num_of_subflows;
len = (oct & 0x40) ? 2 : 1;
proto_item_set_text(pi,"RFCI %i Initialization",rfci->id);
proto_item_set_len(pi,(len*iuup_circuit->num_of_subflows)+1);
(*offset)++;
for(i = 0; i < iuup_circuit->num_of_subflows; i++) {
guint subflow_len;
if (len == 2) {
subflow_len = tvb_get_ntohs(tvb,*offset);
} else {
subflow_len = tvb_get_guint8(tvb,*offset);
}
rfci->subflow[i].len = subflow_len;
rfci->sum_len += subflow_len;
proto_tree_add_uint(pt,hf_iuup_init_rfci_flow_len[c][i],tvb,*offset,len,subflow_len);
(*offset) += len;
}
if (iuup_circuit->last_rfci) {
iuup_circuit->last_rfci = iuup_circuit->last_rfci->next = rfci;
} else {
iuup_circuit->last_rfci = iuup_circuit->rfcis = rfci;
}
c++;
} while ( ! (oct & 0x80) );
return c - 1;
}
static void dissect_iuup_init(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint32 circuit_id) {
int offset = 4;
guint8 oct = tvb_get_guint8(tvb,offset);
guint n = (oct & 0x0e) >> 1;
gboolean ti = oct & 0x10;
guint i;
guint rfcis;
proto_item* pi;
proto_tree* support_tree = NULL;
proto_tree* iptis_tree;
iuup_circuit_t* iuup_circuit = NULL;
if (circuit_id) {
iuup_circuit = (iuup_circuit_t *)wmem_map_lookup(circuits,GUINT_TO_POINTER(circuit_id));
if (iuup_circuit) {
wmem_map_remove(circuits,GUINT_TO_POINTER(circuit_id));
}
iuup_circuit = wmem_new0(wmem_file_scope(), iuup_circuit_t);
} else {
iuup_circuit = wmem_new0(wmem_packet_scope(), iuup_circuit_t);
}
iuup_circuit->id = circuit_id;
iuup_circuit->num_of_subflows = n;
iuup_circuit->rfcis = NULL;
iuup_circuit->last_rfci = NULL;
if (circuit_id) {
wmem_map_insert(circuits,GUINT_TO_POINTER(iuup_circuit->id),iuup_circuit);
}
if (tree) {
proto_tree_add_item(tree,hf_iuup_spare_e0,tvb,offset,1,ENC_BIG_ENDIAN);
proto_tree_add_item(tree,hf_iuup_init_ti,tvb,offset,1,ENC_BIG_ENDIAN);
proto_tree_add_item(tree,hf_iuup_init_subflows_per_rfci,tvb,offset,1,ENC_BIG_ENDIAN);
proto_tree_add_item(tree,hf_iuup_init_chain_ind,tvb,offset,1,ENC_BIG_ENDIAN);
}
offset++;
rfcis = dissect_rfcis(tvb, pinfo, tree, &offset, iuup_circuit);
if (!tree) return;
if (ti) {
iptis_tree = proto_tree_add_subtree(tree,tvb,offset,(rfcis/2)+(rfcis%2),ett_ipti,NULL,"IPTIs");
for (i = 0; i <= rfcis; i++) {
proto_tree_add_item(iptis_tree,hf_iuup_init_ipti[i],tvb,offset,1,ENC_BIG_ENDIAN);
if ((i%2)) {
offset++;
}
}
if ((i%2)) {
offset++;
}
}
if (tree) {
pi = proto_tree_add_item(tree,hf_iuup_mode_versions,tvb,offset,2,ENC_BIG_ENDIAN);
support_tree = proto_item_add_subtree(pi,ett_support);
for (i = 0; i < 16; i++) {
proto_tree_add_item(support_tree,hf_iuup_mode_versions_a[i],tvb,offset,2,ENC_BIG_ENDIAN);
}
}
offset += 2;
proto_tree_add_item(tree,hf_iuup_data_pdu_type,tvb,offset,1,ENC_BIG_ENDIAN);
}
static void dissect_iuup_ratectl(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree) {
guint num = tvb_get_guint8(tvb,4) & 0x3f;
guint i;
proto_item* pi;
proto_tree* inds_tree;
int offset = 4;
pi = proto_tree_add_item(tree,hf_iuup_num_rfci_ind,tvb,4,1,ENC_BIG_ENDIAN);
inds_tree = proto_item_add_subtree(pi,ett_rfciinds);
for (i = 0; i < num; i++) {
if (! (i % 8) ) offset++;
proto_tree_add_item(inds_tree,hf_iuup_rfci_ratectl[i],tvb,offset,1,ENC_BIG_ENDIAN);
}
}
static void add_hdr_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree, guint16 crccheck)
{
proto_item *crc_item;
crc_item = proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,ENC_BIG_ENDIAN);
if (crccheck) {
proto_item_append_text(crc_item, "%s", " [incorrect]");
expert_add_info(pinfo, crc_item, &ei_iuup_hdr_crc_bad);
}
}
static guint16
update_crc10_by_bytes_iuup(tvbuff_t *tvb, int offset, int length)
{
guint16 crc10;
guint16 extra_16bits;
guint8 extra_8bits[2];
crc10 = update_crc10_by_bytes_tvb(0, tvb, offset + 2, length);
extra_16bits = tvb_get_ntohs(tvb, offset) & 0x3FF;
extra_8bits[0] = extra_16bits >> 2;
extra_8bits[1] = (extra_16bits << 6) & 0xFF;
crc10 = update_crc10_by_bytes(crc10, extra_8bits, 2);
return crc10;
}
static void add_payload_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree)
{
proto_item *crc_item;
int length = tvb_reported_length(tvb);
guint16 crccheck = update_crc10_by_bytes_iuup(tvb, 2, length - 4);
crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,ENC_BIG_ENDIAN);
if (crccheck) {
proto_item_append_text(crc_item, "%s", " [incorrect]");
expert_add_info(pinfo, crc_item, &ei_iuup_payload_crc_bad);
}
}
#define ACKNACK_MASK 0x0c
#define PROCEDURE_MASK 0x0f
#define FQC_MASK 0xc0
#define PDUTYPE_MASK 0xf0
static int dissect_iuup(tvbuff_t* tvb_in, packet_info* pinfo, proto_tree* tree, void* data _U_) {
proto_item* pi;
proto_item* iuup_item = NULL;
proto_item* pdutype_item = NULL;
proto_tree* iuup_tree = NULL;
proto_item* proc_item = NULL;
proto_item* ack_item = NULL;
guint8 first_octet;
guint8 second_octet;
guint8 octet_array[2];
guint8 pdutype;
guint phdr = 0;
guint16 hdrcrc6;
guint16 crccheck;
tvbuff_t* tvb = tvb_in;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IuUP");
if (two_byte_pseudoheader) {
int len = tvb_reported_length(tvb_in) - 2;
phdr = tvb_get_ntohs(tvb,0);
proto_tree_add_item(tree,hf_iuup_direction,tvb,0,2,ENC_BIG_ENDIAN);
proto_tree_add_item(tree,hf_iuup_circuit_id,tvb,0,2,ENC_BIG_ENDIAN);
phdr &= 0x7fff;
conversation_create_endpoint_by_id(pinfo, ENDPOINT_IUUP, phdr, 0);
tvb = tvb_new_subset_length(tvb_in,2,len);
}
octet_array[0] = first_octet = tvb_get_guint8(tvb,0);
octet_array[1] = second_octet = tvb_get_guint8(tvb,1);
hdrcrc6 = tvb_get_guint8(tvb, 2) >> 2;
crccheck = crc6_0X6F(hdrcrc6, octet_array, 2);
pdutype = ( first_octet & PDUTYPE_MASK ) >> 4;
if (tree) {
iuup_item = proto_tree_add_item(tree,proto_iuup,tvb,0,-1,ENC_NA);
iuup_tree = proto_item_add_subtree(iuup_item,ett_iuup);
pdutype_item = proto_tree_add_item(iuup_tree,hf_iuup_pdu_type,tvb,0,1,ENC_BIG_ENDIAN);
}
col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pdutype, iuup_colinfo_pdu_types, "Unknown PDU Type(%u) "));
switch(pdutype) {
case PDUTYPE_DATA_WITH_CRC:
col_append_fstr(pinfo->cinfo, COL_INFO,"FN: %x RFCI: %u", (guint)(first_octet & 0x0f) ,(guint)(second_octet & 0x3f));
proto_tree_add_item(iuup_tree,hf_iuup_frame_number,tvb,0,1,ENC_BIG_ENDIAN);
pi = proto_tree_add_item(iuup_tree,hf_iuup_fqc,tvb,1,1,ENC_BIG_ENDIAN);
if (first_octet & FQC_MASK) {
expert_add_info(pinfo, pi, &ei_iuup_error_response);
}
proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,ENC_BIG_ENDIAN);
add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
add_payload_crc(tvb, pinfo, iuup_tree);
dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,4, conversation_get_endpoint_by_id(pinfo, ENDPOINT_IUUP, USE_LAST_ENDPOINT));
return tvb_captured_length(tvb);
case PDUTYPE_DATA_NO_CRC:
col_append_fstr(pinfo->cinfo, COL_INFO," RFCI %u", (guint)(second_octet & 0x3f));
proto_tree_add_item(iuup_tree,hf_iuup_frame_number,tvb,0,1,ENC_BIG_ENDIAN);
pi = proto_tree_add_item(iuup_tree,hf_iuup_fqc,tvb,1,1,ENC_BIG_ENDIAN);
if (first_octet & FQC_MASK) {
expert_add_info(pinfo, pi, &ei_iuup_error_response);
}
proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,ENC_BIG_ENDIAN);
add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,3, conversation_get_endpoint_by_id(pinfo, ENDPOINT_IUUP, USE_LAST_ENDPOINT));
return tvb_captured_length(tvb);
case PDUTYPE_DATA_CONTROL_PROC:
if (tree) {
ack_item = proto_tree_add_item(iuup_tree,hf_iuup_ack_nack,tvb,0,1,ENC_BIG_ENDIAN);
proto_tree_add_item(iuup_tree,hf_iuup_frame_number_t14,tvb,0,1,ENC_BIG_ENDIAN);
proto_tree_add_item(iuup_tree,hf_iuup_mode_version,tvb,1,1,ENC_BIG_ENDIAN);
proc_item = proto_tree_add_item(iuup_tree,hf_iuup_procedure_indicator,tvb,1,1,ENC_BIG_ENDIAN);
add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
}
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(first_octet & ACKNACK_MASK,
iuup_colinfo_acknack_vals, "[action:%u] "));
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(second_octet & PROCEDURE_MASK,
iuup_colinfo_procedures, "[proc:%u] "));
switch ( first_octet & ACKNACK_MASK ) {
case ACKNACK_ACK:
switch(second_octet & PROCEDURE_MASK) {
case PROC_INIT:
proto_tree_add_item(iuup_tree,hf_iuup_spare_03,tvb,2,1,ENC_BIG_ENDIAN);
proto_tree_add_item(iuup_tree,hf_iuup_spare_ff,tvb,3,1,ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
case PROC_RATE:
dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
return tvb_captured_length(tvb);
case PROC_TIME:
case PROC_ERROR:
break;
default:
expert_add_info(pinfo, proc_item, &ei_iuup_procedure_indicator);
return tvb_captured_length(tvb);
}
break;
case ACKNACK_NACK:
pi = proto_tree_add_item(iuup_tree,hf_iuup_error_cause_val,tvb,4,1,ENC_BIG_ENDIAN);
expert_add_info(pinfo, pi, &ei_iuup_error_response);
return tvb_captured_length(tvb);
case ACKNACK_RESERVED:
expert_add_info(pinfo, ack_item, &ei_iuup_ack_nack);
return tvb_captured_length(tvb);
case ACKNACK_PROC:
break;
}
switch( second_octet & PROCEDURE_MASK ) {
case PROC_INIT:
add_payload_crc(tvb, pinfo, iuup_tree);
dissect_iuup_init(tvb,pinfo,iuup_tree, conversation_get_endpoint_by_id(pinfo, ENDPOINT_IUUP, USE_LAST_ENDPOINT));
return tvb_captured_length(tvb);
case PROC_RATE:
add_payload_crc(tvb, pinfo, iuup_tree);
dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
return tvb_captured_length(tvb);
case PROC_TIME:
{
proto_tree* time_tree;
guint ta;
ta = tvb_get_guint8(tvb,4);
pi = proto_tree_add_item(iuup_tree,hf_iuup_time_align,tvb,4,1,ENC_BIG_ENDIAN);
time_tree = proto_item_add_subtree(pi,ett_time);
if (ta >= 1 && ta <= 80) {
pi = proto_tree_add_uint(time_tree,hf_iuup_delay,tvb,4,1,ta * 500);
proto_item_set_generated(pi);
pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((gfloat)((gint)(ta) * 500))/(gfloat)1000000.0);
proto_item_set_generated(pi);
} else if (ta >= 129 && ta <= 208) {
pi = proto_tree_add_uint(time_tree,hf_iuup_advance,tvb,4,1,(ta-128) * 500);
proto_item_set_generated(pi);
pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((gfloat)((gint)(-(((gint)ta)-128))) * 500)/(gfloat)1000000.0);
proto_item_set_generated(pi);
} else {
expert_add_info(pinfo, pi, &ei_iuup_time_align);
}
proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,ENC_NA);
return tvb_captured_length(tvb);
}
case PROC_ERROR:
col_append_str(pinfo->cinfo, COL_INFO, val_to_str(tvb_get_guint8(tvb,4) & 0x3f,iuup_error_causes,"Unknown (%u)"));
proto_tree_add_item(iuup_tree,hf_iuup_error_distance,tvb,4,1,ENC_BIG_ENDIAN);
pi = proto_tree_add_item(iuup_tree,hf_iuup_errorevt_cause_val,tvb,4,1,ENC_BIG_ENDIAN);
expert_add_info(pinfo, pi, &ei_iuup_error_response);
proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,ENC_NA);
return tvb_captured_length(tvb);
default: /* bad */
expert_add_info(pinfo, proc_item, &ei_iuup_procedure_indicator);
return tvb_captured_length(tvb);
}
default:
expert_add_info(pinfo, pdutype_item, &ei_iuup_pdu_type);
break;
}
return tvb_captured_length(tvb);
}
static gboolean dissect_iuup_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
int len = tvb_captured_length(tvb);
guint8 first_octet = tvb_get_guint8(tvb,0);
guint8 second_octet = tvb_get_guint8(tvb,1);
guint8 octet_array[] = {first_octet, second_octet};
guint16 hdrcrc6 = tvb_get_guint8(tvb, 2) >> 2;
if (crc6_0X6F(hdrcrc6, octet_array, second_octet)) return FALSE;
switch ( first_octet & 0xf0 ) {
case 0x00: {
if (len<7) return FALSE;
if (update_crc10_by_bytes_iuup(tvb, 4, len-4) ) return FALSE;
break;
}
case 0x10:
/* a FALSE positive factory */
if (len<5) return FALSE;
break;
case 0xe0:
if (len<5) return FALSE;
if( (second_octet & 0x0f) > 3) return FALSE;
break;
default:
return FALSE;
}
dissect_iuup(tvb, pinfo, tree, data);
return TRUE;
}
static int find_iuup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
int len = tvb_captured_length(tvb);
int offset = 0;
while (len > 3) {
if ( dissect_iuup_heur(tvb_new_subset_remaining(tvb,offset), pinfo, tree, data) )
return tvb_captured_length(tvb);
offset++;
len--;
}
call_data_dissector(tvb, pinfo, tree);
return tvb_captured_length(tvb);
}
void proto_reg_handoff_iuup(void) {
static gboolean iuup_prefs_initialized = FALSE;
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
static range_t *saved_dynamic_payload_type_range = NULL;
if (!iuup_prefs_initialized) {
dissector_add_string("rtp_dyn_payload_type","VND.3GPP.IUFP", iuup_handle);
iuup_prefs_initialized = TRUE;
} else {
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
dissector_delete_uint_range("rtp.pt", saved_dynamic_payload_type_range, iuup_handle);
wmem_free(wmem_epan_scope(), saved_dynamic_payload_type_range);
}
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
saved_dynamic_payload_type_range = range_copy(wmem_epan_scope(), global_dynamic_payload_type_range);
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
range_remove_value(wmem_epan_scope(), &saved_dynamic_payload_type_range, 0);
dissector_add_uint_range("rtp.pt", saved_dynamic_payload_type_range, iuup_handle);
}
#define HFS_RFCI(i) \
{ &hf_iuup_rfci_ratectl[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, VALS(iuup_rfci_indicator),0x80>>(i%8),NULL,HFILL}}, \
{ &hf_iuup_init_rfci[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][0], { "RFCI " #i " Flow 0 Len", "iuup.rfci."#i".flow.0.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][1], { "RFCI " #i " Flow 1 Len", "iuup.rfci."#i".flow.1.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][2], { "RFCI " #i " Flow 2 Len", "iuup.rfci."#i".flow.2.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][3], { "RFCI " #i " Flow 3 Len", "iuup.rfci."#i".flow.3.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][4], { "RFCI " #i " Flow 4 Len", "iuup.rfci."#i".flow.4.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][5], { "RFCI " #i " Flow 5 Len", "iuup.rfci."#i".flow.5.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][6], { "RFCI " #i " Flow 6 Len", "iuup.rfci."#i".flow.6.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_flow_len[i][7], { "RFCI " #i " Flow 7 Len", "iuup.rfci."#i".flow.7.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_rfci_li[i], { "RFCI " #i " LI", "iuup.rfci."#i".li", FT_UINT8, BASE_HEX, VALS(iuup_init_rfci_li_vals),0x40,"Length Indicator",HFILL}}, \
{ &hf_iuup_init_rfci_lri[i], { "RFCI " #i " LRI", "iuup.rfci."#i".lri", FT_UINT8, BASE_HEX, VALS(iuup_init_lri_vals),0x80,"Last Record Indicator",HFILL}}, \
{ &hf_iuup_rfci_subflow[i][0], { "RFCI " #i " Flow 0", "iuup.rfci."#i".flow.0", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][1], { "RFCI " #i " Flow 1", "iuup.rfci."#i".flow.1", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][2], { "RFCI " #i " Flow 2", "iuup.rfci."#i".flow.2", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][3], { "RFCI " #i " Flow 3", "iuup.rfci."#i".flow.3", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][4], { "RFCI " #i " Flow 4", "iuup.rfci."#i".flow.4", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][5], { "RFCI " #i " Flow 5", "iuup.rfci."#i".flow.5", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][6], { "RFCI " #i " Flow 6", "iuup.rfci."#i".flow.6", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_rfci_subflow[i][7], { "RFCI " #i " Flow 7", "iuup.rfci."#i".flow.7", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
{ &hf_iuup_init_ipti[i], { "RFCI " #i " IPTI", "iuup.rfci."#i".ipti", FT_UINT8, BASE_HEX, NULL,i%2 ? 0x0F : 0xF0,NULL,HFILL}}
void proto_register_iuup(void) {
static hf_register_info hf[] = {
{ &hf_iuup_direction, { "Frame Direction", "iuup.direction", FT_UINT16, BASE_DEC, NULL,0x8000,NULL,HFILL}},
{ &hf_iuup_circuit_id, { "Circuit ID", "iuup.circuit_id", FT_UINT16, BASE_DEC, NULL,0x7fff,NULL,HFILL}},
{ &hf_iuup_pdu_type, { "PDU Type", "iuup.pdu_type", FT_UINT8, BASE_DEC, VALS(iuup_pdu_types),0xf0,NULL,HFILL}},
{ &hf_iuup_frame_number, { "Frame Number", "iuup.framenum", FT_UINT8, BASE_DEC, NULL,0x0F,NULL,HFILL}},
{ &hf_iuup_fqc, { "FQC", "iuup.fqc", FT_UINT8, BASE_DEC, VALS(iuup_fqcs),0xc0,"Frame Quality Classification",HFILL}},
{ &hf_iuup_rfci, { "RFCI", "iuup.rfci", FT_UINT8, BASE_HEX, NULL, 0x3f, "RAB sub-Flow Combination Indicator",HFILL}},
{ &hf_iuup_hdr_crc, { "Header CRC", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,NULL,HFILL}},
{ &hf_iuup_payload_crc, { "Payload CRC", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,NULL,HFILL}},
{ &hf_iuup_ack_nack, { "Ack/Nack", "iuup.ack", FT_UINT8, BASE_DEC, VALS(iuup_acknack_vals),0x0c,NULL,HFILL}},
{ &hf_iuup_frame_number_t14, { "Frame Number", "iuup.framenum_t14", FT_UINT8, BASE_DEC, NULL,0x03,NULL,HFILL}},
{ &hf_iuup_mode_version, { "Mode Version", "iuup.mode", FT_UINT8, BASE_HEX, NULL,0xf0,NULL,HFILL}},
{ &hf_iuup_procedure_indicator, { "Procedure", "iuup.procedure", FT_UINT8, BASE_DEC, VALS(iuup_procedures),0x0f,NULL,HFILL}},
{ &hf_iuup_error_cause_val, { "Error Cause", "iuup.error_cause", FT_UINT8, BASE_DEC, VALS(iuup_error_causes),0xfc,NULL,HFILL}},
{ &hf_iuup_error_distance, { "Error DISTANCE", "iuup.error_distance", FT_UINT8, BASE_DEC, VALS(iuup_error_distances),0xc0,NULL,HFILL}},
{ &hf_iuup_errorevt_cause_val, { "Error Cause", "iuup.errorevt_cause", FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}},
{ &hf_iuup_time_align, { "Time Align", "iuup.time_align", FT_UINT8, BASE_HEX, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_data_pdu_type, { "RFCI Data Pdu Type", "iuup.data_pdu_type", FT_UINT8, BASE_HEX, VALS(iuup_payload_pdu_type),0xF0,NULL,HFILL}},
{ &hf_iuup_spare_03, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x03,NULL,HFILL}},
#if 0
{ &hf_iuup_spare_0f, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x0f,NULL,HFILL}},
#endif
#if 0
{ &hf_iuup_spare_c0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xc0,NULL,HFILL}},
#endif
{ &hf_iuup_spare_e0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xe0,NULL,HFILL}},
{ &hf_iuup_spare_ff, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xff,NULL,HFILL}},
{ &hf_iuup_spare_bytes, { "Spare", "iuup.spare_bytes", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_delay, { "Delay", "iuup.delay", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_advance, { "Advance", "iuup.advance", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_delta, { "Delta Time", "iuup.delta", FT_FLOAT, BASE_NONE, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_init_ti, { "TI", "iuup.ti", FT_UINT8, BASE_DEC, VALS(iuup_ti_vals),0x10,"Timing Information",HFILL}},
{ &hf_iuup_init_subflows_per_rfci, { "Subflows", "iuup.subflows", FT_UINT8, BASE_DEC, NULL,0x0e,"Number of Subflows",HFILL}},
{ &hf_iuup_init_chain_ind, { "Chain Indicator", "iuup.chain_ind", FT_UINT8, BASE_DEC, VALS(iuup_init_chain_ind_vals),0x01,NULL,HFILL}},
{ &hf_iuup_payload, { "Payload Data", "iuup.payload_data", FT_BYTES, BASE_NONE, NULL,0x00,NULL,HFILL}},
{ &hf_iuup_mode_versions, { "Iu UP Mode Versions Supported", "iuup.support_mode", FT_UINT16, BASE_HEX, NULL,0x0,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 0], { "Version 16", "iuup.support_mode.version16", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x8000,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 1], { "Version 15", "iuup.support_mode.version15", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x4000,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 2], { "Version 14", "iuup.support_mode.version14", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x2000,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 3], { "Version 13", "iuup.support_mode.version13", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x1000,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 4], { "Version 12", "iuup.support_mode.version12", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0800,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 5], { "Version 11", "iuup.support_mode.version11", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0400,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 6], { "Version 10", "iuup.support_mode.version10", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0200,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 7], { "Version 9", "iuup.support_mode.version9", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0100,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 8], { "Version 8", "iuup.support_mode.version8", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0080,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[ 9], { "Version 7", "iuup.support_mode.version7", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0040,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[10], { "Version 6", "iuup.support_mode.version6", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0020,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[11], { "Version 5", "iuup.support_mode.version5", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0010,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[12], { "Version 4", "iuup.support_mode.version4", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0008,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[13], { "Version 3", "iuup.support_mode.version3", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0004,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[14], { "Version 2", "iuup.support_mode.version2", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0002,NULL,HFILL}},
{ &hf_iuup_mode_versions_a[15], { "Version 1", "iuup.support_mode.version1", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0001,NULL,HFILL}},
{ &hf_iuup_num_rfci_ind, { "Number of RFCI Indicators", "iuup.p", FT_UINT8, BASE_HEX, NULL,0x3f,NULL,HFILL}},
{ &hf_iuup_init_rfci_ind, { "RFCI Initialization", "iuup.rfci.init", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
HFS_RFCI(0),HFS_RFCI(1),HFS_RFCI(2),HFS_RFCI(3),HFS_RFCI(4),HFS_RFCI(5),HFS_RFCI(6),HFS_RFCI(7),
HFS_RFCI(8),HFS_RFCI(9),HFS_RFCI(10),HFS_RFCI(11),HFS_RFCI(12),HFS_RFCI(13),HFS_RFCI(14),HFS_RFCI(15),
HFS_RFCI(16),HFS_RFCI(17),HFS_RFCI(18),HFS_RFCI(19),HFS_RFCI(20),HFS_RFCI(21),HFS_RFCI(22),HFS_RFCI(23),
HFS_RFCI(24),HFS_RFCI(25),HFS_RFCI(26),HFS_RFCI(27),HFS_RFCI(28),HFS_RFCI(29),HFS_RFCI(30),HFS_RFCI(31),
HFS_RFCI(32),HFS_RFCI(33),HFS_RFCI(34),HFS_RFCI(35),HFS_RFCI(36),HFS_RFCI(37),HFS_RFCI(38),HFS_RFCI(39),
HFS_RFCI(40),HFS_RFCI(41),HFS_RFCI(42),HFS_RFCI(43),HFS_RFCI(44),HFS_RFCI(45),HFS_RFCI(46),HFS_RFCI(47),
HFS_RFCI(48),HFS_RFCI(49),HFS_RFCI(50),HFS_RFCI(51),HFS_RFCI(52),HFS_RFCI(53),HFS_RFCI(54),HFS_RFCI(55),
HFS_RFCI(56),HFS_RFCI(57),HFS_RFCI(58),HFS_RFCI(59),HFS_RFCI(60),HFS_RFCI(61),HFS_RFCI(62),HFS_RFCI(63)
};
gint* ett[] = {
&ett_iuup,
&ett_rfci,
&ett_ipti,
&ett_support,
&ett_time,
&ett_rfciinds,
&ett_payload,
&ett_payload_subflows
};
static ei_register_info ei[] = {
{ &ei_iuup_hdr_crc_bad, { "iuup.hdr.crc.bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
{ &ei_iuup_payload_crc_bad, { "iuup.payload.crc.bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
{ &ei_iuup_payload_undecoded, { "iuup.payload.undecoded", PI_UNDECODED, PI_WARN, "Undecoded payload", EXPFILL }},
{ &ei_iuup_error_response, { "iuup.error_response", PI_RESPONSE_CODE, PI_ERROR, "Error response", EXPFILL }},
{ &ei_iuup_ack_nack, { "iuup.ack.malformed", PI_MALFORMED, PI_ERROR, "Malformed Ack/Nack", EXPFILL }},
{ &ei_iuup_time_align, { "iuup.time_align.malformed", PI_MALFORMED, PI_ERROR, "Malformed Time Align", EXPFILL }},
{ &ei_iuup_procedure_indicator, { "iuup.procedure.malformed", PI_MALFORMED, PI_ERROR, "Malformed Procedure", EXPFILL }},
{ &ei_iuup_pdu_type, { "iuup.pdu_type.malformed", PI_MALFORMED, PI_ERROR, "Malformed PDU Type", EXPFILL }},
};
module_t *iuup_module;
expert_module_t* expert_iuup;
proto_iuup = proto_register_protocol("IuUP", "IuUP", "iuup");
proto_register_field_array(proto_iuup, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_iuup = expert_register_protocol(proto_iuup);
expert_register_field_array(expert_iuup, ei, array_length(ei));
iuup_handle = register_dissector("iuup", dissect_iuup, proto_iuup);
register_dissector("find_iuup", find_iuup, proto_iuup);
circuits = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
iuup_module = prefs_register_protocol(proto_iuup, proto_reg_handoff_iuup);
prefs_register_bool_preference(iuup_module, "dissect_payload",
"Dissect IuUP Payload bits",
"Whether IuUP Payload bits should be dissected",
&dissect_fields);
prefs_register_bool_preference(iuup_module, "two_byte_pseudoheader",
"Two byte pseudoheader",
"The payload contains a two byte pseudoheader indicating direction and circuit_id",
&two_byte_pseudoheader);
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
prefs_register_range_preference(iuup_module, "dynamic.payload.type",
"IuUP dynamic payload type",
RTP: Make Decode As handling consistent across subdissectors RTP has two dissector tables, one directly associated with payload types, and one which is associated with strings that appear in SDP commands. This makes all dissectors that are registered as a dynamic payload type that can be configured by SDP appear as a Decode As option for the RTP PT table. Some protocols were registered in the table for configuration by SDP but had no way to register with the rtp.pt table. These include EVRC, H.223, and v150fw. Other protocols had a long standing preference to set a dynamic payload type, but they still did not appear in the Decode As menu unless that preference was changed from the default, largely because of the way that the preference was not actually registered with the rtp.pt table unless it had a value in the dynamic payload type range. These include EVS, H.263P, H.264, H.265, ISMACryp, IuUP, LAPD, MP4V-ES, RTP-MIDI, and VP8. RFC 3551 says that not just the dynamic payload types, but also the unassigned and even the statically assigned payload types MAY be dynamically reassigned as necessary, so this patch also allows these preferences to be set for payload types less than 96. The only payload type not allowed is 0 (which RFCs 3551 and 7007 say must be μ-law PCM), which is handy anyone for backwards compatibility with preferences that used to be uints (where 0 meant disabled.) All protcols which formerly used a uint preference are all converted to a range preference, and the text is changed to be similar for each. This works in a backwards compatible fashion, and any defaults are maintained. The patch also adds some of the dissector variants as PINOs so that they will show up with distinct names in the Decode As menus, and changes some of the protocol short names so that the entry in Decode As is clearer and matches what is used for other similar protocols. Change-Id: I68627b5c3e495d9fc813d88208f3b62e47e0c4de Reviewed-on: https://code.wireshark.org/review/37396 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
2020-06-07 20:15:49 +00:00
"Dynamic payload types which will be interpreted as IuUP"
"; values must be in the range 1 - 127",
&global_dynamic_payload_type_range, 127);
}
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/