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