3 * Routines for RFC2190-encapsulated H.263 dissection
5 * Copyright 2003 Niklas Ogren <niklas.ogren@7l.se>
6 * Seven Levels Consultants AB
8 * Copyright 2008 Richard van der Hoff, MX Telecom
9 * <richardv@mxtelecom.com>
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 * This dissector tries to dissect the H.263 protocol according to
34 * RFC 2190, http://www.ietf.org/rfc/rfc2190.txt
40 #include <epan/packet.h>
42 #include <epan/rtp_pt.h>
43 #include <epan/iax2_codec_type.h>
45 #include "packet-h263.h"
47 /* H.263 header fields */
48 static int proto_rfc2190
= -1;
51 static int hf_rfc2190_ftype
= -1;
52 static int hf_rfc2190_pbframes
= -1;
53 static int hf_rfc2190_sbit
= -1;
54 static int hf_rfc2190_ebit
= -1;
55 static int hf_rfc2190_srcformat
= -1;
56 static int hf_rfc2190_picture_coding_type
= -1;
57 static int hf_rfc2190_unrestricted_motion_vector
= -1;
58 static int hf_rfc2190_syntax_based_arithmetic
= -1;
59 static int hf_rfc2190_advanced_prediction
= -1;
60 static int hf_rfc2190_r
= -1;
61 static int hf_rfc2190_rr
= -1;
62 static int hf_rfc2190_dbq
= -1;
63 static int hf_rfc2190_trb
= -1;
64 static int hf_rfc2190_tr
= -1;
65 /* Additional fields for Mode B or C header */
66 static int hf_rfc2190_quant
= -1;
67 static int hf_rfc2190_gobn
= -1;
68 static int hf_rfc2190_mba
= -1;
69 static int hf_rfc2190_hmv1
= -1;
70 static int hf_rfc2190_vmv1
= -1;
71 static int hf_rfc2190_hmv2
= -1;
72 static int hf_rfc2190_vmv2
= -1;
74 static gint ett_rfc2190
= -1;
75 static dissector_handle_t h263_handle
;
79 dissect_rfc2190( tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
81 proto_item
*ti
= NULL
;
82 proto_tree
*rfc2190_tree
= NULL
;
84 unsigned int rfc2190_version
= 0;
88 rfc2190_version
= (tvb_get_guint8( tvb
, offset
) & 0xc0 ) >> 6;
90 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "H.263 ");
92 /* Three formats (mode A, mode B and mode C) are defined for H.263
93 * payload header. In mode A, an H.263 payload header of four bytes is
94 * present before actual compressed H.263 video bitstream in a packet.
95 * It allows fragmentation at GOB boundaries. In mode B, an eight byte
96 * H.263 payload header is used and each packet starts at MB boundaries
97 * without the PB-frames option. Finally, a twelve byte H.263 payload
98 * header is defined in mode C to support fragmentation at MB boundaries
99 * for frames that are coded with the PB-frames option.
101 if( rfc2190_version
== 0x00) {
102 col_append_str( pinfo
->cinfo
, COL_INFO
, "MODE A ");
105 else if( rfc2190_version
== 0x02) {
106 col_append_str( pinfo
->cinfo
, COL_INFO
, "MODE B ");
109 else if( rfc2190_version
== 0x03) {
110 col_append_str( pinfo
->cinfo
, COL_INFO
, "MODE C ");
115 ti
= proto_tree_add_item( tree
, proto_rfc2190
, tvb
, offset
, hdr_len
, ENC_NA
);
116 rfc2190_tree
= proto_item_add_subtree( ti
, ett_rfc2190
);
118 /* FBIT 1st octet, 1 bit */
119 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_ftype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
120 /* PBIT 1st octet, 1 bit */
121 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_pbframes
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
122 /* SBIT 1st octet, 3 bits */
123 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_sbit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
124 /* EBIT 1st octet, 3 bits */
125 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_ebit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
128 /* SRC 2nd octet, 3 bits */
129 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_srcformat
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
131 if(rfc2190_version
== 0x00) { /* MODE A */
133 proto_tree_add_bits_item(rfc2190_tree
, hf_rfc2190_picture_coding_type
, tvb
, (offset
<<3)+3, 1, ENC_BIG_ENDIAN
);
135 proto_tree_add_bits_item(rfc2190_tree
, hf_rfc2190_unrestricted_motion_vector
, tvb
, (offset
<<3)+4, 1, ENC_BIG_ENDIAN
);
137 proto_tree_add_bits_item(rfc2190_tree
, hf_rfc2190_syntax_based_arithmetic
, tvb
, (offset
<<3)+5, 1, ENC_BIG_ENDIAN
);
139 proto_tree_add_bits_item(rfc2190_tree
, hf_rfc2190_advanced_prediction
, tvb
, (offset
<<3)+6, 1, ENC_BIG_ENDIAN
);
141 /* Reserved 2nd octect, 1 bit + 3rd octect 3 bits */
142 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_r
, tvb
, offset
, 2, ( ( tvb_get_guint8( tvb
, offset
) & 0x1 ) << 3 ) + ( ( tvb_get_guint8( tvb
, offset
+ 1 ) & 0xe0 ) >> 5 ) );
146 /* DBQ 3 octect, 2 bits */
147 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_dbq
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
148 /* TRB 3 octect, 3 bits */
149 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_trb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
152 /* TR 4 octect, 8 bits */
153 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_tr
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) );
157 } else { /* MODE B or MODE C */
158 /* QUANT 2 octect, 5 bits */
159 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_quant
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x1f );
163 /* GOBN 3 octect, 5 bits */
164 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_gobn
, tvb
, offset
, 1, ( tvb_get_guint8( tvb
, offset
) & 0xf8 ) >> 3);
165 /* MBA 3 octect, 3 bits + 4 octect 6 bits */
166 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_mba
, tvb
, offset
, 2, ( ( tvb_get_guint8( tvb
, offset
) & 0x7 ) << 6 ) + ( ( tvb_get_guint8( tvb
, offset
+ 1 ) & 0xfc ) >> 2 ) );
170 /* Reserved 4th octect, 2 bits */
171 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_r
, tvb
, offset
, 1, ( tvb_get_guint8( tvb
, offset
) & 0x3 ) );
176 proto_tree_add_boolean( rfc2190_tree
, hf_rfc2190_picture_coding_type
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x80 );
178 proto_tree_add_boolean( rfc2190_tree
, hf_rfc2190_unrestricted_motion_vector
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x40 );
180 proto_tree_add_boolean( rfc2190_tree
, hf_rfc2190_syntax_based_arithmetic
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x20 );
182 proto_tree_add_boolean( rfc2190_tree
, hf_rfc2190_advanced_prediction
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x10 );
184 /* HMV1 5th octect, 4 bits + 6th octect 3 bits*/
185 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_hmv1
, tvb
, offset
, 2,( ( tvb_get_guint8( tvb
, offset
) & 0xf ) << 3 ) + ( ( tvb_get_guint8( tvb
, offset
+1 ) & 0xe0 ) >> 5) );
189 /* VMV1 6th octect, 5 bits + 7th octect 2 bits*/
190 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_vmv1
, tvb
, offset
, 2,( ( tvb_get_guint8( tvb
, offset
) & 0x1f ) << 2 ) + ( ( tvb_get_guint8( tvb
, offset
+1 ) & 0xc0 ) >> 6) );
194 /* HMV2 7th octect, 6 bits + 8th octect 1 bit*/
195 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_hmv2
, tvb
, offset
, 2,( ( tvb_get_guint8( tvb
, offset
) & 0x3f ) << 1 ) + ( ( tvb_get_guint8( tvb
, offset
+1 ) & 0xf0 ) >> 7) );
199 /* VMV2 8th octect, 7 bits*/
200 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_vmv2
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) & 0x7f );
204 if(rfc2190_version
== 0x03) { /* MODE C */
205 /* Reserved 9th to 11th octect, 8 + 8 + 3 bits */
206 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_rr
, tvb
, offset
, 3, ( tvb_get_guint8( tvb
, offset
) << 11 ) + ( tvb_get_guint8( tvb
, offset
+ 1 ) << 3 ) + ( ( tvb_get_guint8( tvb
, offset
+ 2 ) & 0xe0 ) >> 5 ) );
210 /* DBQ 11th octect, 2 bits */
211 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_dbq
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
212 /* TRB 11th octect, 3 bits */
213 proto_tree_add_item( rfc2190_tree
, hf_rfc2190_trb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
217 /* TR 12th octect, 8 bits */
218 proto_tree_add_uint( rfc2190_tree
, hf_rfc2190_tr
, tvb
, offset
, 1, tvb_get_guint8( tvb
, offset
) );
222 } /* end not mode a */
224 switch(rfc2190_version
) {
225 case 0x00: /* MODE A */
228 case 0x01: /* MODE B */
231 case 0x02: /* MODE C */
238 /* The rest of the packet is the H.263 stream */
239 next_tvb
= tvb_new_subset_remaining( tvb
, offset
);
240 call_dissector(h263_handle
,next_tvb
,pinfo
,tree
);
244 proto_reg_handoff_rfc2190(void)
246 dissector_handle_t rfc2190_handle
;
248 rfc2190_handle
= find_dissector("rfc2190");
249 dissector_add_uint("rtp.pt", PT_H263
, rfc2190_handle
);
250 dissector_add_uint("iax2.codec", AST_FORMAT_H263
, rfc2190_handle
);
252 h263_handle
= find_dissector("h263data");
257 proto_register_rfc2190(void)
259 static hf_register_info hf
[] =
270 "Indicates the mode of the payload header (MODE A or B/C)", HFILL
274 &hf_rfc2190_pbframes
,
282 "Optional PB-frames mode as defined by H.263 (MODE C)", HFILL
288 "Start bit position",
294 "Start bit position specifies number of most significant bits that shall be ignored in the first data byte.", HFILL
306 "End bit position specifies number of least significant bits that shall be ignored in the last data byte.", HFILL
310 &hf_rfc2190_srcformat
,
316 VALS(h263_srcformat_vals
),
318 "Source format specifies the resolution of the current picture.", HFILL
322 &hf_rfc2190_picture_coding_type
,
325 "rfc2190.picture_coding_type",
330 "Picture coding type, intra-coded (false) or inter-coded (true)", HFILL
334 &hf_rfc2190_unrestricted_motion_vector
,
337 "rfc2190.unrestricted_motion_vector",
342 "Unrestricted Motion Vector option for current picture", HFILL
346 &hf_rfc2190_syntax_based_arithmetic
,
348 "Syntax-based arithmetic coding",
349 "rfc2190.syntax_based_arithmetic",
354 "Syntax-based Arithmetic Coding option for current picture", HFILL
358 &hf_rfc2190_advanced_prediction
,
360 "Advanced prediction option",
361 "rfc2190.advanced_prediction",
366 "Advanced Prediction option for current picture", HFILL
372 "Differential quantization parameter",
378 "Differential quantization parameter used to calculate quantizer for the B frame based on quantizer for the P frame, when PB-frames option is used.", HFILL
384 "Temporal Reference for B frames",
390 "Temporal Reference for the B frame as defined by H.263", HFILL
396 "Temporal Reference for P frames",
402 "Temporal Reference for the P frame as defined by H.263", HFILL
414 "Quantization value for the first MB coded at the starting of the packet.", HFILL
426 "GOB number in effect at the start of the packet.", HFILL
432 "Macroblock address",
438 "The address within the GOB of the first MB in the packet, counting from zero in scan order.", HFILL
444 "Horizontal motion vector 1",
450 "Horizontal motion vector predictor for the first MB in this packet", HFILL
456 "Vertical motion vector 1",
462 "Vertical motion vector predictor for the first MB in this packet", HFILL
468 "Horizontal motion vector 2",
474 "Horizontal motion vector predictor for block number 3 in the first MB in this packet when four motion vectors are used with the advanced prediction option.", HFILL
480 "Vertical motion vector 2",
486 "Vertical motion vector predictor for block number 3 in the first MB in this packet when four motion vectors are used with the advanced prediction option.", HFILL
498 "Reserved field that should contain zeroes", HFILL
510 "Reserved field that should contain zeroes", HFILL
520 proto_register_subtree_array(ett
, array_length(ett
));
522 proto_rfc2190
= proto_register_protocol("H.263 RTP Payload header (RFC2190)",
523 "RFC2190", "rfc2190");
525 proto_register_field_array(proto_rfc2190
, hf
, array_length(hf
));
526 register_dissector("rfc2190", dissect_rfc2190
, proto_rfc2190
);