Have "proto_register_protocol()" build a list of data structures for
[obnox/wireshark/wip.git] / packet-h261.c
1 /* packet-h261.c
2  *
3  * Routines for ITU-T Recommendation H.261 dissection
4  * 
5  * Copyright 2000, Philips Electronics N.V.
6  * Andreas Sikkema <andreas.sikkema@philips.com>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 /*
29  * This dissector tries to dissect the H.261 protocol according to Annex C
30  * of ITU-T Recommendation H.225.0 (02/98)
31  *
32  * This dissector is called by the RTP dissector
33  */
34
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40 #include <glib.h>
41 #include "packet.h"
42
43 #ifdef HAVE_SYS_TYPES_H
44 #  include <sys/types.h>
45 #endif
46
47 #ifdef HAVE_NETINET_IN_H
48 #  include <netinet/in.h>
49 #endif
50
51 #include <stdio.h>
52 #include <string.h>
53
54 #include "packet-h261.h"
55
56 /* H.261 header fields             */
57 static int proto_h261          = -1;
58 static int hf_h261_sbit        = -1;
59 static int hf_h261_ebit        = -1;
60 static int hf_h261_ibit        = -1;
61 static int hf_h261_vbit        = -1;
62 static int hf_h261_gobn        = -1;
63 static int hf_h261_mbap        = -1;
64 static int hf_h261_quant       = -1;
65 static int hf_h261_hmvd        = -1; /* Mislabeled in a figure in section C.3.1 as HMDV */
66 static int hf_h261_vmvd        = -1;
67 static int hf_h261_data        = -1;
68
69 /* H.261 fields defining a sub tree */
70 static gint ett_h261           = -1;
71
72 void
73 dissect_h261( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
74 {
75         proto_item *ti            = NULL;
76         proto_tree *h261_tree     = NULL;
77         unsigned int offset       = 0;
78
79         if ( check_col( pinfo->fd, COL_PROTOCOL ) )   {
80                 col_set_str( pinfo->fd, COL_PROTOCOL, "H.261" );
81         }
82         
83         if ( check_col( pinfo->fd, COL_INFO) ) {
84                 col_set_str( pinfo->fd, COL_INFO, "H.261 message");
85         }
86
87         if ( tree ) {
88                 /* Using fd->pkt_len here instead of END_OF_FRAME. This variable is changed in dissect_rtp()! */
89                 ti = proto_tree_add_item( tree, proto_h261, tvb, offset, tvb_length( tvb ), FALSE );
90                 h261_tree = proto_item_add_subtree( ti, ett_h261 );
91                 /* SBIT 1st octet, 3 bits */
92                 proto_tree_add_uint( h261_tree, hf_h261_sbit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) >> 5 );
93                 /* EBIT 1st octet, 3 bits */
94                 proto_tree_add_item( h261_tree, hf_h261_ebit, tvb, offset, 1, ( tvb_get_guint8( tvb, offset )  << 3 ) >> 5 );
95                 /* I flag, 1 bit */
96                 proto_tree_add_boolean( h261_tree, hf_h261_ibit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 2 );
97                 /* V flag, 1 bit */
98                 proto_tree_add_boolean( h261_tree, hf_h261_vbit, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 1 );
99                 offset++;
100
101                 /* GOBN 2nd octet, 4 bits */
102                 proto_tree_add_uint( h261_tree, hf_h261_gobn, tvb, offset, 1, tvb_get_guint8( tvb, offset ) >> 4 );
103                 /* MBAP 2nd octet, 4 bits, 3rd octet 1 bit */
104                 proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1,
105                     ( tvb_get_guint8( tvb, offset ) & 15 )
106                     + ( tvb_get_guint8( tvb, offset + 1 ) >> 7 ) );
107                 offset++;
108
109                 /* QUANT 3rd octet, 5 bits (starting at bit 2!) */
110                 proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 124 );
111                 /* HMDV 3rd octet 2 bits, 4th octet 3 bits */
112                 proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1,
113                     ( ( tvb_get_guint8( tvb, offset ) << 4) >> 4 )
114                      + ( tvb_get_guint8( tvb, offset ) >> 5 ) );
115                 offset++;
116
117                 /* VMVD 4th octet, last 5 bits */
118                 proto_tree_add_uint( h261_tree, hf_h261_mbap, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 31 );
119                 offset++;
120
121                 /* The rest of the packet is the H.261 stream */
122                 proto_tree_add_bytes( h261_tree, hf_h261_data, tvb, offset, tvb_length_remaining( tvb, offset ), tvb_get_ptr( tvb, offset, tvb_length_remaining( tvb, offset ) ) );
123         }
124 }
125
126 void
127 proto_register_h261(void)
128 {
129         static hf_register_info hf[] = 
130         {
131                 { 
132                         &hf_h261_sbit,
133                         { 
134                                 "Start bit position", 
135                                 "h261.sbit", 
136                                 FT_UINT8, 
137                                 BASE_DEC, 
138                                 NULL, 
139                                 0x0,
140                                 "" 
141                         }
142                 },
143                 { 
144                         &hf_h261_ebit,
145                         { 
146                                 "End bit position", 
147                                 "h261.ebit", 
148                                 FT_UINT8, 
149                                 BASE_DEC, 
150                                 NULL, 
151                                 0x0,
152                                 "" 
153                         }
154                 },
155                 { 
156                         &hf_h261_ibit,
157                         { 
158                                 "Intra frame encoded data flag", 
159                                 "h261.i", 
160                                 FT_BOOLEAN, 
161                                 BASE_NONE, 
162                                 NULL, 
163                                 0x0,
164                                 "" 
165                         }
166                 },
167                 { 
168                         &hf_h261_vbit,
169                         { 
170                                 "Motion vector flag", 
171                                 "h261.v", 
172                                 FT_BOOLEAN, 
173                                 BASE_NONE, 
174                                 NULL, 
175                                 0x0,
176                                 "" 
177                         }
178                 },
179                 { 
180                         &hf_h261_gobn,
181                         { 
182                                 "GOB Number", 
183                                 "h261.gobn", 
184                                 FT_UINT8, 
185                                 BASE_DEC, 
186                                 NULL, 
187                                 0x0,
188                                 "" 
189                         }
190                 },
191                 { 
192                         &hf_h261_mbap,
193                         { 
194                                 "Macroblock address predictor", 
195                                 "h261.mbap", 
196                                 FT_UINT8, 
197                                 BASE_DEC, 
198                                 NULL, 
199                                 0x0,
200                                 "" 
201                         }
202                 },
203                 { 
204                         &hf_h261_quant,
205                         { 
206                                 "Quantizer", 
207                                 "h261.quant", 
208                                 FT_UINT8, 
209                                 BASE_DEC, 
210                                 NULL, 
211                                 0x0,
212                                 "" 
213                         }
214                 },
215                 { 
216                         &hf_h261_hmvd,
217                         { 
218                                 "Horizontal motion vctor data", 
219                                 "h261.hmvd", 
220                                 FT_UINT8, 
221                                 BASE_DEC, 
222                                 NULL, 
223                                 0x0,
224                                 "" 
225                         }
226                 },
227                 { 
228                         &hf_h261_vmvd,
229                         { 
230                                 "Vertical motion vector data", 
231                                 "h261.vmvd", 
232                                 FT_UINT8, 
233                                 BASE_DEC, 
234                                 NULL, 
235                                 0x0,
236                                 "" 
237                         }
238                 },
239                 { 
240                         &hf_h261_data,
241                         { 
242                                 "H.261 stream", 
243                                 "h261.stream", 
244                                 FT_BYTES, 
245                                 BASE_NONE, 
246                                 NULL, 
247                                 0x0,
248                                 "" 
249                         }
250                 },
251 };
252         
253         static gint *ett[] = 
254         {
255                 &ett_h261,
256         };
257
258
259         proto_h261 = proto_register_protocol("ITU-T Recommendation H.261",
260             "H.261", "h261");
261         proto_register_field_array(proto_h261, hf, array_length(hf));
262         proto_register_subtree_array(ett, array_length(ett));
263 }