7fa16f888b1ebf07ccbe61752b0b71c9e731f7af
[obnox/wireshark/wip.git] / epan / dissectors / packet-h223.c
1 /* packet-h223.c
2  * Routines for H.223 packet dissection
3  * Copyright (c) 2004-5 MX Telecom Ltd <richardv@mxtelecom.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/emem.h>
32 #include <epan/bitswap.h>
33 #include <epan/circuit.h>
34 #include <epan/conversation.h>
35 #include <epan/packet.h>
36 #include <epan/stream.h>
37 #include <epan/reassemble.h>
38 #include <epan/golay.h>
39 #include <epan/iax2_codec_type.h>
40 #include <epan/dissectors/packet-frame.h>
41 #include <epan/asn1.h>
42 #include <epan/dissectors/packet-h245.h>
43
44 #include "packet-h223.h"
45
46 #include <string.h>
47
48 /* #define DEBUG_H223 */
49
50 /* debug the mux-pdu defragmentation code. warning: verbose output! */
51 /* #define DEBUG_H223_FRAGMENTATION */
52
53 #define PROTO_TAG_H223 "H223"
54
55 /* Wireshark ID of the H.223 protocol */
56 static int proto_h223 = -1;
57
58 /* The following hf_* variables are used to hold the Wireshark IDs of
59  * our header fields; they are filled out when we call
60  * proto_register_field_array() in proto_register_h223()
61  */
62 static int hf_h223_non_h223_data = -1;
63 static int hf_h223_mux_stuffing_pdu = -1;
64 static int hf_h223_mux_pdu = -1;
65 static int hf_h223_mux_header = -1;
66 static int hf_h223_mux_rawhdr = -1;
67 static int hf_h223_mux_correctedhdr = -1;
68 static int hf_h223_mux_mc = -1;
69 static int hf_h223_mux_mpl = -1;
70 static int hf_h223_mux_deact = -1;
71 static int hf_h223_mux_vc = -1;
72 static int hf_h223_mux_extra = -1;
73 static int hf_h223_mux_hdlc2 = -1;
74 static int hf_h223_mux_fragments = -1;
75 static int hf_h223_mux_fragment = -1;
76 static int hf_h223_mux_fragment_overlap = -1;
77 static int hf_h223_mux_fragment_overlap_conflict = -1;
78 static int hf_h223_mux_fragment_multiple_tails = -1;
79 static int hf_h223_mux_fragment_too_long_fragment = -1;
80 static int hf_h223_mux_fragment_error = -1;
81 static int hf_h223_mux_fragment_count = -1;
82 static int hf_h223_mux_reassembled_in = -1;
83 static int hf_h223_mux_reassembled_length = -1;
84
85 static int hf_h223_al_fragments = -1;
86 static int hf_h223_al_fragment = -1;
87 static int hf_h223_al_fragment_overlap = -1;
88 static int hf_h223_al_fragment_overlap_conflict = -1;
89 static int hf_h223_al_fragment_multiple_tails = -1;
90 static int hf_h223_al_fragment_too_long_fragment = -1;
91 static int hf_h223_al_fragment_error = -1;
92 static int hf_h223_al_fragment_count = -1;
93 static int hf_h223_al_reassembled_in = -1;
94 static int hf_h223_al_reassembled_length = -1;
95
96 static int hf_h223_al1 = -1;
97 static int hf_h223_al1_framed = -1;
98 static int hf_h223_al2 = -1;
99 static int hf_h223_al2_sequenced = -1;
100 static int hf_h223_al2_unsequenced = -1;
101 static int hf_h223_al2_seqno = -1;
102 static int hf_h223_al2_crc = -1;
103 static int hf_h223_al2_crc_bad = -1;
104
105 static int hf_h223_al_payload = -1;
106
107 /* These are the ids of the subtrees that we may be creating */
108 static gint ett_h223 = -1;
109 static gint ett_h223_non_h223_data = -1;
110 static gint ett_h223_mux_stuffing_pdu = -1;
111 static gint ett_h223_mux_pdu = -1;
112 static gint ett_h223_mux_header = -1;
113 static gint ett_h223_mux_deact = -1;
114 static gint ett_h223_mux_vc = -1;
115 static gint ett_h223_mux_extra = -1;
116 static gint ett_h223_mux_fragments = -1;
117 static gint ett_h223_mux_fragment  = -1;
118 static gint ett_h223_al_fragments = -1;
119 static gint ett_h223_al_fragment  = -1;
120 static gint ett_h223_al1 = -1;
121 static gint ett_h223_al2 = -1;
122 static gint ett_h223_al_payload = -1;
123
124 /* These are the handles of our subdissectors */
125 static dissector_handle_t data_handle;
126 static dissector_handle_t srp_handle;
127
128 static const fragment_items h223_mux_frag_items _U_ = {
129     &ett_h223_mux_fragment,
130     &ett_h223_mux_fragments,
131     &hf_h223_mux_fragments,
132     &hf_h223_mux_fragment,
133     &hf_h223_mux_fragment_overlap,
134     &hf_h223_mux_fragment_overlap_conflict,
135     &hf_h223_mux_fragment_multiple_tails,
136     &hf_h223_mux_fragment_too_long_fragment,
137     &hf_h223_mux_fragment_error,
138     &hf_h223_mux_fragment_count,
139     &hf_h223_mux_reassembled_in,
140     &hf_h223_mux_reassembled_length,
141     "fragments"
142 };
143
144 static const fragment_items h223_al_frag_items = {
145     &ett_h223_al_fragment,
146     &ett_h223_al_fragments,
147     &hf_h223_al_fragments,
148     &hf_h223_al_fragment,
149     &hf_h223_al_fragment_overlap,
150     &hf_h223_al_fragment_overlap_conflict,
151     &hf_h223_al_fragment_multiple_tails,
152     &hf_h223_al_fragment_too_long_fragment,
153     &hf_h223_al_fragment_error,
154     &hf_h223_al_fragment_count,
155     &hf_h223_al_reassembled_in,
156     &hf_h223_al_reassembled_length,
157     "fragments"
158 };
159
160 /* this is a fudge to pass pdu_offset into add_h223_mux_element() */
161 static guint32 pdu_offset;
162
163 /***************************************************************************
164  *
165  * virtual circuit number handling
166  *
167  * we have to be able to manage more than one H.223 call at a time,
168  * so have a hash which maps {call,vc} to an integer.
169  */
170
171 typedef struct _h223_call_info h223_call_info;
172
173 typedef struct {
174     const h223_call_info* call; /* h223 call */
175     guint32 vc;                 /* child circuit */
176 } circuit_chain_key;
177
178 static GHashTable *circuit_chain_hashtable = NULL;
179 static guint circuit_chain_count = 1;
180
181 /* Hash Functions */
182 static gint
183 circuit_chain_equal(gconstpointer v, gconstpointer w)
184 {
185     const circuit_chain_key *v1 = (const circuit_chain_key *)v;
186     const circuit_chain_key *v2 = (const circuit_chain_key *)w;
187     gint result;
188     result = ( v1->call == v2->call &&
189                v1->vc == v2 -> vc );
190     return result;
191 }
192
193 static guint
194 circuit_chain_hash (gconstpointer v)
195 {
196     const circuit_chain_key *key = (const circuit_chain_key *)v;
197     guint hash_val = ((guint32)(unsigned long)(key->call))^(((guint32)key->vc) << 16);
198     return hash_val;
199 }
200
201 static guint32
202 circuit_chain_lookup(const h223_call_info* call_info, guint32 child_vc)
203 {
204     circuit_chain_key key, *new_key;
205     guint32 circuit_id;
206     key.call = call_info;
207     key.vc = child_vc;
208     circuit_id = GPOINTER_TO_UINT(g_hash_table_lookup( circuit_chain_hashtable, &key ));
209     if( circuit_id == 0 ) {
210         new_key = se_alloc(sizeof(circuit_chain_key));
211         *new_key = key;
212         circuit_id = ++circuit_chain_count;
213         g_hash_table_insert(circuit_chain_hashtable, new_key, GUINT_TO_POINTER(circuit_id));
214     }
215     return circuit_id;
216 }
217
218 static void
219 circuit_chain_init(void)
220 {
221     if (circuit_chain_hashtable)
222         g_hash_table_destroy(circuit_chain_hashtable);
223     circuit_chain_hashtable = g_hash_table_new(circuit_chain_hash, circuit_chain_equal);
224     circuit_chain_count = 1;
225 }
226
227
228 /***************************************************************************
229  *
230  * Call information management
231  *
232  */
233
234 /* we keep information on each call in an h223_call_info structure
235  *
236  * We attach the h223_call_info structures to individual calls with
237  * circuit_add_proto_data().
238 */
239
240 typedef struct _h223_mux_element_listitem h223_mux_element_listitem;
241 struct _h223_mux_element_listitem {
242     h223_mux_element          *me;
243     guint32                    first_frame;
244     guint32                    pdu_offset;
245     h223_mux_element_listitem *next;
246 };
247
248 /* we have this information for each stream */
249 typedef struct {
250     h223_mux_element_listitem* mux_table[16];
251 } h223_call_direction_data;
252
253
254 struct _h223_call_info {
255     /* H.223 level: 0 for standard H223, 1, 2 or 3 for the enhanced protocols
256        specified in the annexes
257     */
258     int h223_level;
259
260     /* for H.223 streams over TCP (as opposed to IAX), this
261        stores the source address and port of the first packet spotted,
262        so that we can differentiate directions.
263     */
264     address srcaddress;
265     guint32 srcport;
266
267     h223_call_direction_data direction_data[2];
268 };
269
270 typedef struct _h223_lc_params_listitem h223_lc_params_listitem;
271 struct _h223_lc_params_listitem
272 {
273     h223_lc_params         *lc_params;
274     guint32                 first_frame;
275     guint32                 last_frame;
276     h223_lc_params_listitem *next;
277 };
278
279 typedef struct {
280     h223_lc_params_listitem *lc_params[2];
281     h223_call_info          *call_info;
282 } h223_vc_info;
283
284 static void
285 add_h223_mux_element(h223_call_direction_data *direct, guint8 mc, h223_mux_element *me, guint32 framenum)
286 {
287     h223_mux_element_listitem *li;
288     h223_mux_element_listitem **old_li_ptr;
289     h223_mux_element_listitem *old_li;
290
291     DISSECTOR_ASSERT(mc < 16);
292
293     li = se_alloc(sizeof(h223_mux_element_listitem));
294     old_li_ptr = &(direct->mux_table[mc]);
295     old_li = *old_li_ptr;
296     if( !old_li ) {
297         direct->mux_table[mc] = li;
298     } else {
299         while( old_li->next ) {
300             old_li_ptr = &(old_li->next);
301             old_li = *old_li_ptr;
302         }
303         if( framenum < old_li->first_frame || (framenum == old_li->first_frame && pdu_offset < old_li->pdu_offset)  )
304             return;
305         else if ( framenum == old_li->first_frame && pdu_offset == old_li->pdu_offset )
306             *old_li_ptr = li; /* replace the tail of the list with the new item, since */
307                               /* a single h223 pdu has just set the same MC twice.. */
308         else
309             old_li->next = li;
310     }
311     li->first_frame = framenum;
312     li->pdu_offset = pdu_offset;
313     li->next = 0;
314     li->me = me;
315 }
316
317 static h223_mux_element*
318 find_h223_mux_element(h223_call_direction_data* direct, guint8 mc, guint32 framenum, guint32 pkt_offset)
319 {
320     h223_mux_element_listitem* li;
321
322     DISSECTOR_ASSERT(mc < 16);
323
324     li = direct->mux_table[mc];
325
326     while( li && li->next && li->next->first_frame < framenum )
327         li = li->next;
328     while( li && li->next && li->next->first_frame == framenum && li->next->pdu_offset < pkt_offset )
329         li = li->next;
330     if( li ) {
331         return li->me;
332     } else {
333         return NULL;
334     }
335 }
336
337 static void
338 add_h223_lc_params(h223_vc_info* vc_info, int direction, h223_lc_params *lc_params, guint32 framenum )
339 {
340     h223_lc_params_listitem *li = se_alloc(sizeof(h223_lc_params_listitem));
341     h223_lc_params_listitem **old_li_ptr = &(vc_info->lc_params[direction ? 0 : 1]);
342     h223_lc_params_listitem *old_li = *old_li_ptr;
343     if( !old_li ) {
344         vc_info->lc_params[direction ? 0 : 1] = li;
345     } else {
346         while( old_li->next ) {
347             old_li_ptr = &(old_li->next);
348             old_li = *old_li_ptr;
349         }
350         if( framenum < old_li->first_frame )
351             return;
352         else if( framenum == old_li->first_frame )
353             *old_li_ptr = li;
354         else {
355             old_li->next = li;
356             old_li->last_frame = framenum - 1;
357         }
358     }
359     li->first_frame = framenum;
360     li->last_frame = 0;
361     li->next = 0;
362     li->lc_params = lc_params;
363 }
364
365 static h223_lc_params*
366 find_h223_lc_params(h223_vc_info* vc_info, int direction, guint32 framenum)
367 {
368     h223_lc_params_listitem* li = vc_info->lc_params[direction? 0 : 1];
369     while( li && li->next && li->next->first_frame <= framenum )
370         li = li->next;
371     if( li )
372         return li->lc_params;
373     else
374         return NULL;
375 }
376
377 static void
378 init_direction_data(h223_call_direction_data *direct)
379 {
380     int i;
381     h223_mux_element *mc0_element;
382
383     for ( i = 0; i < 16; ++i )
384         direct->mux_table[i] = NULL;
385
386     /* set up MC 0 to contain just VC 0 */
387     mc0_element = se_alloc(sizeof(h223_mux_element));
388     add_h223_mux_element( direct, 0, mc0_element, 0 );
389     mc0_element->sublist = NULL;
390     mc0_element->vc = 0;
391     mc0_element->repeat_count = 0; /* until closing flag */
392     mc0_element->next = NULL;
393 }
394
395 static h223_vc_info*
396 h223_vc_info_new( h223_call_info* call_info )
397 {
398     h223_vc_info *vc_info = se_alloc(sizeof(h223_vc_info));
399     vc_info->lc_params[0] = vc_info->lc_params[1] = NULL;
400     vc_info->call_info = call_info;
401     return vc_info;
402 }
403
404 static void
405 init_logical_channel( guint32 start_frame, h223_call_info* call_info, int vc, int direction, h223_lc_params* params )
406 {
407     guint32 circuit_id = circuit_chain_lookup(call_info, vc);
408     circuit_t *subcircuit;
409     h223_vc_info *vc_info;
410     subcircuit = find_circuit( CT_H223, circuit_id, start_frame );
411
412     if( subcircuit == NULL ) {
413         subcircuit = circuit_new( CT_H223, circuit_id, start_frame );
414 #ifdef DEBUG_H223
415         g_debug("%d: Created new circuit %d for call %p VC %d", start_frame, circuit_id, call_info, vc);
416 #endif
417         vc_info = h223_vc_info_new( call_info );
418         circuit_add_proto_data( subcircuit, proto_h223, vc_info );
419     } else {
420         vc_info = circuit_get_proto_data( subcircuit, proto_h223 );
421     }
422     add_h223_lc_params( vc_info, direction, params, start_frame );
423 }
424
425 /* create a brand-new h223_call_info structure */
426 static h223_call_info *
427 create_call_info( guint32 start_frame )
428 {
429     h223_call_info *datax;
430     h223_lc_params *vc0_params;
431
432     datax = se_alloc(sizeof(h223_call_info));
433
434     /* initialise the call info */
435     init_direction_data(&datax -> direction_data[0]);
436     init_direction_data(&datax -> direction_data[1]);
437
438     /* FIXME shouldn't this be figured out dynamically? */
439     datax -> h223_level = 2;
440
441     vc0_params = se_alloc(sizeof(h223_lc_params));
442     vc0_params->al_type = al1Framed;
443     vc0_params->al_params = NULL;
444     vc0_params->segmentable = TRUE;
445     vc0_params->subdissector = srp_handle;
446     init_logical_channel( start_frame, datax, 0, P2P_DIR_SENT, vc0_params );
447     init_logical_channel( start_frame, datax, 0, P2P_DIR_RECV, vc0_params );
448     return datax;
449 }
450
451 /* find or create call_info struct for calls over circuits (eg, IAX) */
452 static h223_call_info *
453 find_or_create_call_info_circ(packet_info * pinfo)
454 {
455     h223_call_info *datax;
456     circuit_t *circ = NULL;
457
458     if(pinfo->ctype != CT_NONE)
459         circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
460     if(circ == NULL)
461         return NULL;
462
463     datax = (h223_call_info *)circuit_get_proto_data(circ, proto_h223);
464
465     if( datax == NULL ) {
466         datax = create_call_info(pinfo->fd->num);
467
468 #ifdef DEBUG_H223
469         g_debug("%u: Created new call %p for circuit %p ctype %d, id %u",
470                 pinfo->fd->num, datax, circ, pinfo->ctype, pinfo->circuit_id);
471 #endif
472         circuit_add_proto_data(circ, proto_h223, datax);
473     }
474
475     /* work out what direction we're really going in */
476     if( pinfo->p2p_dir < 0 || pinfo->p2p_dir > 1)
477         pinfo->p2p_dir = P2P_DIR_SENT;
478
479     return datax;
480 }
481
482 /* find or create call_info struct for calls over conversations (eg, RTP) */
483 static h223_call_info *
484 find_or_create_call_info_conv(packet_info * pinfo)
485 {
486     h223_call_info *datax;
487     conversation_t *conv;
488
489     /* assume we're running atop TCP or RTP; use the conversation support */
490     conv = find_conversation( pinfo->fd->num,
491                               &pinfo->src,&pinfo->dst,
492                               pinfo->ptype,
493                               pinfo->srcport,pinfo->destport, 0 );
494
495     /* both RTP and TCP track their conversations, so just assert here if
496      * we can't find one */
497     DISSECTOR_ASSERT(conv);
498
499     datax = (h223_call_info *)conversation_get_proto_data(conv, proto_h223);
500
501     if(datax == NULL && pinfo->ptype == PT_UDP ) {
502         conversation_t *conv2;
503
504         /* RTP tracks the two sides of the conversation totally separately;
505          * this messes us up totally.
506          *
507          * Look for another converstation, going in the opposite direction.
508          */
509         conv2 = find_conversation( pinfo->fd->num,
510                                   &pinfo->dst,&pinfo->src,
511                                   pinfo->ptype,
512                                   pinfo->destport,pinfo->srcport, 0 );
513         if(conv2 != NULL)
514             datax = (h223_call_info *)conversation_get_proto_data(conv2, proto_h223);
515
516         if(datax != NULL) {
517 #ifdef DEBUG_H223
518             g_debug("%u: Identified conv %p as reverse of conv %p with call %p and type=%u src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u",
519                     pinfo->fd->num, conv, conv2, datax, pinfo->ptype,
520                     pinfo->dst.data[0], pinfo->dst.data[1], pinfo->dst.data[2], pinfo->dst.data[3],
521                     pinfo->destport,
522                     pinfo->src.data[0], pinfo->src.data[1], pinfo->src.data[2], pinfo->src.data[3],
523                     pinfo->srcport);
524 #endif
525             conversation_add_proto_data(conv, proto_h223, datax);
526         }
527     }
528
529     /* we still haven't found any call data - create a new one for this
530      * conversation */
531     if(datax == NULL) {
532         datax = create_call_info(pinfo->fd->num);
533
534 #ifdef DEBUG_H223
535         g_debug("%u: Created new call %p for conv %p type=%u src=%u.%u.%u.%u:%u dst=%u.%u.%u.%u:%u",
536                 pinfo->fd->num, datax, conv, pinfo->ptype,
537                 pinfo->src.data[0], pinfo->src.data[1], pinfo->src.data[2], pinfo->src.data[3],
538                 pinfo->srcport,
539                 pinfo->dst.data[0], pinfo->dst.data[1], pinfo->dst.data[2], pinfo->dst.data[3],
540                 pinfo->destport);
541 #endif
542
543         conversation_add_proto_data(conv, proto_h223, datax);
544         /* add the source details so we can distinguish directions
545          * in future */
546         COPY_ADDRESS(&(datax -> srcaddress), &(pinfo->src));
547         datax -> srcport = pinfo->srcport;
548     }
549
550     /* work out what direction we're really going in */
551     if( ADDRESSES_EQUAL( &(pinfo->src), &(datax->srcaddress))
552         && pinfo->srcport == datax->srcport )
553         pinfo->p2p_dir = P2P_DIR_SENT;
554     else
555         pinfo->p2p_dir = P2P_DIR_RECV;
556
557     return datax;
558 }
559
560 static h223_call_info *
561 find_or_create_call_info ( packet_info * pinfo )
562 {
563     h223_call_info *datax;
564
565     datax = find_or_create_call_info_circ(pinfo);
566     if(datax == NULL)
567         datax = find_or_create_call_info_conv(pinfo);
568     return datax;
569 }
570
571 /* called from the h245 dissector to handle a MultiplexEntrySend message */
572 static void
573 h223_set_mc( packet_info* pinfo, guint8 mc, h223_mux_element* me )
574 {
575     circuit_t *circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
576     h223_vc_info* vc_info;
577
578     /* if this h245 pdu packet came from an h223 circuit, add the details on
579      * the new mux entry */
580     if(circ) {
581         vc_info = circuit_get_proto_data(circ, proto_h223);
582         add_h223_mux_element( &(vc_info->call_info->direction_data[pinfo->p2p_dir ? 0 : 1]), mc, me, pinfo->fd->num );
583     }
584 }
585
586 /* called from the h245 dissector to handle an OpenLogicalChannelAck message */
587 static void
588 h223_add_lc( packet_info* pinfo, guint16 lc, h223_lc_params* params )
589 {
590     circuit_t *circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
591     h223_vc_info* vc_info;
592
593     /* if this h245 pdu packet came from an h223 circuit, add the details on
594      * the new channel */
595     if(circ) {
596         vc_info = circuit_get_proto_data(circ, proto_h223);
597         init_logical_channel( pinfo->fd->num, vc_info->call_info, lc, pinfo->p2p_dir, params );
598     }
599 }
600
601 /************************************************************************************
602  *
603  * AL-PDU dissection
604  */
605
606 static const guint8 crctable[256] = {
607     0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
608     0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
609     0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
610     0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
611     0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
612     0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
613     0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
614     0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
615     0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
616     0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
617     0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
618     0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
619     0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
620     0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
621     0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
622     0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf };
623
624 static guint8 h223_al2_crc8bit( tvbuff_t *tvb ) {
625     guint32 len = tvb_reported_length(tvb) - 1;
626     const guint8* datax = tvb_get_ptr( tvb, 0, len );
627     unsigned char crc = 0;
628     guint32 pos = 0;
629     DISSECTOR_ASSERT(tvb_reported_length(tvb) >= 1);
630     while ( len-- )
631         crc = crctable[crc^datax[pos++]];
632     return crc;
633 }
634
635 static void
636 dissect_mux_al_pdu( tvbuff_t *tvb, packet_info *pinfo, proto_tree *vc_tree,
637 /*                  circuit_t* vc_circuit, */
638                     h223_lc_params* lc_params )
639 {
640     proto_tree *al_tree = NULL;
641     proto_item *al_item, *hidden_item;
642     proto_tree *al_subtree;
643     proto_item *al_subitem = NULL;
644     proto_item *tmp_item;
645     tvbuff_t *next_tvb = NULL;
646     dissector_handle_t subdissector = lc_params->subdissector;
647     guint32 len = tvb_reported_length(tvb);
648
649     guint8 calc_checksum;
650     guint8 real_checksum;
651     gboolean al2_sequenced = FALSE;
652     int data_start;
653
654     switch( lc_params->al_type ) {
655         case al1Framed:
656         case al1NotFramed:
657             al_item = proto_tree_add_none_format(vc_tree, hf_h223_al1, tvb, 0, -1, "H.223 AL1 (%sframed)",
658                                                  (lc_params->al_type==al1Framed)?"":"not ");
659             al_tree = proto_item_add_subtree (al_item, ett_h223_al1);
660             if(lc_params->al_type == al1Framed) {
661                 hidden_item = proto_tree_add_boolean(al_tree, hf_h223_al1_framed, tvb, 0, 1, TRUE );
662                 PROTO_ITEM_SET_HIDDEN(hidden_item);
663             }
664             next_tvb = tvb;
665             al_subitem = proto_tree_add_item(al_tree, hf_h223_al_payload, next_tvb, 0, -1, FALSE);
666             break;
667
668         case al2WithSequenceNumbers:
669             al2_sequenced = TRUE;
670             /* fall-through */
671         case al2WithoutSequenceNumbers:
672             tmp_item = proto_tree_add_boolean(vc_tree, hf_h223_al2, tvb, 0, 0, TRUE );
673
674             al_item = proto_tree_add_item(vc_tree,
675                                           al2_sequenced?hf_h223_al2_sequenced:hf_h223_al2_unsequenced,
676                                           tvb, 0, -1,FALSE);
677             al_tree = proto_item_add_subtree (al_item, ett_h223_al2);
678
679             PROTO_ITEM_SET_GENERATED(tmp_item);
680
681             /* check minimum payload length */
682             if(len < (al2_sequenced?2U:1U))
683                 THROW(BoundsError);
684
685             data_start = 0;
686             if( al2_sequenced ) {
687                 proto_tree_add_item(al_tree, hf_h223_al2_seqno, tvb, 0, 1, TRUE);
688                 data_start++;
689             }
690
691             next_tvb = tvb_new_subset( tvb, data_start, len-1-data_start, len-1-data_start );
692             al_subitem = proto_tree_add_item(al_tree, hf_h223_al_payload, next_tvb, 0, -1, FALSE);
693
694             calc_checksum = h223_al2_crc8bit(tvb);
695             real_checksum = tvb_get_guint8(tvb, len - 1);
696
697             if( calc_checksum == real_checksum ) {
698                 proto_tree_add_uint_format(al_tree, hf_h223_al2_crc, tvb, len - 1, 1, real_checksum,
699                                            "CRC: 0x%02x (correct)", real_checksum );
700             } else {
701                 proto_tree_add_uint_format(al_tree, hf_h223_al2_crc, tvb, len - 1, 1, real_checksum,
702                                            "CRC: 0x%02x (incorrect, should be 0x%02x)", real_checksum, calc_checksum );
703                 tmp_item = proto_tree_add_boolean( al_tree, hf_h223_al2_crc_bad, tvb, len - 1, 1, TRUE );
704                 PROTO_ITEM_SET_GENERATED(tmp_item);
705
706                 /* don't pass pdus which fail checksums on to the subdissector */
707                 subdissector = data_handle;
708             }
709             break;
710         default:
711             call_dissector(data_handle, tvb, pinfo, vc_tree);
712             return;
713     }
714
715     if (!subdissector)
716         subdissector = data_handle;
717
718     al_subtree = proto_item_add_subtree(al_subitem, ett_h223_al_payload);
719     call_dissector(subdissector, next_tvb, pinfo, al_subtree);
720 }
721
722 /************************************************************************************
723  *
724  * MUX-PDU dissection
725  */
726
727
728 /* dissect a fragment of a MUX-PDU which belongs to a particular VC
729  *
730  * tvb          buffer containing the MUX-PDU fragment
731  * pinfo        info on the packet containing the last fragment of the MUX-PDU
732  * pkt_offset   offset within the block from the superdissector where the
733  *                fragment starts (must increase monotonically for constant pinfo->fd->num)
734  * pdu_tree     dissection tree for the PDU; a single item will be added (with
735  *              its own subtree)
736  * vc           VC for this SDU
737  * end_of_mux_sdu true if this is a segmentable VC and this is the last
738  *              fragment in an SDU
739  */
740 static void
741 dissect_mux_sdu_fragment(tvbuff_t *volatile next_tvb, packet_info *pinfo,
742                          guint32 pkt_offset, proto_tree *pdu_tree,
743                          h223_call_info* call_info, guint16 vc,
744                          gboolean end_of_mux_sdu)
745 {
746     /* update the circuit details before passing to a subdissector */
747     guint32 orig_circuit = pinfo->circuit_id;
748     guint32 orig_ctype = pinfo->ctype;
749     pinfo->circuit_id=circuit_chain_lookup(call_info, vc);
750     pinfo->ctype=CT_H223;
751
752     TRY {
753         circuit_t *subcircuit=find_circuit(pinfo->ctype,pinfo->circuit_id,pinfo->fd->num);
754         proto_tree *vc_tree = NULL;
755         proto_item *vc_item;
756         h223_vc_info *vc_info = NULL;
757         h223_lc_params *lc_params = NULL;
758
759         if(pdu_tree) {
760             vc_item = proto_tree_add_uint(pdu_tree, hf_h223_mux_vc, next_tvb, 0, tvb_reported_length(next_tvb), vc);
761             vc_tree = proto_item_add_subtree (vc_item, ett_h223_mux_vc);
762         }
763
764         if( subcircuit == NULL ) {
765             g_message( "Frame %d: Subcircuit id %d not found for call %p VC %d", pinfo->fd->num,
766                        pinfo->circuit_id, (void *)call_info, vc );
767         } else {
768             vc_info = circuit_get_proto_data(subcircuit, proto_h223);
769             if( vc_info != NULL ) {
770                 lc_params = find_h223_lc_params( vc_info, pinfo->p2p_dir, pinfo->fd->num );
771             }
772         }
773
774
775         if( lc_params != NULL ) {
776                 if( lc_params->segmentable && lc_params->al_type != al1NotFramed ) {
777                     stream_t *substream;
778                     stream_pdu_fragment_t *frag;
779
780                     substream = find_stream_circ(subcircuit,pinfo->p2p_dir);
781                     if(substream == NULL )
782                         substream = stream_new_circ(subcircuit,pinfo->p2p_dir);
783                     frag = stream_find_frag(substream,pinfo->fd->num,pkt_offset);
784
785                     if(frag == NULL ) {
786 #ifdef DEBUG_H223
787                         g_debug("%d: New H.223 VC fragment: Parent circuit %d; subcircuit %d; offset %d; len %d, end %d",
788                                 pinfo->fd->num, orig_circuit, pinfo->circuit_id, pkt_offset, tvb_reported_length(next_tvb), end_of_mux_sdu);
789 #endif
790                         frag = stream_add_frag(substream,pinfo->fd->num,pkt_offset,
791                                                next_tvb,pinfo,!end_of_mux_sdu);
792                     } else {
793 #ifdef DEBUG_H223
794                         g_debug("%d: Found H.223 VC fragment: Parent circuit %d; subcircuit %d; offset %d; len %d, end %d",
795                                 pinfo->fd->num, orig_circuit, pinfo->circuit_id, pkt_offset, tvb_reported_length(next_tvb), end_of_mux_sdu);
796 #endif
797                     }
798
799                     next_tvb = stream_process_reassembled(
800                         next_tvb, 0, pinfo,
801                         "Reassembled H.223 AL-PDU",
802                         frag, &h223_al_frag_items,
803                         NULL, vc_tree);
804                 }
805
806                 if(next_tvb) {
807                     /* fudge to pass pkt_offset down to add_h223_mux_element,
808                      * should it be called */
809                     pdu_offset = pkt_offset;
810                     dissect_mux_al_pdu(next_tvb, pinfo, vc_tree,/* subcircuit,*/ lc_params );
811                 }
812         } else {
813             call_dissector(data_handle,next_tvb,pinfo,vc_tree);
814         }
815     }
816
817     /* restore the original circuit details for future PDUs */
818     FINALLY {
819         pinfo->ctype=orig_ctype;
820         pinfo->circuit_id=orig_circuit;
821     }
822     ENDTRY;
823 }
824
825 static guint32
826 mux_element_sublist_size( h223_mux_element* me )
827 {
828     h223_mux_element *current_me = me;
829     guint32 length = 0;
830     while ( current_me ) {
831         current_me = current_me->next;
832         if ( current_me->sublist )
833             length += current_me->repeat_count * mux_element_sublist_size( current_me->sublist );
834         else
835             length += current_me->repeat_count;
836     }
837     if ( length == 0 ) { /* should never happen, but to avoid infinite loops... */
838         DISSECTOR_ASSERT_NOT_REACHED();
839         length = 1;
840     }
841     return length;
842 }
843
844 /* dissect part of a MUX-PDU payload according to a multiplex list
845  *
846  * tvb          buffer containing entire mux-pdu payload
847  * pinfo        info on the packet containing the last fragment of the MUX-PDU
848  * pkt_offset   offset within the block from the superdissector where the
849  *                MUX-PDU starts (must increase monotonically for constant
850  *                pinfo->fd->num)
851  * pdu_tree     dissection tree for the PDU
852  * call_info    data structure for h223 call
853  * me           top of mux list
854  * offset       offset within tvb to start work
855  * endOfMuxSdu  true if the end-of-sdu flag was set
856  */
857 static guint32
858 dissect_mux_payload_by_me_list( tvbuff_t *tvb, packet_info *pinfo,
859                                 guint32 pkt_offset, proto_tree *pdu_tree,
860                                 h223_call_info* call_info,
861                                 h223_mux_element *me, guint32 offset,
862                                 gboolean endOfMuxSdu )
863 {
864     guint32 len = tvb_reported_length(tvb);
865     guint32 frag_len;
866     guint32 sublist_len;
867     int i;
868     while ( me ) {
869         if ( me->sublist ) {
870             if ( me->repeat_count == 0 ) {
871                 for(sublist_len = mux_element_sublist_size( me->sublist );
872                     offset + sublist_len <= len;
873                     offset = dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree,
874                                                              call_info, me->sublist, offset, endOfMuxSdu ) );
875             } else {
876                 for(i = 0; i < me->repeat_count; ++i)
877                     offset = dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree,
878                                                              call_info, me->sublist, offset, endOfMuxSdu );
879             }
880         } else {
881             if ( me->repeat_count == 0 )
882                 frag_len = len - offset;
883             else
884                 frag_len = me->repeat_count;
885             if(frag_len > 0) {
886                 tvbuff_t *next_tvb;
887                 next_tvb = tvb_new_subset(tvb, offset, frag_len, frag_len);
888                 dissect_mux_sdu_fragment( next_tvb, pinfo, pkt_offset + offset, pdu_tree,
889                                           call_info, me->vc, (offset+frag_len==len) && endOfMuxSdu);
890                 offset += frag_len;
891             }
892         }
893         me = me->next;
894     }
895     return offset;
896 }
897
898 /* dissect the payload of a MUX-PDU
899  *
900  * tvb          buffer containing entire mux-pdu payload
901  * pinfo        info on the packet containing the last fragment of the MUX-PDU
902  * pkt_offset   offset within the block from the superdissector where the
903  *                MUX-PDU starts (must increase monotonically for constant
904  *                pinfo->fd->num)
905  * pdu_tree     dissection tree for the PDU
906  * call_info    data structure for h223 call
907  * mc           multiplex code for this PDU
908  * endOfMuxSdu  true if the end-of-sdu flag was set
909  */
910 static void
911 dissect_mux_payload( tvbuff_t *tvb, packet_info *pinfo, guint32 pkt_offset,
912                      proto_tree *pdu_tree, h223_call_info *call_info,
913                      guint8 mc, gboolean endOfMuxSdu )
914 {
915     guint32 len = tvb_reported_length(tvb);
916
917     h223_mux_element* me = find_h223_mux_element( &(call_info->direction_data[pinfo->p2p_dir ? 0 : 1]), mc, pinfo->fd->num, pkt_offset );
918
919     if( me ) {
920         dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree, call_info, me, 0, endOfMuxSdu );
921     } else {
922         /* no entry found in mux-table. ignore packet and dissect as data */
923         proto_tree *vc_tree = NULL;
924
925         if(pdu_tree) {
926             proto_item *vc_item = proto_tree_add_item(pdu_tree, hf_h223_mux_deact, tvb, 0, len, FALSE);
927             vc_tree = proto_item_add_subtree(vc_item, ett_h223_mux_deact);
928         }
929         call_dissector(data_handle,tvb,pinfo,vc_tree);
930     }
931 }
932
933 /* dissect a reassembled mux-pdu
934  *
935  * tvb          buffer containing mux-pdu, including header and closing flag
936  * pinfo        packet info for packet containing the end of the mux-pdu
937  * pkt_offset   offset within the block from the superdissector where the
938  *                MUX-PDU starts (must increase monotonically for constant
939  *                pinfo->fd->num)
940  * h223_tree    dissection tree for h223 protocol; a single item will be added
941  *              (with a sub-tree)
942  * call_info    h223 info structure for this h223 call
943  * pdu_no       index of this pdu within the call
944  */
945 static void
946 dissect_mux_pdu( tvbuff_t *tvb, packet_info *pinfo, guint32 pkt_offset,
947                  proto_tree *h223_tree, h223_call_info *call_info)
948 {
949     guint32 offset = 0;
950     /* actual (as opposed to reported) payload len */
951     guint32 len;
952     guint32 raw_hdr = 0, correct_hdr = 0;
953     gint32  errors = 0;
954     guint16 closing_flag = 0;
955     guint8 mc = 0;
956     guint8 mpl = 0;
957     gboolean end_of_mux_sdu = FALSE;
958     tvbuff_t *pdu_tvb;
959
960     proto_item *pdu_item = NULL;
961     proto_tree *pdu_tree = NULL;
962
963 #ifdef DEBUG_H223_FRAGMENTATION
964     g_debug("%u: dissecting complete H.223 MUX-PDU, pkt_offset %u, len %u",
965             pinfo->fd->num, pkt_offset, tvb_reported_length(tvb));
966 #endif
967
968     switch(call_info->h223_level) {
969         case 0: case 1:
970             raw_hdr = tvb_get_guint8(tvb,0);
971             mc = (guint8)((raw_hdr>>1) & 0xf);
972             end_of_mux_sdu = raw_hdr & 1;
973             offset++;
974             /* closing flag is one byte long for h223 level 0, two for level 1 */
975             len = mpl = tvb_length_remaining(tvb, offset)-(call_info->h223_level+1);
976
977             /* XXX should ignore pdus with incorrect HECs */
978             break;
979
980         case 2:
981             raw_hdr = tvb_get_letoh24(tvb,0);
982             errors = golay_errors(raw_hdr);
983             offset += 3;
984             len = tvb_length_remaining(tvb,offset)-2;
985
986             if(errors != -1) {
987                 correct_hdr = raw_hdr ^ (guint32)errors;
988
989                 mc = (guint8)(correct_hdr & 0xf);
990                 mpl = (guint8)((correct_hdr >> 4) & 0xff);
991
992                 /* we should never have been called if there's not enough data in
993                  * available. */
994                 DISSECTOR_ASSERT(len >= mpl);
995
996                 closing_flag = tvb_get_ntohs(tvb,offset+len);
997                 end_of_mux_sdu = (closing_flag==(0xE14D ^ 0xFFFF));
998             } else {
999                 mc = 0;
1000                 mpl = len;
1001             }
1002             break;
1003
1004         case 3:
1005             /* XXX not implemented */
1006         default:
1007             DISSECTOR_ASSERT_NOT_REACHED();
1008     }
1009
1010
1011     if( h223_tree ) {
1012         if( mpl == 0 ) {
1013             pdu_item = proto_tree_add_item (h223_tree, hf_h223_mux_stuffing_pdu, tvb, 0, -1, FALSE);
1014             pdu_tree = proto_item_add_subtree (pdu_item, ett_h223_mux_stuffing_pdu);
1015         } else {
1016             pdu_item = proto_tree_add_item (h223_tree, hf_h223_mux_pdu, tvb, 0, -1, FALSE);
1017             pdu_tree = proto_item_add_subtree (pdu_item, ett_h223_mux_pdu);
1018         }
1019     }
1020
1021     if( pdu_tree ) {
1022         proto_item *item = proto_tree_add_item (pdu_tree, hf_h223_mux_header, tvb, 0, offset, FALSE);
1023         proto_tree *hdr_tree = proto_item_add_subtree (item, ett_h223_mux_header);
1024
1025         switch(call_info->h223_level) {
1026             case 0: case 1:
1027                 proto_tree_add_uint(hdr_tree,hf_h223_mux_mc,tvb,0,1,mc);
1028                 break;
1029
1030             case 2:
1031                 if( errors == -1 ) {
1032                     proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
1033                                                0, 3, raw_hdr,
1034                                                "Raw value: 0x%06x (uncorrectable errors)", raw_hdr );
1035                 } else {
1036                     if( errors == 0 ) {
1037                         proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
1038                                                    0, 3, raw_hdr,
1039                                                    "Raw value: 0x%06x (correct)", raw_hdr );
1040                     } else {
1041                         proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
1042                                                    0, 3, raw_hdr,
1043                                                    "Raw value: 0x%06x (errors are 0x%06x)", raw_hdr, errors );
1044                     }
1045                     item = proto_tree_add_uint(hdr_tree,hf_h223_mux_correctedhdr,tvb,0,3,
1046                                                correct_hdr);
1047                     PROTO_ITEM_SET_GENERATED(item);
1048                     proto_tree_add_uint(hdr_tree,hf_h223_mux_mc,tvb,0,1,mc);
1049                     proto_tree_add_uint(hdr_tree,hf_h223_mux_mpl,tvb,0,2,mpl);
1050                 }
1051                 break;
1052
1053             case 3:
1054                 /* XXX not implemented */
1055             default:
1056                 DISSECTOR_ASSERT_NOT_REACHED();
1057         }
1058     }
1059
1060     if(mpl > 0) {
1061         pdu_tvb = tvb_new_subset(tvb, offset, len, mpl);
1062         if(errors != -1) {
1063             dissect_mux_payload(pdu_tvb,pinfo,pkt_offset+offset,pdu_tree,call_info,mc,end_of_mux_sdu);
1064         } else {
1065             call_dissector(data_handle,pdu_tvb,pinfo,pdu_tree);
1066         }
1067         offset += mpl;
1068     }
1069
1070     /* any extra data in the PDU, beyond that indictated by the mpl, is
1071        dissected as data. */
1072     len -= mpl;
1073     if( len > 0 ) {
1074         tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, len, len);
1075         proto_tree *vc_tree = NULL;
1076
1077         if( pdu_tree ) {
1078             proto_item *vc_item = proto_tree_add_item(pdu_tree, hf_h223_mux_extra, next_tvb, 0, len, FALSE);
1079             vc_tree = proto_item_add_subtree(vc_item, ett_h223_mux_deact);
1080         }
1081         call_dissector(data_handle,next_tvb,pinfo,vc_tree);
1082
1083         offset += len;
1084     }
1085
1086     /* add the closing HDLC flag */
1087     if( pdu_tree )
1088         proto_tree_add_item(pdu_tree,hf_h223_mux_hdlc2,tvb,offset,2,FALSE);
1089 }
1090
1091
1092 /************************************************************************************
1093  *
1094  * MUX-PDU delineation and defragmentation
1095  */
1096
1097 /* attempt to parse the header of a mux pdu */
1098 static gboolean
1099 attempt_mux_level0_header_parse(guint32 nbytes _U_, guint32 hdr _U_, guint32 *minlen _U_)
1100 {
1101     /* level 0 isn't byte-aligned, so is a complete pain to implement */
1102     DISSECTOR_ASSERT_NOT_REACHED();
1103     return FALSE;
1104 }
1105
1106 static gboolean
1107 attempt_mux_level1_header_parse(guint32 nbytes, guint32 hdr, guint32 *minlen)
1108 {
1109     /* this is untested */
1110     DISSECTOR_ASSERT_NOT_REACHED();
1111
1112     if(nbytes < 2)
1113         return FALSE;
1114
1115     hdr &= 0xffff;
1116     /* don't interpret a repeated hdlc as a header */
1117     if(hdr == 0xE14D)
1118         return FALSE;
1119
1120     /* + 1 byte of header and 2 bytes of closing HDLC */
1121     *minlen = (guint8)((hdr >> 12) & 0xff) + 3;
1122     return TRUE;
1123 }
1124
1125 static gboolean
1126 attempt_mux_level2_3_header_parse(guint32 nbytes, guint32 hdr, guint32 *minlen)
1127 {
1128     gint32 errors;
1129
1130     if(nbytes < 3)
1131         return FALSE;
1132
1133     /* + 3 bytes of header and 2 bytes of closing HDLC */
1134     *minlen = 5;
1135
1136     /* bah, we get the header in the wrong order */
1137     hdr =
1138         ((hdr & 0xFF0000) >> 16) |
1139         (hdr & 0x00FF00) |
1140         ((hdr & 0x0000FF) << 16);
1141
1142     errors = golay_errors(hdr);
1143     if(errors != -1) {
1144         hdr ^= errors;
1145         *minlen += ((hdr >> 4) & 0xff);
1146     }
1147
1148     return TRUE;
1149 }
1150
1151 static gboolean (* const attempt_mux_header_parse[])(guint32 nbytes, guint32 header_buf, guint32 *minlen) = {
1152     attempt_mux_level0_header_parse,
1153     attempt_mux_level1_header_parse,
1154     attempt_mux_level2_3_header_parse,
1155     attempt_mux_level2_3_header_parse
1156 };
1157
1158 static gboolean
1159 h223_mux_check_hdlc(int h223_level, guint32 nbytes, guint32 tail_buf)
1160 {
1161     guint32 masked;
1162
1163     switch(h223_level) {
1164         case 0:
1165             /* level 0 isn't byte-aligned, so is a complete pain to implement */
1166             DISSECTOR_ASSERT_NOT_REACHED();
1167             return FALSE;
1168
1169         case 1:
1170             masked = tail_buf & 0xffff;
1171             return nbytes >= 2 && masked == 0xE14D;
1172
1173         case 2: case 3:
1174             masked = tail_buf & 0xffff;
1175             return nbytes >= 2 && (masked == 0xE14D || masked == (0xE14D ^ 0xFFFF));
1176
1177         default:
1178             DISSECTOR_ASSERT_NOT_REACHED();
1179             return FALSE;
1180     }
1181 }
1182
1183 /* read a pdu (or the start of a pdu) from the tvb, and dissect it
1184  *
1185  * returns the number of bytes processed, or the negative of the number of
1186  * extra bytes needed, or zero if we don't know yet
1187  */
1188
1189 static gint
1190 dissect_mux_pdu_fragment( tvbuff_t *tvb, guint32 start_offset,
1191                           packet_info *pinfo, proto_tree *h223_tree,
1192                           h223_call_info *call_info)
1193 {
1194     tvbuff_t *volatile next_tvb;
1195     volatile guint32 offset = start_offset;
1196     gboolean more_frags = TRUE;
1197
1198     gboolean header_parsed = FALSE;
1199     guint32 header_buf = 0, tail_buf = 0;
1200     guint32 pdu_minlen = 0;
1201     void *pd_save;
1202
1203
1204 #ifdef DEBUG_H223_FRAGMENTATION
1205     g_debug("%d: dissecting H.223 PDU, start_offset %u, %u bytes left",
1206             pinfo->fd->num,start_offset, tvb_reported_length_remaining( tvb, start_offset ));
1207 #endif
1208
1209     while( more_frags && offset < tvb_reported_length( tvb )) {
1210         guint8 byte = tvb_get_guint8(tvb, offset++);
1211
1212         /* read a byte into the header buf, if necessary */
1213         if((offset-start_offset) <= 4) {
1214             header_buf <<= 8;
1215             header_buf |= byte;
1216         }
1217
1218         /* read the byte into the tail buf */
1219         tail_buf <<= 8;
1220         tail_buf |= byte;
1221
1222         /* if we haven't parsed the header yet, attempt to do so now */
1223         if(!header_parsed)
1224             /* this sets current_pdu_header parsed if current_pdu_read == 3 */
1225             header_parsed = (attempt_mux_header_parse[call_info->h223_level])
1226                 (offset-start_offset,header_buf,&pdu_minlen);
1227
1228         /* if we have successfully parsed the header, we have sufficient data,
1229          * and we have found the closing hdlc, we are done here */
1230         if(header_parsed && (offset-start_offset) >= pdu_minlen) {
1231             if(h223_mux_check_hdlc(call_info->h223_level,offset-start_offset,tail_buf)) {
1232                 more_frags = FALSE;
1233             }
1234         }
1235     }
1236
1237     if( more_frags ) {
1238         if(pdu_minlen <= (offset-start_offset)) {
1239             /* we haven't found the closing hdlc yet, but we don't know how
1240              * much more we need */
1241 #ifdef DEBUG_H223_FRAGMENTATION
1242             g_debug("\tBailing, requesting more bytes");
1243 #endif
1244             return 0;
1245         } else {
1246             guint32 needed = pdu_minlen-(offset-start_offset);
1247 #ifdef DEBUG_H223_FRAGMENTATION
1248             g_debug("\tBailing, requesting %i-%i=%u more bytes", pdu_minlen,(offset-start_offset),needed);
1249 #endif
1250             return - (gint) needed;
1251         }
1252     }
1253
1254     /* create a tvb for the fragment */
1255     next_tvb = tvb_new_subset(tvb, start_offset, offset-start_offset,
1256                               offset-start_offset);
1257
1258
1259     /* we catch boundserrors on the pdu so that errors on an
1260      * individual pdu don't screw up the whole of the rest of the
1261      * stream */
1262     pd_save = pinfo->private_data;
1263     TRY {
1264         dissect_mux_pdu( next_tvb, pinfo, start_offset, h223_tree, call_info);
1265     }
1266
1267     CATCH2(BoundsError,ReportedBoundsError) {
1268         /*  Restore the private_data structure in case one of the
1269          *  called dissectors modified it (and, due to the exception,
1270          *  was unable to restore it).
1271          */
1272         pinfo->private_data = pd_save;
1273
1274         col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]");
1275         proto_tree_add_protocol_format(h223_tree, proto_malformed,
1276                                        tvb, 0, 0, "[Malformed Packet: %s]",
1277                                        pinfo->current_proto);
1278     }
1279
1280     ENDTRY;
1281
1282     return (offset-start_offset);
1283 }
1284
1285 /************************************************************************************
1286  *
1287  * main dissector entry points
1288  */
1289
1290 /* dissects PDUs from the tvb
1291  *
1292  * Updates desegment_offset and desegment_len if the end of the data didn't
1293  * line up with the end of a pdu.
1294  */
1295 static void
1296 dissect_h223 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1297 {
1298     proto_tree *h223_tree = NULL;
1299     proto_item *h223_item = NULL;
1300     h223_call_info *call_info = NULL;
1301     guint32 offset = 0;
1302
1303     /* set up the protocol and info fields in the summary pane */
1304     col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_H223);
1305
1306     col_clear(pinfo->cinfo, COL_INFO);
1307
1308     /* find or create the call_info for this call */
1309     call_info = find_or_create_call_info(pinfo);
1310
1311     /* add the 'h223' tree to the main tree */
1312     if (tree) {
1313         h223_item = proto_tree_add_item (tree, proto_h223, tvb, 0, -1, FALSE);
1314         h223_tree = proto_item_add_subtree (h223_item, ett_h223);
1315     }
1316
1317     while( offset < tvb_reported_length( tvb )) {
1318         int res = dissect_mux_pdu_fragment( tvb, offset, pinfo,
1319                                             h223_tree, call_info);
1320         if(res <= 0) {
1321             /* the end of the tvb held the start of a PDU */
1322             pinfo->desegment_offset = offset;
1323
1324             /* if res != 0, we actually know how much more data we need for a
1325              * PDU.
1326              *
1327              * However, if we return that, it means that we get called twice
1328              * for the next packet; this makes it hard to tell how far throught
1329              * the stream we are and we have to start messing about with
1330              * getting the seqno from the superdissector's private data. So we
1331              * don't do that.
1332              *
1333              * pinfo->desegment_len = (res == 0 ? DESEGMENT_ONE_MORE_SEGMENT : -res);
1334              */
1335             pinfo -> desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
1336
1337             if(h223_item) {
1338                 /* shrink the h223 protocol item such that it only includes the
1339                  * bits we dissected */
1340                 proto_item_set_len(h223_item,offset);
1341             }
1342
1343             if(offset == 0) {
1344                 col_set_str(pinfo->cinfo, COL_INFO, "(No complete PDUs)");
1345             }
1346             return;
1347         }
1348         offset += res;
1349     }
1350 }
1351
1352 /* H.223 specifies that the least-significant bit is transmitted first;
1353  * however this is at odds with IAX which transmits bytes with the
1354  * first-received bit as the MSB.
1355  *
1356  * This dissector swaps the ordering of the bits in each byte before using the
1357  * normal entry point.
1358  */
1359 static void
1360 dissect_h223_bitswapped (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1361 {
1362     tvbuff_t *reversed_tvb;
1363     guint8 *datax;
1364     guint len;
1365     guint i;
1366
1367     len = tvb_length(tvb);
1368     datax = g_malloc(len);
1369     for( i=0; i<len; i++)
1370         datax[i]=BIT_SWAP(tvb_get_guint8(tvb,i));
1371
1372     /*
1373      * Add the reversed tvbuff to the list of tvbuffs to which
1374      * the tvbuff we were handed refers, so it'll get
1375      * cleaned up when that tvbuff is cleaned up.
1376      */
1377     reversed_tvb = tvb_new_child_real_data(tvb, datax,len,tvb_reported_length(tvb));
1378
1379     /* Add a freer */
1380     tvb_set_free_cb(reversed_tvb, g_free);
1381
1382     /* Add the reversed data to the data source list. */
1383     add_new_data_source(pinfo, reversed_tvb, "Bit-swapped H.223 frame" );
1384
1385     dissect_h223(reversed_tvb,pinfo,tree);
1386 }
1387
1388 /******************************************************************************/
1389
1390 static void
1391 h223_init_protocol (void)
1392 {
1393     circuit_chain_init();
1394 }
1395
1396
1397 void proto_register_h223 (void)
1398 {
1399     /* A header field is something you can search/filter on.
1400      *
1401      * We create a structure to register our fields. It consists of an
1402      * array of hf_register_info structures, each of which are of the format
1403      * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1404      */
1405
1406     static hf_register_info hf[] = {
1407         { &hf_h223_non_h223_data,
1408           { "Non-H.223 data", "h223.non-h223", FT_NONE, BASE_NONE, NULL, 0x0,
1409             "Initial data in stream, not a PDU", HFILL }},
1410
1411         { &hf_h223_mux_stuffing_pdu,
1412           { "H.223 stuffing PDU", "h223.mux.stuffing", FT_NONE, BASE_NONE, NULL, 0x0,
1413             "Empty PDU used for stuffing when no data available", HFILL }},
1414
1415         { &hf_h223_mux_pdu,
1416           { "H.223 MUX-PDU", "h223.mux", FT_NONE, BASE_NONE, NULL, 0x0,
1417             NULL, HFILL }},
1418
1419         { &hf_h223_mux_header,
1420           { "Header", "h223.mux.header", FT_NONE, BASE_NONE, NULL, 0x0,
1421             "H.223 MUX header", HFILL }},
1422
1423         { &hf_h223_mux_rawhdr,
1424           { "Raw value", "h223.mux.rawhdr", FT_UINT24, BASE_HEX, NULL, 0x0,
1425             "Raw header bytes", HFILL }},
1426
1427         { &hf_h223_mux_correctedhdr,
1428           { "Corrected value", "h223.mux.correctedhdr", FT_UINT24, BASE_HEX, NULL, 0x0,
1429             "Corrected header bytes", HFILL }},
1430
1431         { &hf_h223_mux_mc,
1432           { "Multiplex Code", "h223.mux.mc", FT_UINT8, BASE_DEC, NULL, 0x0,
1433             "H.223 MUX multiplex code", HFILL }},
1434
1435         { &hf_h223_mux_mpl,
1436           { "Multiplex Payload Length", "h223.mux.mpl", FT_UINT8, BASE_DEC, NULL, 0x0,
1437             "H.223 MUX multiplex Payload Length", HFILL }},
1438
1439         { &hf_h223_mux_deact,
1440           { "Deactivated multiplex table entry", "h223.mux.deactivated", FT_NONE, BASE_NONE, NULL, 0x0,
1441             "mpl refers to an entry in the multiplex table which is not active", HFILL }},
1442
1443         { &hf_h223_mux_vc,
1444           { "H.223 virtual circuit", "h223.mux.vc", FT_UINT16, BASE_DEC, NULL, 0x0,
1445             NULL, HFILL }},
1446
1447         { &hf_h223_mux_extra,
1448           { "Extraneous data", "h223.mux.extra", FT_NONE, BASE_NONE, NULL, 0x0,
1449             "data beyond mpl", HFILL }},
1450
1451         { &hf_h223_mux_hdlc2,
1452           { "HDLC flag", "h223.mux.hdlc", FT_UINT16, BASE_HEX, NULL, 0x0,
1453             "framing flag", HFILL }},
1454
1455         /* fields for h.223-mux fragments */
1456         { &hf_h223_mux_fragment_overlap,
1457           { "Fragment overlap", "h223.mux.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1458             "Fragment overlaps with other fragments", HFILL }},
1459
1460         { &hf_h223_mux_fragment_overlap_conflict,
1461           { "Conflicting data in fragment overlap",     "h223.mux.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1462             "Overlapping fragments contained conflicting data", HFILL }},
1463
1464         { &hf_h223_mux_fragment_multiple_tails,
1465           { "Multiple tail fragments found",    "h223.mux.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1466             "Several tails were found when defragmenting the packet", HFILL }},
1467
1468         { &hf_h223_mux_fragment_too_long_fragment,
1469           { "Fragment too long",        "h223.mux.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1470             "Fragment contained data past end of packet", HFILL }},
1471
1472         { &hf_h223_mux_fragment_error,
1473           { "Defragmentation error", "h223.mux.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1474             "Defragmentation error due to illegal fragments", HFILL }},
1475
1476         { &hf_h223_mux_fragment_count,
1477           { "Fragment count", "h223.mux.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
1478             NULL, HFILL }},
1479
1480         { &hf_h223_mux_fragment,
1481           { "H.223 MUX-PDU Fragment", "h223.mux.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1482             NULL, HFILL }},
1483
1484         { &hf_h223_mux_fragments,
1485           { "H.223 MUX-PDU Fragments", "h223.mux.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
1486             NULL, HFILL }},
1487
1488         { &hf_h223_mux_reassembled_in,
1489           { "MUX-PDU fragment, reassembled in frame", "h223.mux.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1490             "This H.223 MUX-PDU packet is reassembled in this frame", HFILL }},
1491
1492         { &hf_h223_mux_reassembled_length,
1493           { "Reassembled H.223 MUX-PDU length", "h223.mux.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
1494             "The total length of the reassembled payload", HFILL }},
1495
1496         /* fields for h.223-al fragments */
1497         { &hf_h223_al_fragment_overlap,
1498           { "Fragment overlap", "h223.al.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1499             "Fragment overlaps with other fragments", HFILL }},
1500
1501         { &hf_h223_al_fragment_overlap_conflict,
1502           { "Conflicting data in fragment overlap",     "h223.al.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1503             "Overlapping fragments contained conflicting data", HFILL }},
1504
1505         { &hf_h223_al_fragment_multiple_tails,
1506           { "Multiple tail fragments found",    "h223.al.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1507             "Several tails were found when defragmenting the packet", HFILL }},
1508
1509         { &hf_h223_al_fragment_too_long_fragment,
1510           { "Fragment too long",        "h223.al.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1511             "Fragment contained data past end of packet", HFILL }},
1512
1513         { &hf_h223_al_fragment_error,
1514           { "Defragmentation error", "h223.al.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1515             "Defragmentation error due to illegal fragments", HFILL }},
1516
1517         { &hf_h223_al_fragment_count,
1518           { "Fragment count", "h223.al.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
1519             NULL, HFILL }},
1520
1521         { &hf_h223_al_fragment,
1522           { "H.223 AL-PDU Fragment", "h223.al.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1523             NULL, HFILL }},
1524
1525         { &hf_h223_al_fragments,
1526           { "H.223 AL-PDU Fragments", "h223.al.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
1527             NULL, HFILL }},
1528
1529         { &hf_h223_al_reassembled_in,
1530           { "AL-PDU fragment, reassembled in frame", "h223.al.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1531             "This H.223 AL-PDU packet is reassembled in this frame", HFILL }},
1532
1533         { &hf_h223_al_reassembled_length,
1534           { "Reassembled H.223 AL-PDU length", "h223.al.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
1535             "The total length of the reassembled payload", HFILL }},
1536
1537         /* h223-als */
1538
1539         { &hf_h223_al1,
1540           { "H.223 AL1", "h223.al1", FT_NONE, BASE_NONE, NULL, 0x0,
1541             "H.223 AL-PDU using AL1", HFILL }},
1542
1543         { &hf_h223_al1_framed,
1544           { "H.223 AL1 framing", "h223.al1.framed", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1545             NULL, HFILL }},
1546
1547         { &hf_h223_al2,
1548           { "H.223 AL2", "h223.al2", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1549             "H.223 AL-PDU using AL2", HFILL }},
1550
1551         { &hf_h223_al2_sequenced,
1552           { "H.223 sequenced AL2", "h223.sequenced_al2", FT_NONE, BASE_NONE, NULL, 0x0,
1553             "H.223 AL-PDU using AL2 with sequence numbers", HFILL }},
1554
1555         { &hf_h223_al2_unsequenced,
1556           { "H.223 unsequenced AL2", "h223.unsequenced_al2", FT_NONE, BASE_NONE, NULL, 0x0,
1557             "H.223 AL-PDU using AL2 without sequence numbers", HFILL }},
1558
1559         { &hf_h223_al2_seqno,
1560           { "Sequence Number", "h223.al2.seqno", FT_UINT8, BASE_DEC, NULL, 0x0,
1561             "H.223 AL2 sequence number", HFILL }},
1562
1563         { &hf_h223_al2_crc,
1564           { "CRC", "h223.al2.crc", FT_UINT8, BASE_HEX, NULL, 0x0,
1565             NULL, HFILL }},
1566
1567         { &hf_h223_al2_crc_bad,
1568           { "Bad CRC","h223.al2.crc_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1569             NULL, HFILL }},
1570
1571         { &hf_h223_al_payload,
1572           { "H.223 AL Payload", "h223.al.payload", FT_NONE, BASE_NONE, NULL, 0x0,
1573             "H.223 AL-PDU Payload", HFILL }},
1574
1575     };
1576
1577     static gint *ett[] = {
1578         &ett_h223,
1579         &ett_h223_non_h223_data,
1580         &ett_h223_mux_stuffing_pdu,
1581         &ett_h223_mux_pdu,
1582         &ett_h223_mux_header,
1583         &ett_h223_mux_deact,
1584         &ett_h223_mux_vc,
1585         &ett_h223_mux_extra,
1586         &ett_h223_mux_fragments,
1587         &ett_h223_mux_fragment,
1588         &ett_h223_al_fragments,
1589         &ett_h223_al_fragment,
1590         &ett_h223_al1,
1591         &ett_h223_al2,
1592         &ett_h223_al_payload
1593     };
1594
1595     proto_h223 =
1596         proto_register_protocol ("ITU-T Recommendation H.223", "H.223", "h223");
1597
1598     proto_register_field_array (proto_h223, hf, array_length (hf));
1599     proto_register_subtree_array (ett, array_length (ett));
1600     register_dissector("h223", dissect_h223, proto_h223);
1601     register_dissector("h223_bitswapped", dissect_h223_bitswapped, proto_h223);
1602
1603     /* register our init routine to be called at the start of a capture,
1604        to clear out our hash tables etc */
1605     register_init_routine(&h223_init_protocol);
1606
1607     h245_set_h223_set_mc_handle( &h223_set_mc );
1608     h245_set_h223_add_lc_handle( &h223_add_lc );
1609 }
1610
1611 void proto_reg_handoff_h223(void)
1612 {
1613     dissector_handle_t h223_bitswapped = find_dissector("h223_bitswapped");
1614     dissector_handle_t h223 = find_dissector("h223");
1615     data_handle = find_dissector("data");
1616     srp_handle = find_dissector("srp");
1617
1618     dissector_add_handle("tcp.port", h223);
1619     dissector_add_handle("tcp.port", h223_bitswapped);
1620     dissector_add_string("rtp_dyn_payload_type","CLEARMODE", h223_bitswapped);
1621     dissector_add_uint("iax2.dataformat", AST_DATAFORMAT_H223_H245, h223_bitswapped);
1622 }
1623
1624 /*
1625  * Editor modelines
1626  *
1627  * Local Variables:
1628  * c-basic-offset: 4
1629  * tab-width: 8
1630  * indent-tabs-mode: nil
1631  * End:
1632  *
1633  * ex: set shiftwidth=4 tabstop=8 expandtab:
1634  * :indentSize=4:tabSize=8:noTabs=true:
1635  */