From 959e3e3e2c85fa792fff42374ee9835d4f45e310 Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Sun, 24 Feb 2013 22:06:53 +0000 Subject: Various enhancements to ROHC dissector: - fix dissection of type 0 packets with large CID - add dissection of type 1 and 2 packets (extension 3 dissection to be done) - add dissection of UDP checksum svn path=/trunk/; revision=47869 --- epan/dissectors/packet-rohc.c | 661 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 571 insertions(+), 90 deletions(-) (limited to 'epan/dissectors/packet-rohc.c') diff --git a/epan/dissectors/packet-rohc.c b/epan/dissectors/packet-rohc.c index 7b79a56b28..9f23dbf100 100644 --- a/epan/dissectors/packet-rohc.c +++ b/epan/dissectors/packet-rohc.c @@ -97,7 +97,6 @@ static int hf_rohc_rtp_id = -1; static int hf_rohc_rtp_df = -1; static int hf_rohc_rtp_rnd = -1; static int hf_rohc_rtp_nbo = -1; -/* static int hf_rohc_rtp_checksum = -1; */ static int hf_rohc_dynamic_udp_checksum = -1; static int hf_rohc_dynamic_rtp =-1; static int hf_rohc_rtp_v = -1; @@ -121,6 +120,10 @@ static int hf_rohc_ir_pkt_frame = -1; static int hf_rohc_ir_previous_frame = -1; static int hf_rohc_comp_sn = -1; static int hf_rohc_r_0_crc = -1; +static int hf_rohc_x = -1; +static int hf_rohc_ts = -1; +static int hf_rohc_comp_ip_id = -1; +static int hf_rohc_t = -1; static int hf_rohc_compressed_list = -1; static int hf_rohc_compressed_list_et = -1; @@ -137,6 +140,7 @@ static int hf_rohc_compressed_list_ins_bit_mask = -1; static int hf_rohc_compressed_list_rem_bit_mask = -1; static int hf_rohc_spare_bits = -1; static int hf_rohc_ip_id = -1; +static int hf_rohc_udp_checksum = -1; static int ett_rohc = -1; static int ett_rohc_conf = -1; @@ -162,7 +166,7 @@ typedef struct _rohc_cid_context_t enum rohc_mode mode; enum rohc_d_mode d_mode; gboolean rnd; - gboolean udp_checkum_present; + gboolean udp_checksum_present; guint16 profile; gint prev_ir_frame_number; /* The frame number of the previous IR packet seen */ gint ir_frame_number; /* The frame number of the latest IR packet seen */ @@ -264,18 +268,61 @@ static const value_string compressed_list_ps_vals[] = { 0, NULL }, }; +/* 4.5.6. Self-describing variable-length values */ +static guint32 +get_self_describing_var_len_val(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, guint8 *val_len){ + guint8 oct; + guint32 val = 0; + int num_bits = 0, bit_offset = offset <<3; + + oct = tvb_get_guint8(tvb, offset); + if((oct&0x80)==0){ + /* One octet */ + *val_len = 1; + val = (oct&0x7f); + proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 1, ENC_BIG_ENDIAN); + num_bits = 7; + bit_offset++; + }else if((oct&0xc0)==0x80){ + /* Two octets */ + *val_len = 2; + proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 2, ENC_BIG_ENDIAN); + bit_offset+=2; + num_bits = 14; + val = tvb_get_ntohs(tvb, offset)&0x3fff; + }else if((oct&0xe0)==0xc0){ + /* Three octets */ + *val_len = 3; + proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 3, ENC_BIG_ENDIAN); + bit_offset+=3; + num_bits = 21; + val = tvb_get_ntoh24(tvb, offset)&0x1fffff; + }else if ((oct&0xe0)==0xe0){ + /* Four octets */ + *val_len = 4; + proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 4, ENC_BIG_ENDIAN); + bit_offset+=3; + num_bits = 29; + val = tvb_get_ntohl(tvb, offset)&0x1fffffff; + } + proto_tree_add_bits_item(tree, hf_index, tvb, bit_offset, num_bits, ENC_BIG_ENDIAN); + + return val; + +} + /* 5.7.1. Packet type 0: UO-0, R-0, R-0-CRC */ static int dissect_rohc_pkt_type_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint8 pkt_type, rohc_cid_context_t *rohc_cid_context) { - guint8 sn; + guint8 val_len = 0; + guint64 sn; proto_item *ti; proto_tree *pkt_tree; switch(rohc_cid_context->mode){ case RELIABLE_BIDIRECTIONAL: /* R-mode */ if((pkt_type&0xc0)==0x00){ - /* R-0 * * 0 1 2 3 4 5 6 7 @@ -283,14 +330,18 @@ dissect_rohc_pkt_type_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int * | 0 0 | SN | * +===+===+===+===+===+===+===+===+ */ + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); + } col_set_str(pinfo->cinfo, COL_INFO, "R-0"); - ti = proto_tree_add_text(tree, tvb, offset, 1, "R-0 packet"); + ti = proto_tree_add_text(tree, tvb, offset, 1+val_len, "R-0 packet"); pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); sn = tvb_get_bits8(tvb,(offset<<3)+2, 6); proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); - offset++; + offset += 1 + val_len; /* Show SN in info column */ - col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", (guint)sn); }else if((pkt_type&0xc0)==0x40){ /* R-0-CRC * @@ -301,16 +352,26 @@ dissect_rohc_pkt_type_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int * |SN | CRC | * +---+---+---+---+---+---+---+---+ */ + crumb_spec_t rohc_sn_crumbs[] = { + { 2, 6}, + { 8, 1}, + { 0, 0} + }; + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); + rohc_sn_crumbs[1].crumb_bit_offset += val_len*8; + } col_set_str(pinfo->cinfo, COL_INFO, "R-0-CRC"); - ti = proto_tree_add_text(tree, tvb, offset, 2, "R-0-CRC packet"); + ti = proto_tree_add_text(tree, tvb, offset, 2+val_len, "R-0-CRC packet"); pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); - sn = tvb_get_bits8(tvb,(offset<<3)+2, 7); - proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 7, ENC_BIG_ENDIAN); - offset++; + proto_tree_add_split_bits_item_ret_val(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3), + rohc_sn_crumbs, &sn); + offset += 1 + val_len; proto_tree_add_bits_item(pkt_tree, hf_rohc_r_0_crc, tvb, (offset<<3)+1, 7, ENC_BIG_ENDIAN); offset++; /* Show SN in info column */ - col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", (guint)sn); } break; case UNIDIRECTIONAL: /* U-mode */ @@ -323,15 +384,19 @@ dissect_rohc_pkt_type_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int * | 0 | SN | CRC | * +===+===+===+===+===+===+===+===+ */ + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); + } col_set_str(pinfo->cinfo, COL_INFO, "UO-0"); - ti = proto_tree_add_text(tree, tvb, offset, 1, "UO-0 packet"); + ti = proto_tree_add_text(tree, tvb, offset, 1+val_len, "UO-0 packet"); pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); sn = tvb_get_bits8(tvb,(offset<<3)+1, 4); proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+1, 4, ENC_BIG_ENDIAN); proto_tree_add_bits_item(pkt_tree, hf_rohc_r_0_crc, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); - offset++; + offset += 1 + val_len; /* Show SN in info column */ - col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", (guint)sn); break; default: col_set_str(pinfo->cinfo, COL_INFO, "Packet type 0"); @@ -342,47 +407,424 @@ dissect_rohc_pkt_type_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int } -/* 4.5.6. Self-describing variable-length values */ -static guint32 -get_self_describing_var_len_val(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index, guint8 *val_len){ - guint8 oct; - guint32 val = 0; - int num_bits = 0, bit_offset = offset <<3; +/* 5.7.5. Extension formats */ +static int +dissect_rohc_ext_format(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 t, rohc_cid_context_t *rohc_cid_context) +{ + guint8 ext_type = tvb_get_guint8(tvb, offset) & 0xc0; + + proto_tree_add_bits_item(tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 3, ENC_BIG_ENDIAN); + if (ext_type == 0x00) { + /* Extension 0: + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 0 0 | SN | +T | + * +---+---+---+---+---+---+---+---+ + */ + if ((t == 0) || (rohc_cid_context->profile == ROHC_PROFILE_UDP)) { + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + } + offset++; + } else if (ext_type == 0x40) { + /* Extension 1: + * + * +---+---+---+---+---+---+---+---+ + * | 0 1 | SN | +T | + * +---+---+---+---+---+---+---+---+ + * | -T | + * +---+---+---+---+---+---+---+---+ + */ + if (rohc_cid_context->profile == ROHC_PROFILE_UDP) { + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+5, 11, ENC_BIG_ENDIAN); + offset++; + }else if (t == 0) { + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } else if (t == 1) { + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } + offset++; + } else if (ext_type == 0x80) { + /* Extension 2: + * + * +---+---+---+---+---+---+---+---+ + * | 1 0 | SN | +T | + * +---+---+---+---+---+---+---+---+ + * | +T | + * +---+---+---+---+---+---+---+---+ + * | -T | + * +---+---+---+---+---+---+---+---+ + */ + if (rohc_cid_context->profile == ROHC_PROFILE_UDP) { + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+5, 11, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + }else if (t == 0) { + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+5, 11, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } else if (t == 1) { + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3)+5, 11, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_bits_item(tree, hf_rohc_comp_ip_id, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3)+5, 11, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_bits_item(tree, hf_rohc_ts, tvb, (offset<<3), 8, ENC_BIG_ENDIAN); + } + offset++; + } else { + proto_tree_add_text(tree, tvb, offset, -1, "extension 3[Not dissected yet]"); + offset += tvb_length_remaining(tvb, offset); + } + return offset; +} - oct = tvb_get_guint8(tvb, offset); - if((oct&0x80)==0){ - /* One octet */ - *val_len = 1; - val = (oct&0x7f); - proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 1, ENC_BIG_ENDIAN); - num_bits = 7; - bit_offset++; - }else if((oct&0xc0)==0x80){ - /* Two octets */ - *val_len = 2; - proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 2, ENC_BIG_ENDIAN); - bit_offset+=2; - num_bits = 14; - val = tvb_get_ntohs(tvb, offset)&0x3fff; - }else if((oct&0xe0)==0xc0){ - /* Three octets */ - *val_len = 3; - proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 3, ENC_BIG_ENDIAN); - bit_offset+=3; - num_bits = 21; - val = tvb_get_ntoh24(tvb, offset)&0x1fffff; - }else if ((oct&0xe0)==0xe0){ - /* Four octets */ - *val_len = 4; - proto_tree_add_bits_item(tree, hf_rohc_var_len, tvb, bit_offset, 4, ENC_BIG_ENDIAN); - bit_offset+=3; - num_bits = 29; - val = tvb_get_ntohl(tvb, offset)&0x1fffffff; +/* 5.7.2. Packet type 1 (R-mode): R-1, R-1-TS, R-1-ID */ +static int +dissect_rohc_pkt_type_1_r_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, rohc_cid_context_t *rohc_cid_context) +{ + proto_item *ti; + proto_tree *pkt_tree; + guint8 val_len = 0, x, sn, t = 0xff; + int start_offset = offset; + + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); } - proto_tree_add_bits_item(tree, hf_index, tvb, bit_offset, num_bits, ENC_BIG_ENDIAN); - return val; + if ((rohc_cid_context->rohc_ip_version != 4) || + (rohc_cid_context->rnd == 1) || + (rohc_cid_context->profile == ROHC_PROFILE_UDP)) { + /* R-1 (RTP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | SN | + * +===+===+===+===+===+===+===+===+ + * | M | X | TS | + * +---+---+---+---+---+---+---+---+ + */ + /* R-1 (UDP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | SN | + * +===+===+===+===+===+===+===+===+ + * | X | IP-ID | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "R-1"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "R-1 packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + sn = tvb_get_bits8(tvb, (offset<<3)+2, 6); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset += 1 + val_len; + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + if (rohc_cid_context->profile == ROHC_PROFILE_UDP) { + x= tvb_get_bits8(tvb, (offset<<3), 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+1, 7, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + x = tvb_get_bits8(tvb, (offset<<3)+1, 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3)+1, 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_ts, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + } + offset++; + } else { + t = tvb_get_bits8(tvb, ((offset+1+val_len)<<3)+2, 1); + if (t == 0) { + /* R-1-ID + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | SN | + * +===+===+===+===+===+===+===+===+ + * | M | X |T=0| IP-ID | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "R-1-ID"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "R-1-ID packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + } else { + /* R-1-TS + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | SN | + * +===+===+===+===+===+===+===+===+ + * | M | X |T=1| TS | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "R-1-TS"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "R-1-TS packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + } + sn = tvb_get_bits8(tvb, (offset<<3)+2, 6); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset += 1 + val_len; + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + x = tvb_get_bits8(tvb, (offset<<3)+1, 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3)+1, 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_t, tvb, (offset<<3)+2, 1, ENC_BIG_ENDIAN); + if (t == 0) { + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(pkt_tree, hf_rohc_ts, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + } + offset++; + } + if (x) { + offset = dissect_rohc_ext_format(tvb, pkt_tree, offset, t, rohc_cid_context); + } + proto_item_set_len(ti, offset-start_offset); + + return offset; +} + +/* 5.7.3. Packet type 1 (U/O-mode): UO-1, UO-1-ID, UO-1-TS */ +static int +dissect_rohc_pkt_type_1_u_o_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, rohc_cid_context_t *rohc_cid_context) +{ + proto_item *ti; + proto_tree *pkt_tree; + guint8 val_len = 0, x = 0, sn, t = 0xff; + int start_offset = offset; + + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); + } + if ((rohc_cid_context->rohc_ip_version != 4) || + (rohc_cid_context->rnd == 1) || + (rohc_cid_context->profile == ROHC_PROFILE_UDP)) { + /* UO-1 (RTP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | TS | + * +===+===+===+===+===+===+===+===+ + * | M | SN | CRC | + * +---+---+---+---+---+---+---+---+ + */ + /* UO-1 (UDP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 | IP-ID | + * +===+===+===+===+===+===+===+===+ + * | SN | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UO-1"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UO-1 packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + if (rohc_cid_context->profile == ROHC_PROFILE_UDP) { + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset += 1 + val_len; + sn = tvb_get_bits8(tvb, (offset<<3), 5); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3), 5, ENC_BIG_ENDIAN); + } else { + proto_tree_add_bits_item(pkt_tree, hf_rohc_ts, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset += 1 + val_len; + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + sn = tvb_get_bits8(tvb, (offset<<3)+1, 4); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+1, 4, ENC_BIG_ENDIAN); + } + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + proto_tree_add_bits_item(pkt_tree, hf_rohc_crc, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + offset++; + } else { + t = tvb_get_bits8(tvb, ((offset)<<3)+2, 1); + if (t == 0) { + /* UO-1-ID + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 |T=0| IP-ID | + * +===+===+===+===+===+===+===+===+ + * | X | SN | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UO-1-ID"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UO-1-ID packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + proto_tree_add_bits_item(pkt_tree, hf_rohc_t, tvb, (offset<<3)+2, 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + offset += 1 + val_len; + x = tvb_get_bits8(tvb, (offset<<3), 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + } else { + /* UO-1-TS + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 0 |T=1| TS | + * +===+===+===+===+===+===+===+===+ + * | M | SN | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UO-1-TS"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UO-1-TS packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + proto_tree_add_bits_item(pkt_tree, hf_rohc_t, tvb, (offset<<3)+2, 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_ts, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + offset += 1 + val_len; + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + } + sn = tvb_get_bits8(tvb, (offset<<3)+1, 4); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+1, 4, ENC_BIG_ENDIAN); + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + proto_tree_add_bits_item(pkt_tree, hf_rohc_crc, tvb, (offset<<3)+5, 3, ENC_BIG_ENDIAN); + offset++; + } + if (x) { + offset = dissect_rohc_ext_format(tvb, pkt_tree, offset, t, rohc_cid_context); + } + proto_item_set_len(ti, offset-start_offset); + + return offset; +} + +/* 5.7.4. Packet type 2: UOR-2 */ +static int +dissect_rohc_pkt_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, rohc_cid_context_t *rohc_cid_context) +{ + proto_item *ti; + proto_tree *pkt_tree; + guint8 val_len = 0, x, sn, t = 0xff; + int start_offset = offset; + + if (rohc_cid_context->large_cid_present == TRUE) { + /* Handle Large CID:s here */ + get_self_describing_var_len_val(tvb, tree, offset+1, hf_rohc_large_cid, &val_len); + } + + if ((rohc_cid_context->rohc_ip_version != 4) || + (rohc_cid_context->rnd == 1) || + (rohc_cid_context->profile == ROHC_PROFILE_UDP)) { + /* UOR-2 (RTP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 1 0 | TS | + * +===+===+===+===+===+===+===+===+ + * |TS | M | SN | + * +---+---+---+---+---+---+---+---+ + * | X | CRC | + * +---+---+---+---+---+---+---+---+ + */ + /* UOR-2 (UDP profile) + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 1 0 | SN | + * +===+===+===+===+===+===+===+===+ + * | X | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UOR-2"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UOR-2 packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + if (rohc_cid_context->profile == ROHC_PROFILE_UDP) { + sn = tvb_get_bits8(tvb, (offset<<3)+3, 5); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + offset += 1 + val_len; + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + } else { + crumb_spec_t rohc_ts_crumbs[] = { + { 2, 6}, + { 8, 1}, + { 0, 0} + }; + rohc_ts_crumbs[1].crumb_bit_offset += val_len*8; + proto_tree_add_split_bits_item_ret_val(pkt_tree, hf_rohc_ts, tvb, (offset<<3), + rohc_ts_crumbs, NULL); + offset += 1 + val_len; + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3)+1, 1, ENC_BIG_ENDIAN); + sn = tvb_get_bits8(tvb, (offset<<3)+2, 6); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset++; + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + } + x = tvb_get_bits8(tvb, (offset<<3), 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_crc, tvb, (offset<<3)+1, 7, ENC_BIG_ENDIAN); + offset++; + } else { + t = tvb_get_bits8(tvb, ((offset+1+val_len)<<3), 1); + if (t == 0) { + /* UOR-2-ID + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 1 0 | IP-ID | + * +===+===+===+===+===+===+===+===+ + * |T=0| M | SN | + * +---+---+---+---+---+---+---+---+ + * | X | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UOR-2-ID"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UOR-2-ID packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_ip_id, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + } else { + /* UOR-2-TS + * + * 0 1 2 3 4 5 6 7 + * +---+---+---+---+---+---+---+---+ + * | 1 1 0 | TS | + * +===+===+===+===+===+===+===+===+ + * |T=1| M | SN | + * +---+---+---+---+---+---+---+---+ + * | X | CRC | + * +---+---+---+---+---+---+---+---+ + */ + col_set_str(pinfo->cinfo, COL_INFO, "UOR-2-TS"); + ti = proto_tree_add_text(tree, tvb, offset, -1, "UOR-2-TS packet"); + pkt_tree = proto_item_add_subtree(ti, ett_rohc_packet); + proto_tree_add_bits_item(pkt_tree, hf_rohc_ts, tvb, (offset<<3)+3, 5, ENC_BIG_ENDIAN); + } + offset += 1 + val_len; + proto_tree_add_bits_item(pkt_tree, hf_rohc_t, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_rtp_m, tvb, (offset<<3)+1, 1, ENC_BIG_ENDIAN); + sn = tvb_get_bits8(tvb, (offset<<3)+2, 6); + proto_tree_add_bits_item(pkt_tree, hf_rohc_comp_sn, tvb, (offset<<3)+2, 6, ENC_BIG_ENDIAN); + offset++; + /* Show SN in info column */ + col_append_fstr(pinfo->cinfo, COL_INFO, " (sn=%u)", sn); + x = tvb_get_bits8(tvb, (offset<<3), 1); + proto_tree_add_bits_item(pkt_tree, hf_rohc_x, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(pkt_tree, hf_rohc_crc, tvb, (offset<<3)+1, 7, ENC_BIG_ENDIAN); + offset++; + } + if (x) { + offset = dissect_rohc_ext_format(tvb, pkt_tree, offset, t, rohc_cid_context); + } + proto_item_set_len(ti, offset-start_offset); + + return offset; } static void @@ -410,7 +852,7 @@ dissect_rohc_feedback_data(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, rohc_cid_context = ep_new(rohc_cid_context_t); /*rohc_cid_context->d_mode;*/ rohc_cid_context->rnd = p_rohc_info->rnd; - /*rohc_cid_context->udp_checkum_present;*/ + rohc_cid_context->udp_checksum_present = p_rohc_info->udp_checksum_present; rohc_cid_context->profile = p_rohc_info->profile; rohc_cid_context->mode = p_rohc_info->mode; rohc_cid_context->rohc_ip_version = p_rohc_info->rohc_ip_version; @@ -1001,6 +1443,8 @@ dissect_rohc_ir_rtp_profile_dynamic(tvbuff_t *tvb, packet_info *pinfo, proto_tre /* Create dynamic UDP subtree */ root_ti = proto_tree_add_item(sub_tree, hf_rohc_dynamic_udp, tvb, offset, 2, ENC_NA); dynamic_udp_tree = proto_item_add_subtree(root_ti, ett_rohc_dynamic_udp); + id = tvb_get_ntohs(tvb, offset); + rohc_cid_context->udp_checksum_present = id ? TRUE : FALSE; proto_tree_add_item(dynamic_udp_tree, hf_rohc_dynamic_udp_checksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset +=2; proto_item_set_len(item, offset - start_offset); @@ -1047,7 +1491,7 @@ dissect_rohc_ir_rtp_profile_dynamic(tvbuff_t *tvb, packet_info *pinfo, proto_tre /* cc = oct & 0x0f; */ rx = (oct >> 4)& 0x01; offset++; - proto_tree_add_item(dynamic_rtp_tree, hf_rohc_rtp_m, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_bits_item(dynamic_rtp_tree, hf_rohc_rtp_m, tvb, (offset<<3), 1, ENC_BIG_ENDIAN); proto_tree_add_item(dynamic_rtp_tree, hf_rohc_rtp_pt, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; sequence_number = tvb_get_ntohs(tvb, offset); @@ -1388,6 +1832,8 @@ dissect_rohc_ir_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tmp_prev_ir_frame_number = rohc_cid_context->ir_frame_number; gint tmp_prev_rohc_ip_version = rohc_cid_context->rohc_ip_version; gint tmp_prev_mode = rohc_cid_context->mode; + gboolean tmp_prev_rnd = rohc_cid_context->rnd; + gboolean tmp_prev_udp_checksum_present = rohc_cid_context->udp_checksum_present; /*g_warning("IR pkt found CID %u",cid);*/ @@ -1397,17 +1843,19 @@ dissect_rohc_ir_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, rohc_cid_context->ir_frame_number = pinfo->fd->num; rohc_cid_context->rohc_ip_version = tmp_prev_rohc_ip_version; rohc_cid_context->mode = tmp_prev_mode; + rohc_cid_context->rnd = tmp_prev_rnd; + rohc_cid_context->udp_checksum_present = tmp_prev_udp_checksum_present; + rohc_cid_context->large_cid_present = p_rohc_info->large_cid_present; g_hash_table_replace(rohc_cid_hash, GUINT_TO_POINTER(key), rohc_cid_context); p_add_proto_data(pinfo->fd, proto_rohc, rohc_cid_context); }else{ rohc_cid_context = se_new(rohc_cid_context_t); - /*rohc_cid_context->rohc_ip_version;*/ - /*rohc_cid_context->large_cid_present;*/ + rohc_cid_context->large_cid_present = p_rohc_info->large_cid_present; /*rohc_cid_context->mode mode;*/ /*rohc_cid_context->d_mode;*/ rohc_cid_context->rnd = FALSE; - /*rohc_cid_context->udp_checkum_present;*/ + rohc_cid_context->udp_checksum_present = FALSE; rohc_cid_context->profile = profile; rohc_cid_context->prev_ir_frame_number = -1; rohc_cid_context->ir_frame_number = pinfo->fd->num; @@ -1507,6 +1955,7 @@ dissect_rohc_ir_dyn_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint tmp_prev_rohc_ip_version = rohc_cid_context->rohc_ip_version; gint tmp_prev_mode = rohc_cid_context->mode; gboolean tmp_prev_rnd = rohc_cid_context->rnd; + gboolean tmp_prev_udp_checksum_present = rohc_cid_context->udp_checksum_present; /*g_warning("IR pkt found CID %u",cid);*/ @@ -1517,17 +1966,19 @@ dissect_rohc_ir_dyn_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, rohc_cid_context->rohc_ip_version = tmp_prev_rohc_ip_version; rohc_cid_context->mode = tmp_prev_mode; rohc_cid_context->rnd = tmp_prev_rnd; + rohc_cid_context->udp_checksum_present = tmp_prev_udp_checksum_present; + rohc_cid_context->large_cid_present = p_rohc_info->large_cid_present; g_hash_table_replace(rohc_cid_hash, GUINT_TO_POINTER(key), rohc_cid_context); p_add_proto_data(pinfo->fd, proto_rohc, rohc_cid_context); }else{ rohc_cid_context = se_new(rohc_cid_context_t); /*rohc_cid_context->rohc_ip_version;*/ - /*rohc_cid_context->large_cid_present;*/ + rohc_cid_context->large_cid_present = p_rohc_info->large_cid_present; /*rohc_cid_context->mode mode;*/ /*rohc_cid_context->d_mode;*/ rohc_cid_context->rnd = FALSE; - /*rohc_cid_context->udp_checkum_present;*/ + rohc_cid_context->udp_checksum_present = FALSE; rohc_cid_context->profile = profile; rohc_cid_context->prev_ir_frame_number = -1; rohc_cid_context->ir_frame_number = pinfo->fd->num; @@ -1577,15 +2028,15 @@ dissect_rohc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) rohc_cid_context_t *rohc_cid_context = NULL; if(pinfo->private_data == NULL){ - g_rohc_info.rohc_compression = FALSE; - g_rohc_info.rohc_ip_version = g_version; - g_rohc_info.cid_inclusion_info = FALSE; - g_rohc_info.large_cid_present = FALSE; - g_rohc_info.mode = RELIABLE_BIDIRECTIONAL; - g_rohc_info.rnd = FALSE; - g_rohc_info.udp_checkum_present = FALSE; - g_rohc_info.profile = g_profile; - g_rohc_info.last_created_item = NULL; + g_rohc_info.rohc_compression = FALSE; + g_rohc_info.rohc_ip_version = g_version; + g_rohc_info.cid_inclusion_info = FALSE; + g_rohc_info.large_cid_present = FALSE; + g_rohc_info.mode = RELIABLE_BIDIRECTIONAL; + g_rohc_info.rnd = FALSE; + g_rohc_info.udp_checksum_present = FALSE; + g_rohc_info.profile = g_profile; + g_rohc_info.last_created_item = NULL; p_rohc_info = &g_rohc_info; }else{ p_rohc_info = pinfo->private_data; @@ -1795,7 +2246,7 @@ start_over: rohc_cid_context = se_new(rohc_cid_context_t); /*rohc_cid_context->d_mode;*/ rohc_cid_context->rnd = p_rohc_info->rnd; - /*rohc_cid_context->udp_checkum_present;*/ + rohc_cid_context->udp_checksum_present = p_rohc_info->udp_checksum_present; rohc_cid_context->profile = p_rohc_info->profile; rohc_cid_context->mode = p_rohc_info->mode; rohc_cid_context->rohc_ip_version = p_rohc_info->rohc_ip_version; @@ -1840,16 +2291,18 @@ start_over: else if (((oct&0x80)==0x00) && (rohc_cid_context->profile==ROHC_PROFILE_RTP)) { /* 5.7.1. Packet type 0: UO-0, R-0, R-0-CRC */ offset = dissect_rohc_pkt_type_0(tvb, pinfo, rohc_tree, offset, oct, rohc_cid_context); - }else if ((oct&0xc0)==0x80){ - col_set_str(pinfo->cinfo, COL_INFO, "Packet type 1"); - proto_tree_add_text(rohc_tree, tvb, offset, -1, "Packet type 1[Not dissected yet]"); - pinfo->private_data = save_private_data; - return; - }else if ((oct&0xe0)==0xc0){ - col_set_str(pinfo->cinfo, COL_INFO, "Packet type 2"); - proto_tree_add_text(rohc_tree, tvb, offset, -1, "Packet type 2[Not dissected yet]"); - pinfo->private_data = save_private_data; - return; + } else if ((oct&0xc0)==0x80) { + if (rohc_cid_context->mode == RELIABLE_BIDIRECTIONAL) { + /* 5.7.2. Packet type 1 (R-mode): R-1, R-1-TS, R-1-ID */ + offset = dissect_rohc_pkt_type_1_r_mode(tvb, pinfo, rohc_tree, offset, rohc_cid_context); + } + else { + /* 5.7.3. Packet type 1 (U/O-mode): UO-1, UO-1-ID, UO-1-TS */ + offset = dissect_rohc_pkt_type_1_u_o_mode(tvb, pinfo, rohc_tree, offset, rohc_cid_context); + } + } else if ((oct&0xe0)==0xc0) { + /* 5.7.4. Packet type 2: UOR-2 */ + offset = dissect_rohc_pkt_type_2(tvb, pinfo, rohc_tree, offset, rohc_cid_context); } /* IP-ID */ @@ -1858,6 +2311,12 @@ start_over: offset += 2; } + /* UDP Checksum */ + if (rohc_cid_context->udp_checksum_present) { + proto_tree_add_item(rohc_tree, hf_rohc_udp_checksum, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + } + payload_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_only(data_handle, payload_tvb, pinfo, rohc_tree, NULL); @@ -2158,14 +2617,6 @@ proto_register_rohc(void) "Whether the IP-ID is in Network Byte Order" , HFILL } }, -#if 0 - { &hf_rohc_rtp_checksum, - { "Checksum","rohc.rtp.checksum", - FT_UINT16, BASE_HEX, NULL, 0x0, - NULL , HFILL - } - }, -#endif { &hf_rohc_dynamic_udp_checksum, { "UDP Checksum", "rohc.dynamic.udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, @@ -2204,7 +2655,7 @@ proto_register_rohc(void) }, { &hf_rohc_rtp_m, { "Marker Bit (M)","rohc.rtp.m", - FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, + FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset), 0x00, NULL , HFILL } }, @@ -2228,7 +2679,7 @@ proto_register_rohc(void) }, { &hf_rohc_rtp_x, { "X","rohc.rtp.x", - FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, + FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10, NULL , HFILL } }, @@ -2293,7 +2744,7 @@ proto_register_rohc(void) } }, { &hf_rohc_comp_sn, - { "Compressed RTP Sequence Number","rohc.comp.sn", + { "Compressed Sequence Number","rohc.comp.sn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL , HFILL } @@ -2304,6 +2755,30 @@ proto_register_rohc(void) NULL , HFILL } }, + { &hf_rohc_x, + { "Extension","rohc.x", + FT_BOOLEAN, BASE_NONE, TFS(&tfs_present_not_present), 0x0, + NULL , HFILL + } + }, + { &hf_rohc_ts, + { "Compressed RTP timestamp","rohc.tp", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL , HFILL + } + }, + { &hf_rohc_comp_ip_id, + { "Compressed IP-ID","rohc.comp_ip_id", + FT_UINT16, BASE_HEX_DEC, NULL, 0x0, + NULL , HFILL + } + }, + { &hf_rohc_t, + { "T bit","rohc.t", + FT_UINT8, BASE_NONE, NULL, 0x0, + NULL , HFILL + } + }, { &hf_rohc_compressed_list, { "Compressed List", "rohc.compressed-list", FT_NONE, BASE_NONE, NULL, 0x0, @@ -2394,6 +2869,12 @@ proto_register_rohc(void) NULL, HFILL } }, + { &hf_rohc_udp_checksum, + { "UDP checksum", "rohc.udp_checksum", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL + } + }, }; -- cgit v1.2.1