Ethereal-dev: [Ethereal-dev] New dissectors: H.223 and friends
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Jeff Snyder <jeff@xxxxxxxxxxxxx>
Date: Fri, 30 Sep 2005 16:15:14 +0100
Hi,
I've attached a set of patches (against r16051) that implement dissection of
the ITU-T Recommendation H.223, aswell as several associated protocols.
These have been developed by myself and Richard van der Hoff at MX Telecom.
We would be most greatful if someone could take a look at them and hopefully
check them into the svn repository.
Could any replies to this mail please be sent to Richard van der Hoff
(richardv@xxxxxxxxxxxxx) instead of myself, as I will be leaving this company
at the end of today.
Finally, here's the list of patches:
00-iax.diff
Modifications to the IAX2 dissector so that it offers desegmentation to
subdissectors using the same API as TCP offers (pinfo->desegment_len etc)
01-amr.diff
Modifications to the AMR dissector to allow AMR IF2 data to be dissected via
call_dissector() from packet-h223.c. This patch also causes the AMR dissector
to append the frame type string to the info column, so that the info column
shows what protocols an H.223 frame contains.
02-h263-data.diff
Modifications to packet-h263.c to separate the dissection of h.263 RTP
encpasulation from the dissection of the actual h.263 data. The data
dissection functions are added as a second dissector. This data-only
dissector is used to dissect the video channel in our h.223 streams. As with
the AMR modification, this makes the H.263 dissector append to the info
column.
03-h245.diff
Extensions to the h.245 dissector to extract H.223 Multiplex Code and Logical
Channel setup messages, and pass this information to the H.223 dissector.
04-stream.diff
A simplified packet reassembly API built on top of fragment_add_seq_next for
reassembling fragments that are delivered in-order, where fragments are
identified by a framenum and an offset into that frame. Streams are attached
to a conversation or a circuit and are unidirectional.
05-plugin-framework.diff
Build system stuff for the h223 plugin: confiure.in, Changelog,
COPYING, Makefile.am, Makefile.nmake, moduleinfo.h, plugin.c,
plus neccesary modifications to plugins/Makefile.{am,nmake}
06-srp.dif
A dissector for H.324/SRP and H.324/CCSRL, which runs over H.223 and
encapsulates H.245 messages
07-golay.diff
Methods used for the checksumming/FEC of H.223 MUX-PDU headers
08-h223.diff
The actual H.223 disesctor
Thanks,
Jeff Snyder
--
Jeff Snyder <jeff@xxxxxxxxxxxxx>
http://www.mxtelecom.com
--- epan/dissectors/packet-h261.c 2005-09-29 16:07:12.651436752 +0100
+++ epan/dissectors/packet-h261.c 2005-09-29 17:30:14.803034584 +0100
@@ -2,7 +2,7 @@
*
* Routines for ITU-T Recommendation H.261 dissection
*
- * $Id: packet-h261.c,v 1.1.1.2 2005/09/29 13:18:54 jeff Exp $
+ * $Id: packet-h261.c,v 1.3 2005/09/29 15:51:25 jeff Exp $
*
* Copyright 2000, Philips Electronics N.V.
* Andreas Sikkema <h323@xxxxxxxxxx>
@@ -43,6 +43,7 @@
#include <string.h>
#include <epan/rtp_pt.h>
+#include "iax2_codec_type.h"
/* H.261 header fields */
static int proto_h261 = -1;
@@ -260,4 +261,5 @@
h261_handle = create_dissector_handle(dissect_h261, proto_h261);
dissector_add("rtp.pt", PT_H261, h261_handle);
+ dissector_add("iax2.codec", AST_FORMAT_H261, h261_handle);
}
--- epan/dissectors/packet-iax2.c 2005-09-29 16:07:12.816411672 +0100
+++ epan/dissectors/packet-iax2.c 2005-09-29 17:30:14.963010264 +0100
@@ -8,7 +8,7 @@
* IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
* http://www.asterisk.org for more information.
*
- * $Id: packet-iax2.c,v 1.1.1.4 2005/09/29 13:18:54 jeff Exp $
+ * $Id: packet-iax2.c,v 1.18 2005/09/29 15:51:25 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -39,6 +39,7 @@
#include <epan/packet.h>
#include <epan/to_str.h>
#include <epan/emem.h>
+#include <epan/reassemble.h>
#include "packet-iax2.h"
#include <epan/iax2_codec_type.h>
@@ -102,6 +103,16 @@
static int hf_iax2_cap_h261 = -1;
static int hf_iax2_cap_h263 = -1;
+static int hf_iax2_fragments = -1;
+static int hf_iax2_fragment = -1;
+static int hf_iax2_fragment_overlap = -1;
+static int hf_iax2_fragment_overlap_conflict = -1;
+static int hf_iax2_fragment_multiple_tails = -1;
+static int hf_iax2_fragment_too_long_fragment = -1;
+static int hf_iax2_fragment_error = -1;
+static int hf_iax2_reassembled_in = -1;
+
+
/* hf_iax2_ies is an array of header fields, one per potential Information
* Element. It's done this way (rather than having separate variables for each
* IE) to make the dissection of information elements clearer and more
@@ -128,6 +139,22 @@
static gint ett_iax2_ie = -1; /* single IE */
static gint ett_iax2_codecs = -1; /* capabilities IE */
static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
+static gint ett_iax2_fragment = -1;
+static gint ett_iax2_fragments = -1;
+
+static const fragment_items iax2_fragment_items = {
+ &ett_iax2_fragment,
+ &ett_iax2_fragments,
+ &hf_iax2_fragments,
+ &hf_iax2_fragment,
+ &hf_iax2_fragment_overlap,
+ &hf_iax2_fragment_overlap_conflict,
+ &hf_iax2_fragment_multiple_tails,
+ &hf_iax2_fragment_too_long_fragment,
+ &hf_iax2_fragment_error,
+ &hf_iax2_reassembled_in,
+ "iax2 fragments"
+};
static dissector_handle_t data_handle;
@@ -507,6 +534,11 @@
/* ************************************************************************* */
+typedef struct {
+ guint32 current_frag_id;
+ guint32 current_frag_bytes;
+ gboolean in_frag;
+} iax_call_dirdata;
/* This is our per-call data structure, which is attached to both the
* forward and reverse circuits.
@@ -538,6 +570,11 @@
/* the absolute start time of the call */
nstime_t start_time;
+
+ GHashTable *fid_table;
+ GHashTable *fragment_table;
+ GHashTable *totlen_table;
+ iax_call_dirdata dirdata[2];
} iax_call_data;
static void iax_init_hash( void )
@@ -820,6 +857,11 @@
call -> subdissector = NULL;
call -> start_time = pinfo->fd->abs_ts;
nstime_delta(&call -> start_time, &call -> start_time, &millisecond);
+ call -> fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ call -> totlen_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ call -> dirdata[0].in_frag=FALSE;
+ call -> dirdata[1].in_frag=FALSE;
+ fragment_table_init(&(call->fragment_table));
iax2_new_circuit_for_call(circuit_id,pinfo->fd->num,call,FALSE);
@@ -909,8 +951,8 @@
proto_tree * main_tree);
static void dissect_payload(tvbuff_t *tvb, guint32 offset,
- packet_info *pinfo, proto_tree *tree,
- guint32 ts, gboolean video,
+ packet_info *pinfo, proto_tree *iax2_tree,
+ proto_tree *tree, guint32 ts, gboolean video,
iax_packet_data *iax_packet);
@@ -1468,7 +1510,7 @@
}
}
- dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE,iax_packet);
+ dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE,iax_packet);
break;
case AST_FRAME_VIDEO:
@@ -1496,7 +1538,7 @@
col_append_fstr (pinfo->cinfo, COL_INFO, ", Mark" );
- dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
+ dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
break;
@@ -1586,7 +1628,7 @@
scallno, ts, rtp_marker?", Mark":"");
- dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
+ dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
/* next time we come to parse this packet, don't propogate the codec into the
* call_data */
@@ -1627,7 +1669,7 @@
/* XXX fix the timestamp logic */
- dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE, iax_packet);
+ dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
/* next time we come to parse this packet, don't propogate the codec into the
@@ -1637,14 +1679,179 @@
return offset;
}
+static void process_iax_pdu( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean video, iax_packet_data *iax_packet )
+{
+ guint32 codec = iax_packet -> codec;
+ iax_call_data *iax_call = iax_packet -> call_data;
+
+ if( !video && iax_call && iax_call->subdissector ) {
+ call_dissector(iax_call->subdissector, tvb, pinfo, tree);
+ return;
+ }
+
+ if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, tvb, pinfo, tree ))
+ return;
+
+ /* we don't know how to dissect our data: dissect it as data */
+ call_dissector(data_handle,tvb, pinfo, tree);
+}
+
+static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree,
+ proto_tree *tree, gboolean video, iax_packet_data *iax_packet )
+{
+
+ iax_call_data *iax_call = iax_packet -> call_data;
+ iax_call_dirdata *dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]);
+ gpointer unused,value;
+ guint32 fid,frag_len,offset,tot_len,frag_offset,nbytes,deseg_offset;
+ gint32 old_len;
+ fragment_data *fd_head;
+ tvbuff_t *next_tvb;
+ gboolean complete = FALSE, called_dissector = FALSE, must_desegment = FALSE;
+ proto_item *frag_tree_item, *iax_tree_item;
+
+ pinfo->desegment_offset = 0;
+ pinfo->desegment_len = 0;
+ deseg_offset = 0;
+
+ if((!pinfo->fd->flags.visited && dirdata->in_frag) ||
+ g_hash_table_lookup_extended(iax_call->fid_table,
+ GUINT_TO_POINTER(pinfo->fd->num), &unused, &value) ) {
+ /* then we are continuing an already-started pdu */
+ frag_len = tvb_reported_length( tvb );
+ offset = 0;
+ tot_len = GPOINTER_TO_UINT(g_hash_table_lookup(iax_call->totlen_table, GUINT_TO_POINTER(fid)));
+ if(!pinfo->fd->flags.visited) {
+ fid = dirdata->current_frag_id;
+ g_hash_table_insert( iax_call->fid_table, GUINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(fid) );
+ frag_offset = dirdata->current_frag_bytes;
+ complete = dirdata->current_frag_bytes > tot_len;
+ dirdata->current_frag_bytes += frag_len;
+ } else {
+ fid = GPOINTER_TO_UINT(value);
+ // these values are unused by fragmen_add if pinfo->fd->flags.visited
+ dirdata->current_frag_bytes = 0;
+ complete = FALSE;
+ }
+
+ /* fragment_add checks for already-added */
+ fd_head = fragment_add( tvb, offset, pinfo, fid,
+ iax_call->fragment_table,
+ frag_offset,
+ frag_len, !complete );
+
+ if(pinfo->fd->flags.visited)
+ complete = (fd_head && (pinfo->fd->num == fd_head->reassembled_in));
+
+ } else {
+ fid=offset=0; // initialise them here aswell to get rid of compiler warnings
+ process_iax_pdu(tvb,pinfo,tree,video,iax_packet);
+ called_dissector = TRUE;
+ if(pinfo->desegment_len) {
+ must_desegment = TRUE;
+ deseg_offset = pinfo->desegment_offset;
+ }
+ fd_head = NULL;
+ }
+
+ /* do we have a completely desegmented datagram? */
+ if (fd_head) {
+ /* we've got sometheing dissectable.. but is this the last segment of it? */
+ if(complete) { // this will always be true, since frags are added in seq.
+ next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen);
+ tvb_set_child_real_data_tvbuff(tvb, next_tvb); // I don't know what the f*** this line does, so don't ask
+ add_new_data_source(pinfo, next_tvb, "Reassembled IAX2");
+ process_iax_pdu(next_tvb,pinfo,tree,video,iax_packet);
+ called_dissector = TRUE;
+ old_len = (gint32)(tvb_reported_length(next_tvb) - tvb_reported_length_remaining(tvb,offset));
+ if( pinfo->desegment_len &&
+ pinfo->desegment_offset < old_len ) {
+ /*
+ * oops, it wasn't actually complete
+ */
+ fragment_set_partial_reassembly(pinfo, fid, iax_call->fragment_table);
+ g_hash_table_insert(iax_call->totlen_table, GUINT_TO_POINTER(fid),
+ GUINT_TO_POINTER(tvb_reported_length(next_tvb) + pinfo->desegment_len) );
+ } else {
+ nbytes = tvb_reported_length( tvb );
+ show_fragment_tree(fd_head, &iax2_fragment_items, tree, pinfo, next_tvb, &frag_tree_item);
+ iax_tree_item = proto_tree_get_parent( iax2_tree );
+ if(iax_tree_item)
+ iax_tree_item = proto_item_get_parent( iax_tree_item );
+ if( frag_tree_item && iax_tree_item )
+ proto_tree_move_item( tree, iax_tree_item, frag_tree_item );
+ dirdata->in_frag = FALSE;
+ if( pinfo->desegment_len ) {
+ /*
+ * .. but not everything
+ */
+ must_desegment = TRUE;
+
+ // make desegment_offset relative to the tvb
+ deseg_offset = pinfo->desegment_offset - (tvb_reported_length( next_tvb ) - tvb_reported_length( tvb ));
+ }
+ }
+ }
+ }
+
+ if(must_desegment) {
+ fid = pinfo->fd->num;
+ if(pinfo->fd->flags.visited) {
+ fd_head = fragment_get( pinfo, fid, iax_call->fragment_table );
+ } else {
+ frag_len = tvb_reported_length_remaining(tvb,deseg_offset);
+ dirdata->current_frag_id = fid;
+ dirdata->current_frag_bytes = frag_len;
+ dirdata->in_frag = TRUE;
+ offset = deseg_offset;
+ complete = FALSE;
+ fd_head = fragment_add(tvb, offset, pinfo, fid,
+ iax_call->fragment_table,
+ 0, frag_len, !complete );
+ g_hash_table_insert(iax_call->totlen_table, GUINT_TO_POINTER(fid),
+ GUINT_TO_POINTER( frag_len + pinfo->desegment_len) );
+ }
+ }
+
+ if( !called_dissector || pinfo->desegment_len != 0 ) {
+ if( fd_head != NULL && fd_head->reassembled_in != 0 &&
+ !(fd_head->flags & FD_PARTIAL_REASSEMBLY) ) {
+ iax_tree_item = proto_tree_add_uint( tree, hf_iax2_reassembled_in,
+ tvb, deseg_offset, tvb_reported_length_remaining(tvb,deseg_offset),
+ fd_head->reassembled_in);
+ PROTO_ITEM_SET_GENERATED(iax_tree_item);
+ } else if(fd_head && (fd_head->reassembled_in != 0 || (fd_head->flags & FD_PARTIAL_REASSEMBLY)) ) {
+ // this fragment is never reassembled
+ proto_tree_add_text( tree, tvb, deseg_offset, -1,
+ "IAX2 fragment, unfinished");
+ }
+
+ if( pinfo->desegment_offset == 0 ) {
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)){
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAX2");
+ }
+ if (check_col(pinfo->cinfo, COL_INFO)){
+ col_set_str(pinfo->cinfo, COL_INFO, "[IAX2 segment of a reassembled PDU]");
+ }
+ }
+ nbytes = tvb_reported_length_remaining( tvb, deseg_offset );
+ }
+
+ pinfo->can_desegment = 0;
+ pinfo->desegment_offset = 0;
+ pinfo->desegment_len = 0;
+}
+
static void dissect_payload(tvbuff_t *tvb, guint32 offset,
- packet_info *pinfo, proto_tree *tree,
- guint32 ts, gboolean video,
+ packet_info *pinfo, proto_tree *iax2_tree,
+ proto_tree *tree, guint32 ts, gboolean video,
iax_packet_data *iax_packet)
{
gboolean out_of_order = FALSE;
tvbuff_t *sub_tvb;
guint32 codec = iax_packet -> codec;
+ guint32 nbytes;
iax_call_data *iax_call = iax_packet -> call_data;
/* keep compiler quiet */
@@ -1674,17 +1881,12 @@
}
}
+ nbytes = tvb_reported_length(sub_tvb);
+ proto_tree_add_text( iax2_tree, sub_tvb, 0, -1,
+ "IAX2 payload (%u byte%s)", nbytes,
+ plurality( nbytes, "", "s" ));
/* pass the rest of the block to a subdissector */
- if( !video && iax_call && iax_call->subdissector ) {
- call_dissector(iax_call->subdissector,sub_tvb, pinfo, tree);
- return;
- }
-
- if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, sub_tvb, pinfo, tree ))
- return;
-
- /* we don't know how to dissect our data: dissect it as data */
- call_dissector(data_handle,sub_tvb, pinfo, tree);
+ desegment_iax( sub_tvb, pinfo, iax2_tree, tree, video, iax_packet );
}
/*
@@ -2158,7 +2360,45 @@
{&hf_iax2_cap_h263,
{"H.263 video", "iax2.cap.h263", FT_BOOLEAN, 32,
TFS(&supported_strings), AST_FORMAT_H263,
- "H.263 video", HFILL }}
+ "H.263 video", HFILL }},
+
+ /* reassembly stuff */
+ {&hf_iax2_fragments,
+ {"IAX2 Fragments", "iax2.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
+ "IAX2 Fragments", HFILL }},
+
+ {&hf_iax2_fragment,
+ {"IAX2 Fragment data", "iax2.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "IAX2 Fragment data", HFILL }},
+
+ {&hf_iax2_fragment_overlap,
+ {"Fragment overlap", "iax2.fragment.overlap", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
+
+ {&hf_iax2_fragment_overlap_conflict,
+ {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }},
+
+ {&hf_iax2_fragment_multiple_tails,
+ {"Multiple tail fragments found", "iax2.fragment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }},
+
+ {&hf_iax2_fragment_too_long_fragment,
+ {"Fragment too long", "iax2.fragment.toolongfragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }},
+
+ {&hf_iax2_fragment_error,
+ {"Defragmentation error", "iax2.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }},
+
+ {&hf_iax2_reassembled_in,
+ {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This IAX2 packet is reassembled in this frame", HFILL }}
};
static gint *ett[] = {
@@ -2167,7 +2407,9 @@
&ett_iax2_type,
&ett_iax2_ie,
&ett_iax2_codecs,
- &ett_iax2_ies_apparent_addr
+ &ett_iax2_ies_apparent_addr,
+ &ett_iax2_fragment,
+ &ett_iax2_fragments
};
/* initialise the hf_iax2_ies[] array to -1 */
@@ -2205,4 +2447,7 @@
* Local Variables:
* c-basic-offset: 2
* End:
+ *
+ * .. And for vim:
+ * vim:set ts=8 sts=2 sw=2 noet:
*/
--- epan/Makefile.common 2005-09-29 16:07:07.439229128 +0100
+++ epan/Makefile.common 2005-09-29 17:30:10.987614616 +0100
@@ -3,7 +3,7 @@
# a) common to both files and
# b) portable between both files
#
-# $Id: Makefile.common,v 1.1.1.8 2005/09/29 13:18:52 jeff Exp $
+# $Id: Makefile.common,v 1.9 2005/09/29 15:51:24 jeff Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -76,6 +76,7 @@
stat_cmd_args.c \
stats_tree.c \
strutil.c \
+ stream.c \
t35.c \
tap.c \
timestamp.c \
@@ -165,6 +166,7 @@
stat_cmd_args.h \
stats_tree.h \
stats_tree_priv.h \
+ stream.h \
strutil.h \
t35.h \
tap.h \
--- epan/packet.c 2005-09-29 16:07:08.172117712 +0100
+++ epan/packet.c 2005-09-29 17:30:11.603520984 +0100
@@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
- * $Id: packet.c,v 1.1.1.7 2005/09/29 13:18:53 jeff Exp $
+ * $Id: packet.c,v 1.7 2005/09/29 15:51:24 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -54,6 +54,7 @@
#include "emem.h"
#include <epan/reassemble.h>
+#include <epan/stream.h>
static gint proto_malformed = -1;
static dissector_handle_t frame_handle = NULL;
@@ -146,6 +147,9 @@
may free up space for fragments, which they find by using the
data structures that "reassemble_init()" frees. */
reassemble_init();
+
+ /* Initialise the stream-handling tables */
+ stream_init();
}
void
--- epan/stream.c 1970-01-01 01:00:00.000000000 +0100
+++ epan/stream.c 2005-07-27 23:47:55.000000000 +0100
@@ -0,0 +1,533 @@
+/* stream.c
+ *
+ * Definititions for handling circuit-switched protocols
+ * which are handled as streams, and don't have lengths
+ * and IDs such as are required for reassemble.h
+ *
+ * $Id: stream.c,v 1.9 2005/07/27 22:47:55 richardv Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/reassemble.h>
+#include <epan/stream.h>
+#include <epan/tvbuff.h>
+
+/* number of streams to allocate memory for at once */
+#define MEMCHUNK_STREAM_COUNT 20
+
+/* ditto pdus */
+#define MEMCHUNK_PDU_COUNT 100
+
+/* ditto fragments */
+#define MEMCHUNK_FRAGMENT_COUNT 100
+
+
+typedef struct {
+ fragment_data *fd_head; /* the reassembled data, NULL
+ * until we add the last fragment */
+ guint32 pdu_number; /* Number of this PDU within the stream */
+
+ /* id of this pdu (globally unique) */
+ guint32 id;
+} stream_pdu_t;
+
+
+struct stream_pdu_fragment
+{
+ guint32 len; /* the length of this fragment */
+ stream_pdu_t *pdu;
+ gboolean final_fragment;
+};
+
+struct stream {
+ /* the key used to add this stream to stream_hash */
+ struct stream_key *key;
+
+ /* pdu to add the next fragment to, or NULL if we need to start
+ * a new PDU.
+ */
+ stream_pdu_t *current_pdu;
+
+ /* number of PDUs added to this stream so far */
+ guint32 pdu_counter;
+
+ /* the framenumber and offset of the last fragment added;
+ used for sanity-checking */
+ guint32 lastfrag_framenum;
+ guint32 lastfrag_offset;
+};
+
+
+/*****************************************************************************
+ *
+ * Stream hash
+ */
+
+/* key */
+typedef struct stream_key {
+ /* streams can be attached to circuits or conversations, and we note
+ that here */
+ gboolean is_circuit;
+ union {
+ const struct circuit *circuit;
+ const struct conversation *conv;
+ } circ;
+ int p2p_dir;
+} stream_key_t;
+
+
+/* hash func */
+guint stream_hash_func(gconstpointer k)
+{
+ const stream_key_t *key = (const stream_key_t *)k;
+
+ /* is_circuit is redundant to the circuit/conversation pointer */
+ return ((guint)key->circ.circuit) ^ key->p2p_dir;
+}
+
+/* compare func */
+gboolean stream_compare_func(gconstpointer a,
+ gconstpointer b)
+{
+ const stream_key_t *key1 = (const stream_key_t *)a;
+ const stream_key_t *key2 = (const stream_key_t *)b;
+ if( key1 -> p2p_dir != key2 -> p2p_dir ||
+ key1-> is_circuit != key2 -> is_circuit )
+ return FALSE;
+
+ if( key1 -> is_circuit )
+ return (key1 -> circ.circuit == key2 -> circ.circuit );
+ else
+ return (key1 -> circ.conv == key2 -> circ.conv );
+}
+
+/* value destroy func */
+void stream_value_destroy_func(gpointer v)
+{
+ stream_t *val = (stream_t *)v;
+
+ /* this is only called when the entire hash (and hence the entire
+ * "streams" GMemChunk is being freed, so there is no need to free
+ * v.
+ */
+}
+
+/* memory pools */
+static GMemChunk *stream_keys = NULL;
+static GMemChunk *streams = NULL;
+
+
+/* the hash table */
+static GHashTable *stream_hash;
+
+
+/* init/reset function, call from stream_init() */
+static void init_stream_hash( void ) {
+ if( stream_hash != NULL ) {
+ g_hash_table_destroy( stream_hash );
+ stream_hash = NULL;
+ }
+
+ if( stream_keys != NULL ) {
+ g_mem_chunk_destroy( stream_keys );
+ stream_keys = NULL;
+ }
+
+ if( streams != NULL ) {
+ g_mem_chunk_destroy( streams );
+ streams = NULL;
+ }
+
+ streams = g_mem_chunk_create(stream_t,
+ MEMCHUNK_STREAM_COUNT,
+ G_ALLOC_ONLY);
+
+ stream_keys = g_mem_chunk_create(stream_key_t,
+ MEMCHUNK_STREAM_COUNT,
+ G_ALLOC_ONLY);
+
+ stream_hash = g_hash_table_new_full(stream_hash_func,
+ stream_compare_func,
+ NULL,
+ stream_value_destroy_func);
+}
+
+
+/* lookup function, returns null if not found */
+static stream_t *stream_hash_lookup_circ( const struct circuit *circuit, int p2p_dir )
+{
+ stream_key_t key = {TRUE,{circuit}, p2p_dir};
+ return (stream_t *)g_hash_table_lookup(stream_hash, &key);
+}
+
+static stream_t *stream_hash_lookup_conv( const struct conversation *conv, int p2p_dir )
+{
+ stream_key_t key = {FALSE,{NULL}, p2p_dir};
+ key.circ.conv = conv;
+ return (stream_t *)g_hash_table_lookup(stream_hash, &key);
+}
+
+
+static stream_t *new_stream( stream_key_t *key )
+{
+ stream_t *val;
+
+ val = g_mem_chunk_alloc(streams);
+ val -> key = key;
+ val -> pdu_counter = 0;
+ val -> current_pdu = NULL;
+ val -> lastfrag_framenum = 0;
+ val -> lastfrag_offset = 0;
+ g_hash_table_insert(stream_hash, key, val);
+
+ return val;
+}
+
+
+/* insert function */
+static stream_t *stream_hash_insert_circ( const struct circuit *circuit, int p2p_dir )
+{
+ stream_key_t *key;
+
+ key = g_mem_chunk_alloc(stream_keys);
+ key->is_circuit = TRUE;
+ key->circ.circuit = circuit;
+ key->p2p_dir = p2p_dir;
+
+ return new_stream(key);
+}
+
+static stream_t *stream_hash_insert_conv( const struct conversation *conv, int p2p_dir )
+{
+ stream_key_t *key;
+
+ key = g_mem_chunk_alloc(stream_keys);
+ key->is_circuit = FALSE;
+ key->circ.conv = conv;
+ key->p2p_dir = p2p_dir;
+
+ return new_stream(key);
+}
+
+
+/******************************************************************************
+ *
+ * PDU data
+ */
+static GMemChunk *pdus = NULL;
+
+/* pdu counter, for generating unique pdu ids */
+static guint32 pdu_counter;
+
+
+static void stream_init_pdu_data(void)
+{
+ if( pdus != NULL ) {
+ g_mem_chunk_destroy( pdus );
+ pdus = NULL;
+ }
+
+ pdus = g_mem_chunk_create(stream_pdu_t,
+ MEMCHUNK_PDU_COUNT,
+ G_ALLOC_ONLY);
+ pdu_counter = 0;
+}
+
+
+/* new pdu in this stream */
+static stream_pdu_t *stream_new_pdu(stream_t *stream)
+{
+ stream_pdu_t *pdu;
+ pdu = g_mem_chunk_alloc(pdus);
+ pdu -> fd_head = NULL;
+ pdu -> pdu_number = stream -> pdu_counter++;
+ pdu -> id = pdu_counter++;
+ return pdu;
+}
+
+/*****************************************************************************
+ *
+ * fragment hash
+ */
+
+/* key */
+typedef struct fragment_key {
+ const stream_t *stream;
+ guint32 framenum;
+ guint32 offset;
+} fragment_key_t;
+
+
+/* hash func */
+guint fragment_hash_func(gconstpointer k)
+{
+ const fragment_key_t *key = (const fragment_key_t *)k;
+ return ((guint)key->stream) + ((guint)key -> framenum) + ((guint)key->offset);
+}
+
+/* compare func */
+gboolean fragment_compare_func(gconstpointer a,
+ gconstpointer b)
+{
+ const fragment_key_t *key1 = (const fragment_key_t *)a;
+ const fragment_key_t *key2 = (const fragment_key_t *)b;
+ return (key1 -> stream == key2 -> stream &&
+ key1 -> framenum == key2 -> framenum &&
+ key1 -> offset == key2 -> offset );
+}
+
+/* memory pools */
+static GMemChunk *fragment_keys = NULL;
+static GMemChunk *fragment_vals = NULL;
+
+/* the hash table */
+static GHashTable *fragment_hash;
+
+
+/* init/reset function, call from stream_init() */
+static void init_fragment_hash( void ) {
+ if( fragment_hash != NULL ) {
+ g_hash_table_destroy( fragment_hash );
+ fragment_hash = NULL;
+ }
+
+ if( fragment_vals != NULL ) {
+ g_mem_chunk_destroy( fragment_vals );
+ fragment_vals = NULL;
+ }
+
+ if( fragment_keys != NULL ) {
+ g_mem_chunk_destroy( fragment_keys );
+ fragment_keys = NULL;
+ }
+
+ fragment_keys = g_mem_chunk_create(fragment_key_t,
+ MEMCHUNK_FRAGMENT_COUNT,
+ G_ALLOC_ONLY);
+
+ fragment_vals = g_mem_chunk_create(stream_pdu_fragment_t,
+ MEMCHUNK_FRAGMENT_COUNT,
+ G_ALLOC_ONLY);
+
+ fragment_hash = g_hash_table_new(fragment_hash_func,
+ fragment_compare_func);
+}
+
+
+/* lookup function, returns null if not found */
+static stream_pdu_fragment_t *fragment_hash_lookup( const stream_t *stream, guint32 framenum, guint32 offset )
+{
+ fragment_key_t key = {stream, framenum, offset};
+ stream_pdu_fragment_t *val = g_hash_table_lookup(fragment_hash, &key);
+
+ return val;
+}
+
+
+/* insert function */
+static stream_pdu_fragment_t *fragment_hash_insert( const stream_t *stream, guint32 framenum, guint32 offset,
+ guint32 length)
+{
+ fragment_key_t *key;
+ stream_pdu_fragment_t *val;
+
+ key = g_mem_chunk_alloc(fragment_keys);
+ key->stream = stream;
+ key->framenum = framenum;
+ key->offset = offset;
+
+ val = g_mem_chunk_alloc(fragment_vals);
+ val->len = length;
+ val->pdu = NULL;
+ val->final_fragment = FALSE;
+
+ g_hash_table_insert(fragment_hash, key, val);
+ return val;
+}
+
+/*****************************************************************************/
+
+/* fragmentation hash tables */
+static GHashTable *stream_fragment_table = NULL;
+static GHashTable *stream_reassembled_table = NULL;
+
+/* Initialise a new stream. Call this when you first identify a distinct
+ * stream. */
+stream_t *stream_new_circ ( const struct circuit *circuit, int p2p_dir )
+{
+ stream_t * stream;
+
+ /* we don't want to replace the previous data if we get called twice on the
+ same circuit, so do a lookup first */
+ stream = stream_hash_lookup_circ(circuit, p2p_dir);
+ g_assert( stream == NULL );
+
+ stream = stream_hash_insert_circ(circuit, p2p_dir);
+
+ return stream;
+}
+
+stream_t *stream_new_conv ( const struct conversation *conv, int p2p_dir )
+{
+ stream_t * stream;
+
+ /* we don't want to replace the previous data if we get called twice on the
+ same conversation, so do a lookup first */
+ stream = stream_hash_lookup_conv(conv, p2p_dir);
+ g_assert( stream == NULL );
+
+ stream = stream_hash_insert_conv(conv, p2p_dir);
+ return stream;
+}
+
+
+
+
+/* retrieve a previously-created stream.
+ *
+ * Returns null if no matching stream was found.
+ */
+stream_t *find_stream_circ ( const struct circuit *circuit, int p2p_dir )
+{
+ return stream_hash_lookup_circ(circuit,p2p_dir);
+}
+stream_t *find_stream_conv ( const struct conversation *conv, int p2p_dir )
+{
+ return stream_hash_lookup_conv(conv,p2p_dir);
+}
+
+
+/* initialise the stream routines */
+void stream_init( void )
+{
+ init_stream_hash();
+ init_fragment_hash();
+ stream_init_pdu_data();
+
+ fragment_table_init(&stream_fragment_table);
+ reassembled_table_init(&stream_reassembled_table);
+}
+
+
+
+
+/*****************************************************************************/
+
+stream_pdu_fragment_t *stream_find_frag( stream_t *stream, guint32 framenum, guint32 offset )
+{
+ return fragment_hash_lookup( stream, framenum, offset );
+}
+
+stream_pdu_fragment_t *stream_add_frag( stream_t *stream, guint32 framenum, guint32 offset,
+ tvbuff_t *tvb, packet_info *pinfo, gboolean more_frags )
+{
+ fragment_data *fd_head;
+ stream_pdu_t *pdu;
+ stream_pdu_fragment_t *frag_data;
+ guint8 *datacopy;
+
+ g_assert(stream);
+
+ /* check that this fragment is at the end of the stream */
+ g_assert( framenum > stream->lastfrag_framenum ||
+ (framenum == stream->lastfrag_framenum && offset > stream->lastfrag_offset));
+
+
+ pdu = stream->current_pdu;
+ if( pdu == NULL ) {
+ /* start a new pdu */
+ pdu = stream->current_pdu = stream_new_pdu(stream);
+ }
+
+ /* add it to the reassembly tables */
+ fd_head = fragment_add_seq_next(tvb, 0, pinfo, pdu->id,
+ stream_fragment_table, stream_reassembled_table,
+ tvb_reported_length(tvb), more_frags);
+ /* add it to our hash */
+ frag_data = fragment_hash_insert( stream, framenum, offset, tvb_reported_length(tvb));
+ frag_data -> pdu = pdu;
+
+ if( fd_head != NULL ) {
+ /* if this was the last fragment, update the pdu data.
+ */
+ pdu -> fd_head = fd_head;
+
+ /* start a new pdu next time */
+ stream->current_pdu = NULL;
+
+ frag_data -> final_fragment = TRUE;
+ }
+
+ /* stashing the framenum and offset permit future sanity checks */
+ stream -> lastfrag_framenum = framenum;
+ stream -> lastfrag_offset = offset;
+
+ return frag_data;
+}
+
+
+tvbuff_t *stream_process_reassembled(
+ tvbuff_t *tvb, int offset, packet_info *pinfo,
+ char *name, const stream_pdu_fragment_t *frag,
+ const struct _fragment_items *fit,
+ gboolean *update_col_infop, proto_tree *tree)
+{
+ stream_pdu_t *pdu;
+ g_assert(frag);
+ pdu = frag->pdu;
+
+ /* we handle non-terminal fragments ourselves, because
+ reassemble.c messes them up */
+ if(!frag->final_fragment) {
+ if (pdu->fd_head != NULL && fit->hf_reassembled_in != NULL) {
+ proto_tree_add_uint(tree,
+ *(fit->hf_reassembled_in), tvb,
+ 0, 0, pdu->fd_head->reassembled_in);
+ }
+ return NULL;
+ }
+
+ return process_reassembled_data(tvb, offset, pinfo, name, pdu->fd_head,
+ fit, update_col_infop, tree);
+}
+
+guint32 stream_get_frag_length( const stream_pdu_fragment_t *frag)
+{
+ g_assert( frag );
+ return frag->len;
+}
+
+fragment_data *stream_get_frag_data( const stream_pdu_fragment_t *frag)
+{
+ g_assert( frag );
+ return frag->pdu->fd_head;
+}
+
+guint32 stream_get_pdu_no( const stream_pdu_fragment_t *frag)
+{
+ g_assert( frag );
+ return frag->pdu->pdu_number;
+}
--- epan/stream.h 1970-01-01 01:00:00.000000000 +0100
+++ epan/stream.h 2005-07-27 23:47:55.000000000 +0100
@@ -0,0 +1,137 @@
+/* stream.h
+ *
+ * Definititions for handling circuit-switched protocols
+ * which are handled as streams, and don't have lengths
+ * and IDs such as are required for reassemble.h
+ *
+ * $Id: stream.h,v 1.10 2005/07/27 22:47:55 richardv Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef stream_h
+#define stream_h
+
+#include <epan/tvbuff.h>
+
+struct _fragment_items;
+
+/* A stream represents the concept of an arbitrary stream of data,
+ divided up into frames for transmission, where the frames have
+ little or no correspondence to the PDUs of the protocol being
+ streamed, and those PDUs are just delineated by a magic number.
+
+ For example, we stream H.223 over IAX2. IAX2 has no concept of
+ H.223 PDUs and just divides the H.223 stream into 160-byte
+ frames. H.223 PDUs are delineated by two-byte magic numbers (which
+ may, of course, straddle an IAX2 frame boundary).
+
+ Essentially we act as a wrapper to reassemble.h, by making up
+ PDU ids and keeping some additional data on fragments to allow the
+ PDUs to be defragmented again.
+*/
+
+
+/* A stream_t represents a stream. There might be one or two streams
+ in a circuit, depending on whether that circuit is mono- or bi-directional.
+*/
+typedef struct stream stream_t;
+
+/* Fragments in a PDU are represented using a stream_pdu_fragment_t,
+ and placed in a linked-list with other fragments in the PDU.
+
+ (They're also placed in a hash so we can find them again later)
+*/
+typedef struct stream_pdu_fragment stream_pdu_fragment_t;
+
+
+struct circuit;
+struct conversation;
+
+/* initialise a new stream. Call this when you first identify a distinct
+ * stream. The circit pointer is just used as a key to look up the stream. */
+stream_t *stream_new_circ ( const struct circuit *circuit, int p2p_dir );
+stream_t *stream_new_conv ( const struct conversation *conv, int p2p_dir );
+
+/* retrieve a previously-created stream.
+ *
+ * Returns null if no matching stream was found.
+ */
+stream_t *find_stream_circ ( const struct circuit *circuit, int p2p_dir );
+stream_t *find_stream_conv ( const struct conversation *conv, int p2p_dir );
+
+
+
+/* see if we've seen this fragment before.
+
+ The framenum and offset are just hash keys, so can be any values unique
+ to this frame, but the idea is that you use the number of the frame being
+ disassembled, and the byte-offset within that frame.
+*/
+stream_pdu_fragment_t *stream_find_frag( stream_t *stream, guint32 framenum, guint32 offset );
+
+/* add a new fragment to the fragment tables for the stream. The framenum and
+ * offset are keys allowing future access with stream_find_frag(), tvb is the
+ * fragment to be added, and pinfo is the information for the frame containing
+ * this fragment. more_frags should be set if this is the final fragment in the
+ * PDU.
+ *
+ * * the fragment must be later in the stream than any previous fragment
+ * (ie, framenum.offset must be greater than those passed on the previous
+ * call)
+ *
+ * This essentially means that you can only add fragments on the first pass
+ * through the stream.
+ */
+stream_pdu_fragment_t *stream_add_frag( stream_t *stream, guint32 framenum, guint32 offset,
+ tvbuff_t *tvb, packet_info *pinfo, gboolean more_frags );
+
+/* Get the length of a fragment previously found by stream_find_frag().
+ */
+guint32 stream_get_frag_length( const stream_pdu_fragment_t *frag);
+
+/* Get a handle on the top of the chain of fragment_datas underlying this PDU
+ * frag can be any fragment within a PDU, and it will always return the head of
+ * the chain
+ *
+ * Returns NULL until the last fragment is added.
+ */
+struct _fragment_data *stream_get_frag_data( const stream_pdu_fragment_t *frag);
+
+/*
+ * Process reassembled data; if this is the last fragment, put the fragment
+ * information into the protocol tree, and construct a tvbuff with the
+ * reassembled data, otherwise just put a "reassembled in" item into the
+ * protocol tree.
+ */
+tvbuff_t *stream_process_reassembled(
+ tvbuff_t *tvb, int offset, packet_info *pinfo,
+ char *name, const stream_pdu_fragment_t *frag,
+ const struct _fragment_items *fit,
+ gboolean *update_col_infop, proto_tree *tree);
+
+/* Get the PDU number. PDUs are numbered from zero within a stream.
+ * frag can be any fragment within a PDU.
+ */
+guint32 stream_get_pdu_no( const stream_pdu_fragment_t *frag);
+
+/* initialise the stream routines */
+void stream_init( void );
+
+#endif
--- epan/dissectors/packet-h263.c 2005-09-29 16:07:12.675433104 +0100
+++ epan/dissectors/packet-h263.c 2005-09-29 17:30:14.807033976 +0100
@@ -5,7 +5,7 @@
* Copyright 2003 Niklas Ögren <niklas.ogren@xxxxx>
* Seven Levels Consultants AB
*
- * $Id: packet-h263.c,v 1.1.1.3 2005/09/29 13:18:54 jeff Exp $
+ * $Id: packet-h263.c,v 1.3 2005/09/29 15:51:25 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -47,8 +47,11 @@
#include <epan/rtp_pt.h>
#include <epan/iax2_codec_type.h>
+static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
+
/* H.263 header fields */
static int proto_h263 = -1;
+static int proto_h263_data = -1;
/* Mode A header */
static int hf_h263_ftype = -1;
@@ -87,6 +90,7 @@
static int hf_h263_optional_advanced_prediction_mode = -1;
static int hf_h263_PB_frames_mode = -1;
static int hf_h263_data = -1;
+static int hf_h263_payload = -1;
/* Source format types */
#define SRCFORMAT_FORB 0 /* forbidden */
@@ -128,33 +132,30 @@
dissect_h263( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
proto_item *ti = NULL;
- proto_item *h263_payload_item = NULL;
proto_tree *h263_tree = NULL;
- proto_tree *h263_payload_tree = NULL;
unsigned int offset = 0;
unsigned int h263_version = 0;
- guint32 data;
- guint8 octet;
+ tvbuff_t *next_tvb;
h263_version = (tvb_get_guint8( tvb, offset ) & 0xc0 ) >> 6;
if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
- col_set_str( pinfo->cinfo, COL_PROTOCOL, "H.263" );
+ col_set_str( pinfo->cinfo, COL_PROTOCOL, "H.263 " );
}
if( h263_version == 0x00) {
if ( check_col( pinfo->cinfo, COL_INFO) ) {
- col_append_str( pinfo->cinfo, COL_INFO, " MODE A");
+ col_append_str( pinfo->cinfo, COL_INFO, "MODE A ");
}
}
else if( h263_version == 0x02) {
if ( check_col( pinfo->cinfo, COL_INFO) ) {
- col_append_str( pinfo->cinfo, COL_INFO, " MODE B");
+ col_append_str( pinfo->cinfo, COL_INFO, "MODE B ");
}
}
else if( h263_version == 0x03) {
if ( check_col( pinfo->cinfo, COL_INFO) ) {
- col_append_str( pinfo->cinfo, COL_INFO, " MODE C");
+ col_append_str( pinfo->cinfo, COL_INFO, "MODE C ");
}
}
@@ -272,14 +273,38 @@
} /* end not mode a */
/* The rest of the packet is the H.263 stream */
- h263_payload_item = proto_tree_add_text(h263_tree,tvb,offset,-1,"H263 Payload");
+ next_tvb = tvb_new_subset( tvb, offset, tvb_length(tvb) - offset, tvb_reported_length(tvb) - offset);
+ dissect_h263_data( next_tvb, pinfo, h263_tree );
+
+ }
+}
+
+
+static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+ guint offset = 0;
+ proto_item *h263_payload_item = NULL;
+ proto_tree *h263_payload_tree = NULL;
+ guint32 data;
+ guint8 octet;
+
+ if ( check_col( pinfo->cinfo, COL_INFO) ) {
+ col_append_str( pinfo->cinfo, COL_INFO, "H263 payload ");
+ }
+
+ if( tree ) {
+ h263_payload_item = proto_tree_add_item( tree, hf_h263_payload, tvb, offset, -1, FALSE );
h263_payload_tree = proto_item_add_subtree( h263_payload_item, ett_h263_payload );
+ }
- /* Check for PSC, PSC is a word of 22 bits. Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */
- data = tvb_get_ntohl(tvb, offset);
-
- if (( data & 0xffff8000) == 0x00008000 ) { /* PSC or Group of Block Start Code (GBSC) found */
- if (( data & 0xfffffc00) == 0x00008000 ) { /* PSC found */
+ /* Check for PSC, PSC is a word of 22 bits. Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */
+ data = tvb_get_ntohl(tvb, offset);
+
+ if (( data & 0xffff8000) == 0x00008000 ) { /* PSC or Group of Block Start Code (GBSC) found */
+ if (( data & 0xfffffc00) == 0x00008000 ) { /* PSC found */
+ if ( check_col( pinfo->cinfo, COL_INFO) )
+ col_append_str( pinfo->cinfo, COL_INFO, "(PSC) ");
+ if( tree ) {
proto_tree_add_uint(h263_payload_tree, hf_h263_psc,tvb, offset,3,data);
offset = offset + 2;
proto_tree_add_uint(h263_payload_tree, hf_h263_TR,tvb, offset,2,data);
@@ -313,9 +338,11 @@
/* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/
proto_tree_add_item( h263_payload_tree, hf_h263_PB_frames_mode, tvb, offset, 1, FALSE );
}
- }else{
- if ((data & 0x00007c00)!= 0) { /* GBSC found */
-
+ }
+ }else if ((data & 0x00007c00)!= 0) { /* GBSC found */
+ if ( check_col( pinfo->cinfo, COL_INFO) )
+ col_append_str( pinfo->cinfo, COL_INFO, "(GBSC) ");
+ if( tree ) {
/* Group of Block Start Code (GBSC) (17 bits)
* A word of 17 bits. Its value is 0000 0000 0000 0000 1. GOB start codes may be byte aligned. This
* can be achieved by inserting GSTUF before the start code such that the first bit of the start code is
@@ -324,11 +351,11 @@
*/
proto_tree_add_uint(h263_payload_tree, hf_h263_gbsc,tvb, offset,3,data);
offset = offset + 2;
- }
- }
- }
- proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, FALSE );
+ }
+ }
}
+ if( tree )
+ proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, FALSE );
}
void
@@ -589,6 +616,18 @@
}
},
{
+ &hf_h263_payload,
+ {
+ "H.263 payload",
+ "h263.payload",
+ FT_NONE,
+ BASE_NONE,
+ NULL,
+ 0x0,
+ "The actual H.263 data", HFILL
+ }
+ },
+ {
&hf_h263_data,
{
"H.263 stream",
@@ -755,9 +794,12 @@
proto_h263 = proto_register_protocol("ITU-T Recommendation H.263 RTP Payload header (RFC2190)",
"H.263", "h263");
+ proto_h263_data = proto_register_protocol("ITU-T Recommendation H.263",
+ "H.263 data", "h263data");
proto_register_field_array(proto_h263, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("h263", dissect_h263, proto_h263);
+ register_dissector("h263data", dissect_h263_data, proto_h263_data);
}
void
--- epan/dissectors/packet-amr.c 2005-09-29 16:07:09.478919048 +0100
+++ epan/dissectors/packet-amr.c 2005-09-30 15:54:58.090310528 +0100
@@ -2,7 +2,7 @@
* Routines for AMR dissection
* Copyright 2005, Anders Broman <anders.broman[at]ericsson.com>
*
- * $Id: packet-amr.c,v 1.1.1.3 2005/09/29 13:18:53 jeff Exp $
+ * $Id: packet-amr.c,v 1.6 2005/09/30 14:53:23 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -163,7 +163,7 @@
static void
dissect_amr_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
- int offset =0;
+ int offset =0, i;
guint8 octet;
proto_tree_add_item(tree, hf_amr_if2_ft, tvb, offset, 1, FALSE);
@@ -178,6 +178,12 @@
return;
proto_tree_add_text(tree, tvb, offset+1, -1, "Speech data");
+ for(i=0;amr_codec_mode_request_vals[i].value != 0 || amr_codec_mode_request_vals[i].strptr != NULL;++i) {
+ if(amr_codec_mode_request_vals[i].value == octet)
+ break;
+ }
+ if(amr_codec_mode_request_vals[i].strptr && check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", amr_codec_mode_request_vals[i].strptr );
}
/* Code to actually dissect the packets */
@@ -451,6 +457,8 @@
"Type of AMR encoding of the payload",
&amr_encoding_type, encoding_types, FALSE);
+ register_dissector("amr_if1", dissect_amr_if1, proto_amr);
+ register_dissector("amr_if2", dissect_amr_if2, proto_amr);
}
--- asn1/h245/h245.cnf 2005-09-29 16:07:04.043745320 +0100
+++ asn1/h245/h245.cnf 2005-09-29 17:30:08.694963152 +0100
@@ -1,6 +1,6 @@
# H.245 conformation file
# Copyright 2005 Anders Broman anders.broman[at]ericsson.com
-# $Id: h245.cnf,v 1.1.1.3 2005/09/29 13:18:51 jeff Exp $
+# $Id: h245.cnf,v 1.6 2005/09/29 15:51:24 jeff Exp $
#----------------------------------------------------------------------------------------
#.EXPORTS
#----------------------------------------------------------------------------------------
@@ -12,6 +12,233 @@
OpenLogicalChannel
#----------------------------------------------------------------------------------------
+#.FN_BODY MultiplexEntryDescriptor
+ /*MultiplexEntryDescriptor*/
+ h223_me = NULL;
+ h223_mc = 0;
+%(DEFAULT_BODY)s
+ if(h223_set_mc_handle)
+ (*h223_set_mc_handle)(pinfo, h223_mc, h223_me);
+ /* stuff */
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS MultiplexTableEntryNumber
+ VAL_PTR = &value
+#.FN_BODY MultiplexTableEntryNumber
+ guint32 value;
+%(DEFAULT_BODY)s
+ h223_mc = value & 0xf;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_BODY MultiplexEntryDescriptor/elementList
+ /* create a h223_mux_element to hold onto the head of the list, since
+ * h223_me will track the tail */
+ h223_mux_element dummy_me;
+ h223_me = &dummy_me;
+%(DEFAULT_BODY)s
+ /* set h223_me to the head of the list for MEDescriptor to pick up */
+ h223_me = dummy_me.next;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR MultiplexElement
+ /*MultiplexElement*/
+ h223_mux_element* me = se_alloc(sizeof(h223_mux_element));
+ h223_me->next = me;
+ h223_me = me;
+ h223_me->next = NULL;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS MultiplexElement/type/logicalChannelNumber
+ VAL_PTR = &value
+#.FN_BODY MultiplexElement/type/logicalChannelNumber
+ /*MultiplexElement/type/logicalChannelNumber*/
+ guint32 value;
+%(DEFAULT_BODY)s
+ h223_me->sublist = NULL;
+ h223_me->vc = value & 0xffff;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_BODY MultiplexElement/type/subElementList
+ h223_mux_element dummy_me, *parent_me = h223_me;
+ h223_me = &dummy_me;
+%(DEFAULT_BODY)s
+ parent_me->sublist = dummy_me.next;
+ h223_me = parent_me;
+ h223_me->vc = 0;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR MultiplexElement/repeatCount/untilClosingFlag
+ h223_me->repeat_count = 0;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS MultiplexElement/repeatCount/finite
+ VAL_PTR = &value
+#.FN_BODY MultiplexElement/repeatCount/finite
+ guint32 value;
+%(DEFAULT_BODY)s
+ h223_me->repeat_count = value & 0xffff;
+#.END
+#----------------------------------------------------------------------------------------
+# OpenLogicalChannel .FN_FTR is also declared, line 460ish
+#.FN_BODY OpenLogicalChannel
+ h223_fw_lc_num = 0;
+ h223_lc_params_temp = NULL;
+%(DEFAULT_BODY)s
+ if(h223_fw_lc_num != 0 && h223_fw_lc_params) {
+ h223_pending_olc *pending = se_alloc(sizeof(h223_pending_olc));
+ pending->fw_channel_params = h223_fw_lc_params;
+ pending->rev_channel_params = h223_rev_lc_params;
+ gint32 temp = h223_fw_lc_num;
+ g_hash_table_insert(h223_pending_olc_reqs[pinfo->p2p_dir], GINT_TO_POINTER(temp), pending);
+ }
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS LogicalChannelNumber
+ VAL_PTR = &value
+#.FN_BODY LogicalChannelNumber
+ guint32 value;
+%(DEFAULT_BODY)s
+ h245_lc_temp = value & 0xfff;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR OpenLogicalChannel/forwardLogicalChannelNumber
+ h223_fw_lc_num = h245_lc_temp;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_BODY OpenLogicalChannel/forwardLogicalChannelParameters
+ h245_lc_dissector = NULL;
+%(DEFAULT_BODY)s
+ if(h223_lc_params_temp && h245_lc_dissector)
+ h223_lc_params_temp->subdissector = h245_lc_dissector;
+ else if(h223_lc_params_temp)
+ h223_lc_params_temp->subdissector = data_handle;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters
+ h223_fw_lc_params = se_alloc(sizeof(h223_lc_params));
+ h223_fw_lc_params->al_type = al_nonStandard;
+ h223_fw_lc_params->al_params = NULL;
+ h223_fw_lc_params->segmentable = 0;
+ h223_fw_lc_params->subdissector = NULL;
+ h223_lc_params_temp = h223_fw_lc_params;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters
+ h223_rev_lc_params = se_alloc(sizeof(h223_lc_params));
+ h223_rev_lc_params->al_type = al_nonStandard;
+ h223_rev_lc_params->al_params = NULL;
+ h223_rev_lc_params->segmentable = 0;
+ h223_rev_lc_params->subdissector = NULL;
+ h223_lc_params_temp = h223_rev_lc_params;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al1Framed
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1Framed;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al1NotFramed
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1NotFramed;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al2WithoutSequenceNumbers
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2WithoutSequenceNumbers;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al2WithSequenceNumbers
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2WithSequenceNumbers;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al3
+ if(h223_lc_params_temp) {
+ h223_lc_params_temp->al_type = al3;
+ h223_lc_params_temp->al_params = se_alloc(sizeof(h223_al3_params));
+ }
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS Al3/controlFieldOctets
+ VAL_PTR = &value
+#.FN_BODY Al3/controlFieldOctets
+ guint32 value;
+%(DEFAULT_BODY)s
+ if(h223_lc_params_temp && h223_lc_params_temp->al_params)
+ ((h223_al3_params*)h223_lc_params_temp->al_params)->control_field_octets = value & 3 ;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS Al3/sendBufferSize
+ VAL_PTR = &value
+#.FN_BODY Al3/sendBufferSize
+ guint32 value;
+%(DEFAULT_BODY)s
+ if(h223_lc_params_temp && h223_lc_params_temp->al_params)
+ ((h223_al3_params*)h223_lc_params_temp->al_params)->send_buffer_size = value & 0xfffff;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al1M
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1M;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al2M
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2M;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_HDR H223LogicalChannelParameters/adaptationLayerType/al3M
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al3M;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_PARS H223LogicalChannelParameters/segmentableFlag
+ VAL_PTR = &value
+#.FN_BODY H223LogicalChannelParameters/segmentableFlag
+ guint32 value;
+%(DEFAULT_BODY)s
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->segmentable = value & 1;
+#.END
+#----------------------------------------------------------------------------------------
+# OpenLogicalChannelAck .FN_FTR is also declared, line 460ish
+#.FN_BODY OpenLogicalChannelAck
+ h223_fw_lc_num = 0;
+ h223_rev_lc_num = 0;
+%(DEFAULT_BODY)s
+ guint32 temp = h223_fw_lc_num;
+ int p2p_dir = pinfo->p2p_dir;
+ if(pinfo->p2p_dir == P2P_DIR_SENT)
+ pinfo->p2p_dir = P2P_DIR_RECV;
+ else
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ h223_pending_olc *pend = g_hash_table_lookup( h223_pending_olc_reqs[pinfo->p2p_dir], GINT_TO_POINTER(temp) );
+ if (pend) {
+ DISSECTOR_ASSERT( ( h223_rev_lc_num && pend->rev_channel_params)
+ || (!h223_rev_lc_num && !pend->rev_channel_params) );
+ if(h223_add_lc_handle) {
+ (*h223_add_lc_handle)( pinfo, h223_fw_lc_num, pend->fw_channel_params );
+ if(h223_rev_lc_num)
+ (*h223_add_lc_handle)( pinfo, h223_rev_lc_num, pend->rev_channel_params );
+ }
+ } else {
+ /* we missed the OpenLogicalChannel packet */
+ }
+ pinfo->p2p_dir = p2p_dir;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR OpenLogicalChannelAck/forwardLogicalChannelNumber
+ h223_fw_lc_num = h245_lc_temp;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR OpenLogicalChannelAck/reverseLogicalChannelParamaters/reverseLogicalChannelNumber
+ h223_rev_lc_num = h245_lc_temp;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR H263VideoCapability
+ h245_lc_dissector = h263_handle;
+#.END
+#----------------------------------------------------------------------------------------
#.FN_BODY RequestMessage VAL_PTR = &value
guint32 value;
@@ -231,11 +458,13 @@
h245_pi->msg_type = H245_TermCapSetRls;
#.END
#----------------------------------------------------------------------------------------
+# OpenLogicalChannel .FN_BODY is also declared, line 70ish
#.FN_FTR OpenLogicalChannel
if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
#.END
#----------------------------------------------------------------------------------------
+# OpenLogicalChannelAck .FN_BODY is also declared, line 200ish
#.FN_FTR OpenLogicalChannelAck
h245_pi->msg_type = H245_OpenLogChnAck;
@@ -243,6 +472,9 @@
#----------------------------------------------------------------------------------------
#.FN_PARS CapabilityIdentifier/standard
FN_VARIANT = _str VAL_PTR = &standard_oid_str
+#.FN_FTR CapabilityIdentifier/standard
+ if(!h245_lc_dissector && strcmp(standard_oid_str,"0.0.8.245.1.1.1") == 0)
+ h245_lc_dissector = amr_handle;
#.END
#----------------------------------------------------------------------------------------
#.FN_HDR GenericMessage/subMessageIdentifer
@@ -501,9 +733,13 @@
MulticastAddress/iP6Address MIP6Address
NonStandardIdentifier/h221NonStandard H221NonStandardID
+OpenLogicalChannel/forwardLogicalChannelNumber OLC_fw_lcn
+OpenLogicalChannelAck/forwardLogicalChannelNumber OLC_ack_fw_lcn
OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters OLC_forw_multiplexParameters
OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters OLC_rev_multiplexParameters
OpenLogicalChannel/reverseLogicalChannelParameters OLC_reverseLogicalChannelParameters
+OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters OLC_fw_h223_params
+OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters OLC_rev_h223_params
OpenLogicalChannelAck/reverseLogicalChannelParameters OLC_ack_reverseLogicalChannelParameters
CloseLogicalChannel/reason Clc_reason
VCCapability/availableBitRates/type Avb_type
@@ -518,6 +754,7 @@
FECData/rfc2733/mode FECdata_mode
FECMode/rfc2733Mode/mode FEC_mode
IS11172AudioMode/multichannelType IS11172_multichannelType
+MultiplexElement/repeatCount/finite ME_finiteRepeatCount
MultiplexElement/repeatCount ME_repeatCount
FECCapability/rfc2733 FECC_rfc2733
RequestModeAck/response Req_mode_ack_response
@@ -685,7 +922,7 @@
NewATMVCCommand/aal/aal1/errorCorrection/errorCorrectionOnly errorCorrectionOnlyFlag
NewATMVCIndication/aal/aal1/errorCorrection/errorCorrectionOnly errorCorrectionOnlyFlag
UserInputCapability/extendedAlphanumeric extendedAlphanumericFlag
-MultiplexElement/repeatCount/finite finite_1_65535
+MultiplexElement/repeatCount/finite me_repeatCount_finite
MiscellaneousCommand/type/videoFastUpdateMB/firstMB firstMB_1_8192
MiscellaneousIndication/type/videoNotDecodedMBs/firstMB firstMB_1_8192
H261VideoCapability/cifMPI cifMPI_1_4
@@ -745,8 +982,10 @@
FECData/rfc2733/mode fec_data_mode
V76LogicalChannelParameters/mode v76_mode
OpenLogicalChannelAck/reverseLogicalChannelParameters/multiplexParameters olc_ack_multiplexParameters
-OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters olc_rev_multiplexParameter
+OpenLogicalChannel/forwardLogicalChannelNumber olc_fw_lcn
+OpenLogicalChannelAck/forwardLogicalChannelNumber olc_ack_fw_lcn
OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters olc_forw_multiplexParameters
+OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters olc_rev_multiplexParameter
IS11172AudioMode/multichannelType is11172multichannelType
IS13818AudioMode/multichannelType is13818MultichannelType
CloseLogicalChannel/reason clc_reason
@@ -774,6 +1013,20 @@
CommunicationModeTableEntry/mediaChannel cm_mediaChannel
CommunicationModeTableEntry/mediaControlChannel cm_mediaControlChannel
+OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters olc_rev_h223_params
+OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters olc_fw_h223_params
+
+H223LogicalChannelParameters/adaptationLayerType/al1Framed h223_al_type_al1Framed
+H223LogicalChannelParameters/adaptationLayerType/al1NotFramed h223_al_type_al1NotFramed
+H223LogicalChannelParameters/adaptationLayerType/al2WithoutSequenceNumbers h223_al_type_al2WithoutSequenceNumbers
+H223LogicalChannelParameters/adaptationLayerType/al2WithSequenceNumbers h223_al_type_al2WithSequenceNumbers
+H223LogicalChannelParameters/adaptationLayerType/al3 h223_al_type_al3
+Al3/sendBufferSize al3_sendBufferSize
+H223LogicalChannelParameters/adaptationLayerType/al1M h223_al_type_al1M
+H223LogicalChannelParameters/adaptationLayerType/al2M h223_al_type_al2M
+H223LogicalChannelParameters/adaptationLayerType/al3M h223_al_type_al3M
+H223LogicalChannelParameters/segmentableFlag h223_lc_segmentableFlag
+
#----------------------------------------------------------------------------------------
#.TYPE_ATTR
UnicastAddress/iPAddress/network TYPE = FT_IPv4 DISPLAY = BASE_NONE STRINGS = NULL
@@ -788,4 +1041,6 @@
#----------------------------------------------------------------------------------------
#.FIELD_ATTR
AlternativeCapabilitySet/_item NAME = "alternativeCapability"
+
#----------------------------------------------------------------------------------------
+# vim:set ts=4 sts=2 sw=2:
--- asn1/h245/packet-h245-template.c 2005-09-29 16:07:04.050744256 +0100
+++ asn1/h245/packet-h245-template.c 2005-09-30 15:08:16.432227296 +0100
@@ -2,7 +2,7 @@
* Routines for h245 packet dissection
* Copyright 2004, Anders Broman <anders.broman@xxxxxxxxxxxx>
*
- * $Id: packet-h245-template.c,v 1.1.1.3 2005/09/29 13:18:51 jeff Exp $
+ * $Id: packet-h245-template.c,v 1.9 2005/09/30 11:04:10 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -53,6 +53,7 @@
#include "packet-rtp.h"
#include "packet-rtcp.h"
#include "packet-ber.h"
+#include <epan/emem.h>
#define PNAME "MULTIMEDIA-SYSTEM-CONTROL"
#define PSNAME "H.245"
@@ -66,6 +67,8 @@
static dissector_handle_t data_handle;
static dissector_handle_t h245_handle;
static dissector_handle_t MultimediaSystemControlMessage_handle;
+static dissector_handle_t h263_handle = NULL;
+static dissector_handle_t amr_handle = NULL;
static void reset_h245_packet_info(h245_packet_info *pi);
static int hf_h245_pdu_type = -1;
@@ -221,6 +224,53 @@
{ 3267, "RFC 3267 - Adaptive Multi-Rate (AMR) and Adaptive Multi-Rate Wideband (AMR-WB)" },
{ 0, NULL }
};
+
+/* h223 multiplex codes */
+static h223_set_mc_handle_t h223_set_mc_handle = NULL;
+h223_mux_element *h223_me=NULL;
+guint8 h223_mc=0;
+void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle )
+{
+ h223_set_mc_handle = handle;
+}
+
+/* h223 logical channels */
+typedef struct {
+ h223_lc_params *fw_channel_params;
+ h223_lc_params *rev_channel_params;
+} h223_pending_olc;
+
+static GHashTable* h223_pending_olc_reqs[] = { NULL, NULL };
+static dissector_handle_t h245_lc_dissector;
+static guint16 h245_lc_temp;
+static guint16 h223_fw_lc_num;
+static guint16 h223_rev_lc_num;
+static h223_lc_params *h223_lc_params_temp;
+static h223_lc_params *h223_fw_lc_params;
+static h223_lc_params *h223_rev_lc_params;
+static h223_add_lc_handle_t h223_add_lc_handle = NULL;
+
+static void h223_lc_init_dir( int dir )
+{
+ if ( h223_pending_olc_reqs[dir] )
+ g_hash_table_destroy( h223_pending_olc_reqs[dir] );
+ h223_pending_olc_reqs[dir] = g_hash_table_new( g_direct_hash, g_direct_equal );
+}
+
+static void h223_lc_init()
+{
+ h223_lc_init_dir( P2P_DIR_SENT );
+ h223_lc_init_dir( P2P_DIR_RECV );
+ h223_lc_params_temp = NULL;
+ h245_lc_dissector = NULL;
+ h223_fw_lc_num = 0;
+}
+
+void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle )
+{
+ h223_add_lc_handle = handle;
+}
+
/* Initialize the protocol and registered fields */
int proto_h245 = -1;
#include "packet-h245-hf.c"
@@ -348,12 +398,16 @@
rtp_handle = find_dissector("rtp");
rtcp_handle = find_dissector("rtcp");
data_handle = find_dissector("data");
+ h263_handle = find_dissector("h263data");
+ amr_handle = find_dissector("amr_if2");
h245_handle=create_dissector_handle(dissect_h245, proto_h245);
dissector_add_handle("tcp.port", h245_handle);
MultimediaSystemControlMessage_handle=create_dissector_handle(dissect_h245_h245, proto_h245);
dissector_add_handle("udp.port", MultimediaSystemControlMessage_handle);
+
+ h223_lc_init();
}
static void reset_h245_packet_info(h245_packet_info *pi)
--- asn1/h245/packet-h245-template.h 2005-09-29 16:07:04.051744104 +0100
+++ asn1/h245/packet-h245-template.h 2005-09-29 17:30:08.696962848 +0100
@@ -2,7 +2,7 @@
* Routines for h245 packet dissection
* Copyright 2005, Anders Broman <anders.broman@xxxxxxxxxxxx>
*
- * $Id: packet-h245-template.h,v 1.1.1.2 2005/09/29 13:18:51 jeff Exp $
+ * $Id: packet-h245-template.h,v 1.5 2005/09/29 15:51:24 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -49,8 +49,77 @@
gchar comment[50]; /* the Frame Comment used by graph_analysis, what is a message desc */
} h245_packet_info;
+/*
+ * h223 LC info
+ */
+
+typedef enum {
+ al_nonStandard,
+ al1Framed,
+ al1NotFramed,
+ al2WithoutSequenceNumbers,
+ al2WithSequenceNumbers,
+ al3,
+ /*...*/
+ // al?M: unimplemented annex C adaptation layers
+ al1M,
+ al2M,
+ al3M
+} h223_al_type;
+
+typedef struct {
+ guint8 control_field_octets;
+ guint32 send_buffer_size;
+} h223_al3_params;
+
+typedef struct {
+ h223_al_type al_type;
+ gpointer al_params;
+ gboolean segmentable;
+ dissector_handle_t subdissector;
+} h223_lc_params;
+
+typedef enum {
+ nonStandardDataType,
+ nullData,
+ videoData,
+ audioData,
+ data,
+ encryptionData,
+ /*...,*/
+ h235Control,
+ h235Media,
+ multiplexedStream,
+ redundancyEncoding,
+ multiplePayloadStream,
+ fec
+} h245_lc_data_type_enum;
+
+typedef struct {
+ h245_lc_data_type_enum data_type;
+ gpointer params;
+} h245_lc_data_type;
+
+/*
+ * h223 MUX info
+ */
+
+typedef struct _h223_mux_element h223_mux_element;
+struct _h223_mux_element {
+ h223_mux_element* sublist; /* if NULL, use vc instead */
+ guint16 vc;
+ guint16 repeat_count; /* 0 == untilClosingFlag */
+ h223_mux_element* next;
+};
+
+#include <epan/packet_info.h>
+typedef void (*h223_set_mc_handle_t) ( packet_info* pinfo, guint8 mc, h223_mux_element* me );
+extern void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle );
+
+typedef void (*h223_add_lc_handle_t) ( packet_info* pinfo, guint16 lc, h223_lc_params* params );
+extern void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle );
-#include "packet-h245-exp.h"*/
+#include "packet-h245-exp.h"
void dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, char *codec_str);
--- epan/dissectors/packet-h245.c 2005-09-29 16:07:12.567449520 +0100
+++ epan/dissectors/packet-h245.c 2005-09-30 15:08:18.131968896 +0100
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Ethereal dissector compiler */
-/* .\packet-h245.c */
+/* ./packet-h245.c */
/* ../../tools/asn2eth.py -X -e -p h245 -c h245.cnf -s packet-h245-template h245.asn */
/* Input file: packet-h245-template.c */
@@ -9,7 +9,7 @@
* Routines for h245 packet dissection
* Copyright 2004, Anders Broman <anders.broman@xxxxxxxxxxxx>
*
- * $Id: packet-h245.c,v 1.1.1.4 2005/09/29 13:18:54 jeff Exp $
+ * $Id: packet-h245.c,v 1.10 2005/09/30 11:04:10 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -60,6 +60,7 @@
#include "packet-rtp.h"
#include "packet-rtcp.h"
#include "packet-ber.h"
+#include <epan/emem.h>
#define PNAME "MULTIMEDIA-SYSTEM-CONTROL"
#define PSNAME "H.245"
@@ -73,6 +74,8 @@
static dissector_handle_t data_handle;
static dissector_handle_t h245_handle;
static dissector_handle_t MultimediaSystemControlMessage_handle;
+static dissector_handle_t h263_handle = NULL;
+static dissector_handle_t amr_handle = NULL;
static void reset_h245_packet_info(h245_packet_info *pi);
static int hf_h245_pdu_type = -1;
@@ -228,6 +231,53 @@
{ 3267, "RFC 3267 - Adaptive Multi-Rate (AMR) and Adaptive Multi-Rate Wideband (AMR-WB)" },
{ 0, NULL }
};
+
+/* h223 multiplex codes */
+static h223_set_mc_handle_t h223_set_mc_handle = NULL;
+h223_mux_element *h223_me=NULL;
+guint8 h223_mc=0;
+void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle )
+{
+ h223_set_mc_handle = handle;
+}
+
+/* h223 logical channels */
+typedef struct {
+ h223_lc_params *fw_channel_params;
+ h223_lc_params *rev_channel_params;
+} h223_pending_olc;
+
+static GHashTable* h223_pending_olc_reqs[] = { NULL, NULL };
+static dissector_handle_t h245_lc_dissector;
+static guint16 h245_lc_temp;
+static guint16 h223_fw_lc_num;
+static guint16 h223_rev_lc_num;
+static h223_lc_params *h223_lc_params_temp;
+static h223_lc_params *h223_fw_lc_params;
+static h223_lc_params *h223_rev_lc_params;
+static h223_add_lc_handle_t h223_add_lc_handle = NULL;
+
+static void h223_lc_init_dir( int dir )
+{
+ if ( h223_pending_olc_reqs[dir] )
+ g_hash_table_destroy( h223_pending_olc_reqs[dir] );
+ h223_pending_olc_reqs[dir] = g_hash_table_new( g_direct_hash, g_direct_equal );
+}
+
+static void h223_lc_init()
+{
+ h223_lc_init_dir( P2P_DIR_SENT );
+ h223_lc_init_dir( P2P_DIR_RECV );
+ h223_lc_params_temp = NULL;
+ h245_lc_dissector = NULL;
+ h223_fw_lc_num = 0;
+}
+
+void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle )
+{
+ h223_add_lc_handle = handle;
+}
+
/* Initialize the protocol and registered fields */
int proto_h245 = -1;
@@ -913,19 +963,20 @@
static int hf_h245_separateStreamBool = -1; /* T_separateStream */
static int hf_h245_separatePort = -1; /* BOOLEAN */
static int hf_h245_samePortBool = -1; /* BOOLEAN */
-static int hf_h245_forwardLogicalChannelNumber = -1; /* LogicalChannelNumber */
+static int hf_h245_olc_fw_lcn = -1; /* OLC_fw_lcn */
static int hf_h245_forwardLogicalChannelParameters = -1; /* T_forwardLogicalChannelParameters */
static int hf_h245_portNumber = -1; /* INTEGER_0_65535 */
static int hf_h245_dataType = -1; /* DataType */
static int hf_h245_olc_forw_multiplexParameters = -1; /* OLC_forw_multiplexParameters */
static int hf_h245_h222LogicalChannelParameters = -1; /* H222LogicalChannelParameters */
-static int hf_h245_h223LogicalChannelParameters = -1; /* H223LogicalChannelParameters */
+static int hf_h245_olc_fw_h223_params = -1; /* OLC_fw_h223_params */
static int hf_h245_v76LogicalChannelParameters = -1; /* V76LogicalChannelParameters */
static int hf_h245_h2250LogicalChannelParameters = -1; /* H2250LogicalChannelParameters */
static int hf_h245_forwardLogicalChannelDependency = -1; /* LogicalChannelNumber */
static int hf_h245_replacementFor = -1; /* LogicalChannelNumber */
static int hf_h245_reverseLogicalChannelParameters = -1; /* OLC_reverseLogicalChannelParameters */
static int hf_h245_olc_rev_multiplexParameter = -1; /* OLC_rev_multiplexParameters */
+static int hf_h245_olc_rev_h223_params = -1; /* OLC_rev_h223_params */
static int hf_h245_reverseLogicalChannelDependency = -1; /* LogicalChannelNumber */
static int hf_h245_separateStack = -1; /* NetworkAccessParameters */
static int hf_h245_encryptionSync = -1; /* EncryptionSync */
@@ -965,17 +1016,17 @@
static int hf_h245_programDescriptors = -1; /* OCTET_STRING */
static int hf_h245_streamDescriptors = -1; /* OCTET_STRING */
static int hf_h245_adaptationLayerType = -1; /* T_adaptationLayerType */
-static int hf_h245_al1Framed = -1; /* NULL */
-static int hf_h245_al1NotFramed = -1; /* NULL */
-static int hf_h245_al2WithoutSequenceNumbers = -1; /* NULL */
-static int hf_h245_al2WithSequenceNumbers = -1; /* NULL */
-static int hf_h245_al3 = -1; /* Al3 */
-static int hf_h245_al1M = -1; /* H223AL1MParameters */
-static int hf_h245_al2M = -1; /* H223AL2MParameters */
-static int hf_h245_al3M = -1; /* H223AL3MParameters */
-static int hf_h245_segmentableFlag = -1; /* BOOLEAN */
-static int hf_h245_controlFieldOctets = -1; /* INTEGER_0_2 */
-static int hf_h245_sendBufferSize = -1; /* INTEGER_0_16777215 */
+static int hf_h245_h223_al_type_al1Framed = -1; /* T_al1Framed */
+static int hf_h245_h223_al_type_al1NotFramed = -1; /* T_al1NotFramed */
+static int hf_h245_h223_al_type_al2WithoutSequenceNumbers = -1; /* T_al2WithoutSequenceNumbers */
+static int hf_h245_h223_al_type_al2WithSequenceNumbers = -1; /* T_al2WithSequenceNumbers */
+static int hf_h245_h223_al_type_al3 = -1; /* T_al3 */
+static int hf_h245_h223_al_type_al1M = -1; /* T_al1M */
+static int hf_h245_h223_al_type_al2M = -1; /* T_al2M */
+static int hf_h245_h223_al_type_al3M = -1; /* T_al3M */
+static int hf_h245_h223_lc_segmentableFlag = -1; /* T_segmentableFlag */
+static int hf_h245_controlFieldOctets = -1; /* T_controlFieldOctets */
+static int hf_h245_al3_sendBufferSize = -1; /* T_sendBufferSize */
static int hf_h245_transferMode = -1; /* T_transferMode */
static int hf_h245_framed = -1; /* NULL */
static int hf_h245_unframed = -1; /* NULL */
@@ -1005,6 +1056,7 @@
static int hf_h245_numberOfRetransmissions = -1; /* T_numberOfRetransmissions */
static int hf_h245_finite = -1; /* INTEGER_0_16 */
static int hf_h245_infinite = -1; /* NULL */
+static int hf_h245_sendBufferSize = -1; /* INTEGER_0_16777215 */
static int hf_h245_hdlcParameters = -1; /* V76HDLCParameters */
static int hf_h245_suspendResume = -1; /* T_suspendResume */
static int hf_h245_noSuspendResume = -1; /* NULL */
@@ -1088,11 +1140,13 @@
static int hf_h245_escrowentry_item = -1; /* EscrowData */
static int hf_h245_escrowID = -1; /* OBJECT_IDENTIFIER */
static int hf_h245_escrowValue = -1; /* BIT_STRING_SIZE_1_65535 */
+static int hf_h245_olc_ack_fw_lcn = -1; /* OLC_ack_fw_lcn */
static int hf_h245_olc_ack_reverseLogicalChannelParameters = -1; /* OLC_ack_reverseLogicalChannelParameters */
static int hf_h245_reverseLogicalChannelNumber = -1; /* LogicalChannelNumber */
static int hf_h245_olc_ack_multiplexParameters = -1; /* T_multiplexParameters */
static int hf_h245_forwardMultiplexAckParameters = -1; /* T_forwardMultiplexAckParameters */
static int hf_h245_h2250LogicalChannelAckParameters = -1; /* H2250LogicalChannelAckParameters */
+static int hf_h245_forwardLogicalChannelNumber = -1; /* LogicalChannelNumber */
static int hf_h245_olc_rej_cause = -1; /* OpenLogicalChannelRejectCause */
static int hf_h245_unsuitableReverseParameters = -1; /* NULL */
static int hf_h245_dataTypeNotSupported = -1; /* NULL */
@@ -1125,15 +1179,15 @@
static int hf_h245_multiplexEntryDescriptors = -1; /* SET_SIZE_1_15_OF_MultiplexEntryDescriptor */
static int hf_h245_multiplexEntryDescriptors_item = -1; /* MultiplexEntryDescriptor */
static int hf_h245_multiplexTableEntryNumber = -1; /* MultiplexTableEntryNumber */
-static int hf_h245_elementList = -1; /* SEQUENCE_SIZE_1_256_OF_MultiplexElement */
+static int hf_h245_elementList = -1; /* T_elementList */
static int hf_h245_elementList_item = -1; /* MultiplexElement */
static int hf_h245_me_type = -1; /* Me_type */
-static int hf_h245_logicalChannelNum = -1; /* INTEGER_0_65535 */
-static int hf_h245_subElementList = -1; /* SEQUENCE_SIZE_2_255_OF_MultiplexElement */
+static int hf_h245_logicalChannelNum = -1; /* T_logicalChannelNumber */
+static int hf_h245_subElementList = -1; /* T_subElementList */
static int hf_h245_subElementList_item = -1; /* MultiplexElement */
static int hf_h245_me_repeatCount = -1; /* ME_repeatCount */
-static int hf_h245_finite_1_65535 = -1; /* INTEGER_1_65535 */
-static int hf_h245_untilClosingFlag = -1; /* NULL */
+static int hf_h245_me_repeatCount_finite = -1; /* ME_finiteRepeatCount */
+static int hf_h245_untilClosingFlag = -1; /* T_untilClosingFlag */
static int hf_h245_multiplexTableEntryNumbers = -1; /* SET_SIZE_1_15_OF_MultiplexTableEntryNumber */
static int hf_h245_multiplexTableEntryNumber_item = -1; /* MultiplexTableEntryNumber */
static int hf_h245_rejectionDescriptions1 = -1; /* SET_SIZE_1_15_OF_MultiplexEntryRejectionDescriptions */
@@ -1182,6 +1236,15 @@
static int hf_h245_rfc2733Mode = -1; /* T_rfc2733Mode */
static int hf_h245_fec_mode = -1; /* FEC_mode */
static int hf_h245_adaptationLayer = -1; /* AdaptationLayerType */
+static int hf_h245_al1Framed = -1; /* NULL */
+static int hf_h245_al1NotFramed = -1; /* NULL */
+static int hf_h245_al2WithoutSequenceNumbers = -1; /* NULL */
+static int hf_h245_al2WithSequenceNumbers = -1; /* NULL */
+static int hf_h245_al3 = -1; /* Al3 */
+static int hf_h245_al1M = -1; /* H223AL1MParameters */
+static int hf_h245_al2M = -1; /* H223AL2MParameters */
+static int hf_h245_al3M = -1; /* H223AL3MParameters */
+static int hf_h245_segmentableFlag = -1; /* BOOLEAN */
static int hf_h245_redundancyEncodingMode = -1; /* RedundancyEncodingMode */
static int hf_h245_secondaryEncoding = -1; /* T_secondaryEncoding */
static int hf_h245_h261VideoMode = -1; /* H261VideoMode */
@@ -1834,10 +1897,10 @@
static gint ett_h245_MultiplexEntrySend = -1;
static gint ett_h245_SET_SIZE_1_15_OF_MultiplexEntryDescriptor = -1;
static gint ett_h245_MultiplexEntryDescriptor = -1;
-static gint ett_h245_SEQUENCE_SIZE_1_256_OF_MultiplexElement = -1;
+static gint ett_h245_T_elementList = -1;
static gint ett_h245_MultiplexElement = -1;
static gint ett_h245_Me_type = -1;
-static gint ett_h245_SEQUENCE_SIZE_2_255_OF_MultiplexElement = -1;
+static gint ett_h245_T_subElementList = -1;
static gint ett_h245_ME_repeatCount = -1;
static gint ett_h245_MultiplexEntrySendAck = -1;
static gint ett_h245_SET_SIZE_1_15_OF_MultiplexTableEntryNumber = -1;
@@ -3154,9 +3217,6 @@
static int dissect_audioHeaderPresent(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_audioHeaderPresent);
}
-static int dissect_segmentableFlag(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_segmentableFlag);
-}
static int dissect_alsduSplitting(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_alsduSplitting);
}
@@ -3175,6 +3235,9 @@
static int dissect_flowControlToZero(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_flowControlToZero);
}
+static int dissect_segmentableFlag(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_segmentableFlag);
+}
static int dissect_multiplexCapabilityBool(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_BOOLEAN(tvb, offset, pinfo, tree, hf_h245_multiplexCapabilityBool);
}
@@ -3279,9 +3342,6 @@
static int dissect_multicast_IPv6_tsapIdentifier(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_INTEGER_0_65535(tvb, offset, pinfo, tree, hf_h245_multicast_IPv6_tsapIdentifier);
}
-static int dissect_logicalChannelNum(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_INTEGER_0_65535(tvb, offset, pinfo, tree, hf_h245_logicalChannelNum);
-}
static int dissect_requestedInterval(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_INTEGER_0_65535(tvb, offset, pinfo, tree, hf_h245_requestedInterval);
}
@@ -3325,9 +3385,6 @@
static int dissect_higherBitRate(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_INTEGER_1_65535(tvb, offset, pinfo, tree, hf_h245_higherBitRate);
}
-static int dissect_finite_1_65535(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_INTEGER_1_65535(tvb, offset, pinfo, tree, hf_h245_finite_1_65535);
-}
static int dissect_maxNumberOfAdditionalConnections(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_INTEGER_1_65535(tvb, offset, pinfo, tree, hf_h245_maxNumberOfAdditionalConnections);
}
@@ -3779,18 +3836,6 @@
static int dissect_nullData(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_nullData);
}
-static int dissect_al1Framed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al1Framed);
-}
-static int dissect_al1NotFramed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al1NotFramed);
-}
-static int dissect_al2WithoutSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al2WithoutSequenceNumbers);
-}
-static int dissect_al2WithSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al2WithSequenceNumbers);
-}
static int dissect_framed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_framed);
}
@@ -3926,9 +3971,6 @@
static int dissect_normal(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_normal);
}
-static int dissect_untilClosingFlag(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_untilClosingFlag);
-}
static int dissect_unspecifiedCause(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_unspecifiedCause);
}
@@ -3950,6 +3992,18 @@
static int dissect_requestDenied(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_requestDenied);
}
+static int dissect_al1Framed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al1Framed);
+}
+static int dissect_al1NotFramed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al1NotFramed);
+}
+static int dissect_al2WithoutSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al2WithoutSequenceNumbers);
+}
+static int dissect_al2WithSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_al2WithSequenceNumbers);
+}
static int dissect_qcif(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_NULL(tvb, offset, pinfo, tree, hf_h245_qcif);
}
@@ -5222,6 +5276,8 @@
dissect_h245_T_standard(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
offset = dissect_per_object_identifier_str(tvb, offset, pinfo, tree, hf_index, &standard_oid_str);
+ if(!h245_lc_dissector && strcmp(standard_oid_str,"0.0.8.245.1.1.1") == 0)
+ h245_lc_dissector = amr_handle;
return offset;
}
static int dissect_standardOid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -7358,6 +7414,7 @@
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_H263VideoCapability, H263VideoCapability_sequence);
+ h245_lc_dissector = h263_handle;
return offset;
}
static int dissect_h263VideoCapability(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -8500,14 +8557,14 @@
static int
dissect_h245_LogicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
- 1U, 65535U, NULL, NULL, FALSE);
+ 1U, 65535U, &value, NULL, FALSE);
+
+ h245_lc_temp = value & 0xfff;
return offset;
}
-static int dissect_forwardLogicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_forwardLogicalChannelNumber);
-}
static int dissect_forwardLogicalChannelDependency(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_forwardLogicalChannelDependency);
}
@@ -8520,6 +8577,9 @@
static int dissect_reverseLogicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_reverseLogicalChannelNumber);
}
+static int dissect_forwardLogicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_forwardLogicalChannelNumber);
+}
static int dissect_logicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_logicalChannelNumber);
}
@@ -8543,6 +8603,19 @@
}
+
+static int
+dissect_h245_OLC_fw_lcn(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ offset = dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_index);
+
+ h223_fw_lc_num = h245_lc_temp;
+ return offset;
+}
+static int dissect_olc_fw_lcn(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_OLC_fw_lcn(tvb, offset, pinfo, tree, hf_h245_olc_fw_lcn);
+}
+
+
static const value_string h245_EncryptionMode_vals[] = {
{ 0, "nonStandard" },
{ 1, "h233Encryption" },
@@ -8976,20 +9049,97 @@
static int
-dissect_h245_INTEGER_0_2(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+dissect_h245_T_al1Framed(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1Framed;
+ offset = dissect_per_null(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al1Framed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al1Framed(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al1Framed);
+}
+
+
+
+static int
+dissect_h245_T_al1NotFramed(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1NotFramed;
+ offset = dissect_per_null(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al1NotFramed(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al1NotFramed(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al1NotFramed);
+}
+
+
+
+static int
+dissect_h245_T_al2WithoutSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2WithoutSequenceNumbers;
+ offset = dissect_per_null(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al2WithoutSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al2WithoutSequenceNumbers(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al2WithoutSequenceNumbers);
+}
+
+
+
+static int
+dissect_h245_T_al2WithSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2WithSequenceNumbers;
+ offset = dissect_per_null(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al2WithSequenceNumbers(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al2WithSequenceNumbers(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al2WithSequenceNumbers);
+}
+
+
+
+static int
+dissect_h245_T_controlFieldOctets(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
- 0U, 2U, NULL, NULL, FALSE);
+ 0U, 2U, &value, NULL, FALSE);
+
+ if(h223_lc_params_temp && h223_lc_params_temp->al_params)
+ ((h223_al3_params*)h223_lc_params_temp->al_params)->control_field_octets = value & 3 ;
return offset;
}
static int dissect_controlFieldOctets(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_INTEGER_0_2(tvb, offset, pinfo, tree, hf_h245_controlFieldOctets);
+ return dissect_h245_T_controlFieldOctets(tvb, offset, pinfo, tree, hf_h245_controlFieldOctets);
+}
+
+
+
+static int
+dissect_h245_T_sendBufferSize(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
+ offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
+ 0U, 16777215U, &value, NULL, FALSE);
+
+ if(h223_lc_params_temp && h223_lc_params_temp->al_params)
+ ((h223_al3_params*)h223_lc_params_temp->al_params)->send_buffer_size = value & 0xfffff;
+
+ return offset;
+}
+static int dissect_al3_sendBufferSize(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_sendBufferSize(tvb, offset, pinfo, tree, hf_h245_al3_sendBufferSize);
}
static const per_sequence_t Al3_sequence[] = {
{ "controlFieldOctets" , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_controlFieldOctets },
- { "sendBufferSize" , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_sendBufferSize },
+ { "sendBufferSize" , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_al3_sendBufferSize },
{ NULL, 0, 0, NULL }
};
@@ -9005,6 +9155,22 @@
}
+
+static int
+dissect_h245_T_al3(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp) {
+ h223_lc_params_temp->al_type = al3;
+ h223_lc_params_temp->al_params = se_alloc(sizeof(h223_al3_params));
+ }
+ offset = dissect_h245_Al3(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al3(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al3(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al3);
+}
+
+
static const value_string h245_T_transferMode_vals[] = {
{ 0, "framed" },
{ 1, "unframed" },
@@ -9215,6 +9381,20 @@
}
+
+static int
+dissect_h245_T_al1M(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al1M;
+ offset = dissect_h245_H223AL1MParameters(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al1M(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al1M(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al1M);
+}
+
+
static const value_string h245_AL2HeaderFEC_vals[] = {
{ 0, "sebch16-5" },
{ 1, "golay24-12" },
@@ -9258,6 +9438,20 @@
}
+
+static int
+dissect_h245_T_al2M(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al2M;
+ offset = dissect_h245_H223AL2MParameters(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al2M(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al2M(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al2M);
+}
+
+
static const value_string h245_T_headerFormat_vals[] = {
{ 0, "sebch16-7" },
{ 1, "golay24-12" },
@@ -9342,6 +9536,20 @@
}
+
+static int
+dissect_h245_T_al3M(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->al_type = al3M;
+ offset = dissect_h245_H223AL3MParameters(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_h223_al_type_al3M(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_al3M(tvb, offset, pinfo, tree, hf_h245_h223_al_type_al3M);
+}
+
+
static const value_string h245_T_adaptationLayerType_vals[] = {
{ 0, "nonStandard" },
{ 1, "al1Framed" },
@@ -9357,14 +9565,14 @@
static const per_choice_t T_adaptationLayerType_choice[] = {
{ 0, "nonStandard" , ASN1_EXTENSION_ROOT , dissect_nonStandard },
- { 1, "al1Framed" , ASN1_EXTENSION_ROOT , dissect_al1Framed },
- { 2, "al1NotFramed" , ASN1_EXTENSION_ROOT , dissect_al1NotFramed },
- { 3, "al2WithoutSequenceNumbers" , ASN1_EXTENSION_ROOT , dissect_al2WithoutSequenceNumbers },
- { 4, "al2WithSequenceNumbers" , ASN1_EXTENSION_ROOT , dissect_al2WithSequenceNumbers },
- { 5, "al3" , ASN1_EXTENSION_ROOT , dissect_al3 },
- { 6, "al1M" , ASN1_NOT_EXTENSION_ROOT, dissect_al1M },
- { 7, "al2M" , ASN1_NOT_EXTENSION_ROOT, dissect_al2M },
- { 8, "al3M" , ASN1_NOT_EXTENSION_ROOT, dissect_al3M },
+ { 1, "al1Framed" , ASN1_EXTENSION_ROOT , dissect_h223_al_type_al1Framed },
+ { 2, "al1NotFramed" , ASN1_EXTENSION_ROOT , dissect_h223_al_type_al1NotFramed },
+ { 3, "al2WithoutSequenceNumbers" , ASN1_EXTENSION_ROOT , dissect_h223_al_type_al2WithoutSequenceNumbers },
+ { 4, "al2WithSequenceNumbers" , ASN1_EXTENSION_ROOT , dissect_h223_al_type_al2WithSequenceNumbers },
+ { 5, "al3" , ASN1_EXTENSION_ROOT , dissect_h223_al_type_al3 },
+ { 6, "al1M" , ASN1_NOT_EXTENSION_ROOT, dissect_h223_al_type_al1M },
+ { 7, "al2M" , ASN1_NOT_EXTENSION_ROOT, dissect_h223_al_type_al2M },
+ { 8, "al3M" , ASN1_NOT_EXTENSION_ROOT, dissect_h223_al_type_al3M },
{ 0, NULL, 0, NULL }
};
@@ -9381,9 +9589,26 @@
}
+
+static int
+dissect_h245_T_segmentableFlag(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
+ offset = dissect_per_boolean(tvb, offset, pinfo, tree, hf_index,
+ &value, NULL);
+
+ if(h223_lc_params_temp)
+ h223_lc_params_temp->segmentable = value & 1;
+
+ return offset;
+}
+static int dissect_h223_lc_segmentableFlag(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_segmentableFlag(tvb, offset, pinfo, tree, hf_h245_h223_lc_segmentableFlag);
+}
+
+
static const per_sequence_t H223LogicalChannelParameters_sequence[] = {
{ "adaptationLayerType" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_adaptationLayerType },
- { "segmentableFlag" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_segmentableFlag },
+ { "segmentableFlag" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_h223_lc_segmentableFlag },
{ NULL, 0, 0, NULL }
};
@@ -9394,8 +9619,23 @@
return offset;
}
-static int dissect_h223LogicalChannelParameters(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_H223LogicalChannelParameters(tvb, offset, pinfo, tree, hf_h245_h223LogicalChannelParameters);
+
+
+
+static int
+dissect_h245_OLC_fw_h223_params(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h223_fw_lc_params = se_alloc(sizeof(h223_lc_params));
+ h223_fw_lc_params->al_type = al_nonStandard;
+ h223_fw_lc_params->al_params = NULL;
+ h223_fw_lc_params->segmentable = 0;
+ h223_fw_lc_params->subdissector = NULL;
+ h223_lc_params_temp = h223_fw_lc_params;
+ offset = dissect_h245_H223LogicalChannelParameters(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_olc_fw_h223_params(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_OLC_fw_h223_params(tvb, offset, pinfo, tree, hf_h245_olc_fw_h223_params);
}
@@ -10102,7 +10342,7 @@
static const per_choice_t OLC_forw_multiplexParameters_choice[] = {
{ 0, "h222LogicalChannelParameters", ASN1_EXTENSION_ROOT , dissect_h222LogicalChannelParameters },
- { 1, "h223LogicalChannelParameters", ASN1_EXTENSION_ROOT , dissect_h223LogicalChannelParameters },
+ { 1, "h223LogicalChannelParameters", ASN1_EXTENSION_ROOT , dissect_olc_fw_h223_params },
{ 2, "v76LogicalChannelParameters" , ASN1_EXTENSION_ROOT , dissect_v76LogicalChannelParameters },
{ 3, "h2250LogicalChannelParameters", ASN1_NOT_EXTENSION_ROOT, dissect_h2250LogicalChannelParameters },
{ 4, "none" , ASN1_NOT_EXTENSION_ROOT, dissect_none },
@@ -10133,9 +10373,15 @@
static int
dissect_h245_T_forwardLogicalChannelParameters(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h245_lc_dissector = NULL;
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_T_forwardLogicalChannelParameters, T_forwardLogicalChannelParameters_sequence);
+ if(h223_lc_params_temp && h245_lc_dissector)
+ h223_lc_params_temp->subdissector = h245_lc_dissector;
+ else if(h223_lc_params_temp)
+ h223_lc_params_temp->subdissector = data_handle;
+
return offset;
}
static int dissect_forwardLogicalChannelParameters(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -10143,6 +10389,24 @@
}
+
+static int
+dissect_h245_OLC_rev_h223_params(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h223_rev_lc_params = se_alloc(sizeof(h223_lc_params));
+ h223_rev_lc_params->al_type = al_nonStandard;
+ h223_rev_lc_params->al_params = NULL;
+ h223_rev_lc_params->segmentable = 0;
+ h223_rev_lc_params->subdissector = NULL;
+ h223_lc_params_temp = h223_rev_lc_params;
+ offset = dissect_h245_H223LogicalChannelParameters(tvb, offset, pinfo, tree, hf_index);
+
+ return offset;
+}
+static int dissect_olc_rev_h223_params(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_OLC_rev_h223_params(tvb, offset, pinfo, tree, hf_h245_olc_rev_h223_params);
+}
+
+
static const value_string h245_OLC_rev_multiplexParameters_vals[] = {
{ 0, "h223LogicalChannelParameters" },
{ 1, "v76LogicalChannelParameters" },
@@ -10151,7 +10415,7 @@
};
static const per_choice_t OLC_rev_multiplexParameters_choice[] = {
- { 0, "h223LogicalChannelParameters", ASN1_EXTENSION_ROOT , dissect_h223LogicalChannelParameters },
+ { 0, "h223LogicalChannelParameters", ASN1_EXTENSION_ROOT , dissect_olc_rev_h223_params },
{ 1, "v76LogicalChannelParameters" , ASN1_EXTENSION_ROOT , dissect_v76LogicalChannelParameters },
{ 2, "h2250LogicalChannelParameters", ASN1_NOT_EXTENSION_ROOT, dissect_h2250LogicalChannelParameters },
{ 0, NULL, 0, NULL }
@@ -10432,7 +10696,7 @@
static const per_sequence_t OpenLogicalChannel_sequence[] = {
- { "forwardLogicalChannelNumber" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_forwardLogicalChannelNumber },
+ { "forwardLogicalChannelNumber" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_olc_fw_lcn },
{ "forwardLogicalChannelParameters", ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_forwardLogicalChannelParameters },
{ "reverseLogicalChannelParameters", ASN1_EXTENSION_ROOT , ASN1_OPTIONAL , dissect_reverseLogicalChannelParameters },
{ "separateStack" , ASN1_NOT_EXTENSION_ROOT, ASN1_OPTIONAL , dissect_separateStack },
@@ -10442,9 +10706,19 @@
int
dissect_h245_OpenLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h223_fw_lc_num = 0;
+ h223_lc_params_temp = NULL;
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_OpenLogicalChannel, OpenLogicalChannel_sequence);
+ if(h223_fw_lc_num != 0 && h223_fw_lc_params) {
+ h223_pending_olc *pending = se_alloc(sizeof(h223_pending_olc));
+ pending->fw_channel_params = h223_fw_lc_params;
+ pending->rev_channel_params = h223_rev_lc_params;
+ gint32 temp = h223_fw_lc_num;
+ g_hash_table_insert(h223_pending_olc_reqs[pinfo->p2p_dir], GINT_TO_POINTER(temp), pending);
+ }
+
if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
return offset;
@@ -10578,8 +10852,11 @@
static int
dissect_h245_MultiplexTableEntryNumber(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
- 1U, 15U, NULL, NULL, FALSE);
+ 1U, 15U, &value, NULL, FALSE);
+
+ h223_mc = value & 0xf;
return offset;
}
@@ -10594,20 +10871,44 @@
}
-static const per_sequence_t SEQUENCE_SIZE_2_255_OF_MultiplexElement_sequence_of[1] = {
+
+static int
+dissect_h245_T_logicalChannelNumber(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ /*MultiplexElement/type/logicalChannelNumber*/
+ guint32 value;
+ offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
+ 0U, 65535U, &value, NULL, FALSE);
+
+ h223_me->sublist = NULL;
+ h223_me->vc = value & 0xffff;
+
+ return offset;
+}
+static int dissect_logicalChannelNum(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_logicalChannelNumber(tvb, offset, pinfo, tree, hf_h245_logicalChannelNum);
+}
+
+
+static const per_sequence_t T_subElementList_sequence_of[1] = {
{ "" , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_subElementList_item },
};
static int
-dissect_h245_SEQUENCE_SIZE_2_255_OF_MultiplexElement(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+dissect_h245_T_subElementList(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h223_mux_element dummy_me, *parent_me = h223_me;
+ h223_me = &dummy_me;
offset = dissect_per_constrained_sequence_of(tvb, offset, pinfo, tree, hf_index,
- ett_h245_SEQUENCE_SIZE_2_255_OF_MultiplexElement, SEQUENCE_SIZE_2_255_OF_MultiplexElement_sequence_of,
+ ett_h245_T_subElementList, T_subElementList_sequence_of,
2, 255);
+ parent_me->sublist = dummy_me.next;
+ h223_me = parent_me;
+ h223_me->vc = 0;
+
return offset;
}
static int dissect_subElementList(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_SEQUENCE_SIZE_2_255_OF_MultiplexElement(tvb, offset, pinfo, tree, hf_h245_subElementList);
+ return dissect_h245_T_subElementList(tvb, offset, pinfo, tree, hf_h245_subElementList);
}
@@ -10636,6 +10937,35 @@
}
+
+static int
+dissect_h245_ME_finiteRepeatCount(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ guint32 value;
+ offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
+ 1U, 65535U, &value, NULL, FALSE);
+
+ h223_me->repeat_count = value & 0xffff;
+
+ return offset;
+}
+static int dissect_me_repeatCount_finite(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_ME_finiteRepeatCount(tvb, offset, pinfo, tree, hf_h245_me_repeatCount_finite);
+}
+
+
+
+static int
+dissect_h245_T_untilClosingFlag(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ offset = dissect_per_null(tvb, offset, pinfo, tree, hf_index);
+
+ h223_me->repeat_count = 0;
+ return offset;
+}
+static int dissect_untilClosingFlag(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_T_untilClosingFlag(tvb, offset, pinfo, tree, hf_h245_untilClosingFlag);
+}
+
+
static const value_string h245_ME_repeatCount_vals[] = {
{ 0, "finite" },
{ 1, "untilClosingFlag" },
@@ -10643,7 +10973,7 @@
};
static const per_choice_t ME_repeatCount_choice[] = {
- { 0, "finite" , ASN1_NO_EXTENSIONS , dissect_finite_1_65535 },
+ { 0, "finite" , ASN1_NO_EXTENSIONS , dissect_me_repeatCount_finite },
{ 1, "untilClosingFlag" , ASN1_NO_EXTENSIONS , dissect_untilClosingFlag },
{ 0, NULL, 0, NULL }
};
@@ -10669,6 +10999,11 @@
static int
dissect_h245_MultiplexElement(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ /*MultiplexElement*/
+ h223_mux_element* me = se_alloc(sizeof(h223_mux_element));
+ h223_me->next = me;
+ h223_me = me;
+ h223_me->next = NULL;
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_MultiplexElement, MultiplexElement_sequence);
@@ -10676,20 +11011,27 @@
}
-static const per_sequence_t SEQUENCE_SIZE_1_256_OF_MultiplexElement_sequence_of[1] = {
+static const per_sequence_t T_elementList_sequence_of[1] = {
{ "" , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_elementList_item },
};
static int
-dissect_h245_SEQUENCE_SIZE_1_256_OF_MultiplexElement(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+dissect_h245_T_elementList(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ /* create a h223_mux_element to hold onto the head of the list, since
+ * h223_me will track the tail */
+ h223_mux_element dummy_me;
+ h223_me = &dummy_me;
offset = dissect_per_constrained_sequence_of(tvb, offset, pinfo, tree, hf_index,
- ett_h245_SEQUENCE_SIZE_1_256_OF_MultiplexElement, SEQUENCE_SIZE_1_256_OF_MultiplexElement_sequence_of,
+ ett_h245_T_elementList, T_elementList_sequence_of,
1, 256);
+ /* set h223_me to the head of the list for MEDescriptor to pick up */
+ h223_me = dummy_me.next;
+
return offset;
}
static int dissect_elementList(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h245_SEQUENCE_SIZE_1_256_OF_MultiplexElement(tvb, offset, pinfo, tree, hf_h245_elementList);
+ return dissect_h245_T_elementList(tvb, offset, pinfo, tree, hf_h245_elementList);
}
@@ -10701,9 +11043,16 @@
static int
dissect_h245_MultiplexEntryDescriptor(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ /*MultiplexEntryDescriptor*/
+ h223_me = NULL;
+ h223_mc = 0;
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_MultiplexEntryDescriptor, MultiplexEntryDescriptor_sequence);
+ if(h223_set_mc_handle)
+ (*h223_set_mc_handle)(pinfo, h223_mc, h223_me);
+ /* stuff */
+
return offset;
}
static int dissect_multiplexEntryDescriptors_item(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12825,6 +13174,19 @@
}
+
+static int
+dissect_h245_OLC_ack_fw_lcn(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ offset = dissect_h245_LogicalChannelNumber(tvb, offset, pinfo, tree, hf_index);
+
+ h223_fw_lc_num = h245_lc_temp;
+ return offset;
+}
+static int dissect_olc_ack_fw_lcn(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h245_OLC_ack_fw_lcn(tvb, offset, pinfo, tree, hf_h245_olc_ack_fw_lcn);
+}
+
+
static const value_string h245_T_multiplexParameters_vals[] = {
{ 0, "h222LogicalChannelParameters" },
{ 1, "h2250LogicalChannelParameters" },
@@ -12978,7 +13340,7 @@
static const per_sequence_t OpenLogicalChannelAck_sequence[] = {
- { "forwardLogicalChannelNumber" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_forwardLogicalChannelNumber },
+ { "forwardLogicalChannelNumber" , ASN1_EXTENSION_ROOT , ASN1_NOT_OPTIONAL, dissect_olc_ack_fw_lcn },
{ "reverseLogicalChannelParameters", ASN1_EXTENSION_ROOT , ASN1_OPTIONAL , dissect_olc_ack_reverseLogicalChannelParameters },
{ "separateStack" , ASN1_NOT_EXTENSION_ROOT, ASN1_OPTIONAL , dissect_separateStack },
{ "forwardMultiplexAckParameters", ASN1_NOT_EXTENSION_ROOT, ASN1_OPTIONAL , dissect_forwardMultiplexAckParameters },
@@ -12988,9 +13350,31 @@
static int
dissect_h245_OpenLogicalChannelAck(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ h223_fw_lc_num = 0;
+ h223_rev_lc_num = 0;
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h245_OpenLogicalChannelAck, OpenLogicalChannelAck_sequence);
+ guint32 temp = h223_fw_lc_num;
+ int p2p_dir = pinfo->p2p_dir;
+ if(pinfo->p2p_dir == P2P_DIR_SENT)
+ pinfo->p2p_dir = P2P_DIR_RECV;
+ else
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ h223_pending_olc *pend = g_hash_table_lookup( h223_pending_olc_reqs[pinfo->p2p_dir], GINT_TO_POINTER(temp) );
+ if (pend) {
+ DISSECTOR_ASSERT( ( h223_rev_lc_num && pend->rev_channel_params)
+ || (!h223_rev_lc_num && !pend->rev_channel_params) );
+ if(h223_add_lc_handle) {
+ (*h223_add_lc_handle)( pinfo, h223_fw_lc_num, pend->fw_channel_params );
+ if(h223_rev_lc_num)
+ (*h223_add_lc_handle)( pinfo, h223_rev_lc_num, pend->rev_channel_params );
+ }
+ } else {
+ /* we missed the OpenLogicalChannel packet */
+ }
+ pinfo->p2p_dir = p2p_dir;
+
h245_pi->msg_type = H245_OpenLogChnAck;
return offset;
@@ -19652,10 +20036,10 @@
{ "samePort", "h245.samePort",
FT_BOOLEAN, 8, NULL, 0,
"FECCapability/rfc2733/separateStream/samePort", HFILL }},
- { &hf_h245_forwardLogicalChannelNumber,
+ { &hf_h245_olc_fw_lcn,
{ "forwardLogicalChannelNumber", "h245.forwardLogicalChannelNumber",
FT_UINT32, BASE_DEC, NULL, 0,
- "", HFILL }},
+ "OpenLogicalChannel/forwardLogicalChannelNumber", HFILL }},
{ &hf_h245_forwardLogicalChannelParameters,
{ "forwardLogicalChannelParameters", "h245.forwardLogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
@@ -19676,10 +20060,10 @@
{ "h222LogicalChannelParameters", "h245.h222LogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
"", HFILL }},
- { &hf_h245_h223LogicalChannelParameters,
+ { &hf_h245_olc_fw_h223_params,
{ "h223LogicalChannelParameters", "h245.h223LogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
+ "OpenLogicalChannel/forwardLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters", HFILL }},
{ &hf_h245_v76LogicalChannelParameters,
{ "v76LogicalChannelParameters", "h245.v76LogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
@@ -19704,6 +20088,10 @@
{ "multiplexParameters", "h245.multiplexParameters",
FT_UINT32, BASE_DEC, VALS(h245_OLC_rev_multiplexParameters_vals), 0,
"OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters", HFILL }},
+ { &hf_h245_olc_rev_h223_params,
+ { "h223LogicalChannelParameters", "h245.h223LogicalChannelParameters",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "OpenLogicalChannel/reverseLogicalChannelParameters/multiplexParameters/h223LogicalChannelParameters", HFILL }},
{ &hf_h245_reverseLogicalChannelDependency,
{ "reverseLogicalChannelDependency", "h245.reverseLogicalChannelDependency",
FT_UINT32, BASE_DEC, NULL, 0,
@@ -19860,50 +20248,50 @@
{ "adaptationLayerType", "h245.adaptationLayerType",
FT_UINT32, BASE_DEC, VALS(h245_T_adaptationLayerType_vals), 0,
"H223LogicalChannelParameters/adaptationLayerType", HFILL }},
- { &hf_h245_al1Framed,
+ { &hf_h245_h223_al_type_al1Framed,
{ "al1Framed", "h245.al1Framed",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al1NotFramed,
+ "H223LogicalChannelParameters/adaptationLayerType/al1Framed", HFILL }},
+ { &hf_h245_h223_al_type_al1NotFramed,
{ "al1NotFramed", "h245.al1NotFramed",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al2WithoutSequenceNumbers,
+ "H223LogicalChannelParameters/adaptationLayerType/al1NotFramed", HFILL }},
+ { &hf_h245_h223_al_type_al2WithoutSequenceNumbers,
{ "al2WithoutSequenceNumbers", "h245.al2WithoutSequenceNumbers",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al2WithSequenceNumbers,
+ "H223LogicalChannelParameters/adaptationLayerType/al2WithoutSequenceNumbers", HFILL }},
+ { &hf_h245_h223_al_type_al2WithSequenceNumbers,
{ "al2WithSequenceNumbers", "h245.al2WithSequenceNumbers",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al3,
+ "H223LogicalChannelParameters/adaptationLayerType/al2WithSequenceNumbers", HFILL }},
+ { &hf_h245_h223_al_type_al3,
{ "al3", "h245.al3",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al1M,
+ "H223LogicalChannelParameters/adaptationLayerType/al3", HFILL }},
+ { &hf_h245_h223_al_type_al1M,
{ "al1M", "h245.al1M",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al2M,
+ "H223LogicalChannelParameters/adaptationLayerType/al1M", HFILL }},
+ { &hf_h245_h223_al_type_al2M,
{ "al2M", "h245.al2M",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_al3M,
+ "H223LogicalChannelParameters/adaptationLayerType/al2M", HFILL }},
+ { &hf_h245_h223_al_type_al3M,
{ "al3M", "h245.al3M",
FT_NONE, BASE_NONE, NULL, 0,
- "", HFILL }},
- { &hf_h245_segmentableFlag,
+ "H223LogicalChannelParameters/adaptationLayerType/al3M", HFILL }},
+ { &hf_h245_h223_lc_segmentableFlag,
{ "segmentableFlag", "h245.segmentableFlag",
FT_BOOLEAN, 8, NULL, 0,
- "", HFILL }},
+ "H223LogicalChannelParameters/segmentableFlag", HFILL }},
{ &hf_h245_controlFieldOctets,
{ "controlFieldOctets", "h245.controlFieldOctets",
FT_UINT32, BASE_DEC, NULL, 0,
"Al3/controlFieldOctets", HFILL }},
- { &hf_h245_sendBufferSize,
+ { &hf_h245_al3_sendBufferSize,
{ "sendBufferSize", "h245.sendBufferSize",
FT_UINT32, BASE_DEC, NULL, 0,
- "", HFILL }},
+ "Al3/sendBufferSize", HFILL }},
{ &hf_h245_transferMode,
{ "transferMode", "h245.transferMode",
FT_UINT32, BASE_DEC, VALS(h245_T_transferMode_vals), 0,
@@ -20020,6 +20408,10 @@
{ "infinite", "h245.infinite",
FT_NONE, BASE_NONE, NULL, 0,
"H223AnnexCArqParameters/numberOfRetransmissions/infinite", HFILL }},
+ { &hf_h245_sendBufferSize,
+ { "sendBufferSize", "h245.sendBufferSize",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ "H223AnnexCArqParameters/sendBufferSize", HFILL }},
{ &hf_h245_hdlcParameters,
{ "hdlcParameters", "h245.hdlcParameters",
FT_NONE, BASE_NONE, NULL, 0,
@@ -20352,6 +20744,10 @@
{ "escrowValue", "h245.escrowValue",
FT_BYTES, BASE_HEX, NULL, 0,
"EscrowData/escrowValue", HFILL }},
+ { &hf_h245_olc_ack_fw_lcn,
+ { "forwardLogicalChannelNumber", "h245.forwardLogicalChannelNumber",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ "OpenLogicalChannelAck/forwardLogicalChannelNumber", HFILL }},
{ &hf_h245_olc_ack_reverseLogicalChannelParameters,
{ "reverseLogicalChannelParameters", "h245.reverseLogicalChannelParameters",
FT_NONE, BASE_NONE, NULL, 0,
@@ -20372,6 +20768,10 @@
{ "h2250LogicalChannelAckParameters", "h245.h2250LogicalChannelAckParameters",
FT_NONE, BASE_NONE, NULL, 0,
"OpenLogicalChannelAck/forwardMultiplexAckParameters/h2250LogicalChannelAckParameters", HFILL }},
+ { &hf_h245_forwardLogicalChannelNumber,
+ { "forwardLogicalChannelNumber", "h245.forwardLogicalChannelNumber",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ "", HFILL }},
{ &hf_h245_olc_rej_cause,
{ "cause", "h245.cause",
FT_UINT32, BASE_DEC, VALS(h245_OpenLogicalChannelRejectCause_vals), 0,
@@ -20528,7 +20928,7 @@
{ "repeatCount", "h245.repeatCount",
FT_UINT32, BASE_DEC, VALS(h245_ME_repeatCount_vals), 0,
"MultiplexElement/repeatCount", HFILL }},
- { &hf_h245_finite_1_65535,
+ { &hf_h245_me_repeatCount_finite,
{ "finite", "h245.finite",
FT_UINT32, BASE_DEC, NULL, 0,
"MultiplexElement/repeatCount/finite", HFILL }},
@@ -20728,6 +21128,42 @@
{ "adaptationLayerType", "h245.adaptationLayerType",
FT_UINT32, BASE_DEC, VALS(h245_AdaptationLayerType_vals), 0,
"H223ModeParameters/adaptationLayerType", HFILL }},
+ { &hf_h245_al1Framed,
+ { "al1Framed", "h245.al1Framed",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al1Framed", HFILL }},
+ { &hf_h245_al1NotFramed,
+ { "al1NotFramed", "h245.al1NotFramed",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al1NotFramed", HFILL }},
+ { &hf_h245_al2WithoutSequenceNumbers,
+ { "al2WithoutSequenceNumbers", "h245.al2WithoutSequenceNumbers",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al2WithoutSequenceNumbers", HFILL }},
+ { &hf_h245_al2WithSequenceNumbers,
+ { "al2WithSequenceNumbers", "h245.al2WithSequenceNumbers",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al2WithSequenceNumbers", HFILL }},
+ { &hf_h245_al3,
+ { "al3", "h245.al3",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al3", HFILL }},
+ { &hf_h245_al1M,
+ { "al1M", "h245.al1M",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al1M", HFILL }},
+ { &hf_h245_al2M,
+ { "al2M", "h245.al2M",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al2M", HFILL }},
+ { &hf_h245_al3M,
+ { "al3M", "h245.al3M",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "H223ModeParameters/adaptationLayerType/al3M", HFILL }},
+ { &hf_h245_segmentableFlag,
+ { "segmentableFlag", "h245.segmentableFlag",
+ FT_BOOLEAN, 8, NULL, 0,
+ "H223ModeParameters/segmentableFlag", HFILL }},
{ &hf_h245_redundancyEncodingMode,
{ "redundancyEncodingMode", "h245.redundancyEncodingMode",
FT_NONE, BASE_NONE, NULL, 0,
@@ -22544,10 +22980,10 @@
&ett_h245_MultiplexEntrySend,
&ett_h245_SET_SIZE_1_15_OF_MultiplexEntryDescriptor,
&ett_h245_MultiplexEntryDescriptor,
- &ett_h245_SEQUENCE_SIZE_1_256_OF_MultiplexElement,
+ &ett_h245_T_elementList,
&ett_h245_MultiplexElement,
&ett_h245_Me_type,
- &ett_h245_SEQUENCE_SIZE_2_255_OF_MultiplexElement,
+ &ett_h245_T_subElementList,
&ett_h245_ME_repeatCount,
&ett_h245_MultiplexEntrySendAck,
&ett_h245_SET_SIZE_1_15_OF_MultiplexTableEntryNumber,
@@ -22816,12 +23252,16 @@
rtp_handle = find_dissector("rtp");
rtcp_handle = find_dissector("rtcp");
data_handle = find_dissector("data");
+ h263_handle = find_dissector("h263data");
+ amr_handle = find_dissector("amr_if2");
h245_handle=create_dissector_handle(dissect_h245, proto_h245);
dissector_add_handle("tcp.port", h245_handle);
MultimediaSystemControlMessage_handle=create_dissector_handle(dissect_h245_h245, proto_h245);
dissector_add_handle("udp.port", MultimediaSystemControlMessage_handle);
+
+ h223_lc_init();
}
static void reset_h245_packet_info(h245_packet_info *pi)
--- epan/dissectors/packet-h245.h 2005-09-29 16:07:12.590446024 +0100
+++ epan/dissectors/packet-h245.h 2005-09-29 17:30:14.766040208 +0100
@@ -9,7 +9,7 @@
* Routines for h245 packet dissection
* Copyright 2005, Anders Broman <anders.broman@xxxxxxxxxxxx>
*
- * $Id: packet-h245.h,v 1.1.1.3 2005/09/29 13:18:54 jeff Exp $
+ * $Id: packet-h245.h,v 1.8 2005/09/29 15:51:25 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -56,6 +56,75 @@
gchar comment[50]; /* the Frame Comment used by graph_analysis, what is a message desc */
} h245_packet_info;
+/*
+ * h223 LC info
+ */
+
+typedef enum {
+ al_nonStandard,
+ al1Framed,
+ al1NotFramed,
+ al2WithoutSequenceNumbers,
+ al2WithSequenceNumbers,
+ al3,
+ /*...*/
+ // al?M: unimplemented annex C adaptation layers
+ al1M,
+ al2M,
+ al3M
+} h223_al_type;
+
+typedef struct {
+ guint8 control_field_octets;
+ guint32 send_buffer_size;
+} h223_al3_params;
+
+typedef struct {
+ h223_al_type al_type;
+ gpointer al_params;
+ gboolean segmentable;
+ dissector_handle_t subdissector;
+} h223_lc_params;
+
+typedef enum {
+ nonStandardDataType,
+ nullData,
+ videoData,
+ audioData,
+ data,
+ encryptionData,
+ /*...,*/
+ h235Control,
+ h235Media,
+ multiplexedStream,
+ redundancyEncoding,
+ multiplePayloadStream,
+ fec
+} h245_lc_data_type_enum;
+
+typedef struct {
+ h245_lc_data_type_enum data_type;
+ gpointer params;
+} h245_lc_data_type;
+
+/*
+ * h223 MUX info
+ */
+
+typedef struct _h223_mux_element h223_mux_element;
+struct _h223_mux_element {
+ h223_mux_element* sublist; /* if NULL, use vc instead */
+ guint16 vc;
+ guint16 repeat_count; /* 0 == untilClosingFlag */
+ h223_mux_element* next;
+};
+
+#include <epan/packet_info.h>
+typedef void (*h223_set_mc_handle_t) ( packet_info* pinfo, guint8 mc, h223_mux_element* me );
+extern void h245_set_h223_set_mc_handle( h223_set_mc_handle_t handle );
+
+typedef void (*h223_add_lc_handle_t) ( packet_info* pinfo, guint16 lc, h223_lc_params* params );
+extern void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle );
/*--- Included file: packet-h245-exp.h ---*/
--- plugins/h223/packet-srp.c 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/packet-srp.c 2005-07-05 06:27:45.000000000 +0100
@@ -0,0 +1,242 @@
+/* packet-srp.c
+ * Routines for H.324/SRP dissection
+ * 2004 Richard van der Hoff <richardv@xxxxxxxxxxxxx>
+ *
+ * $Id: packet-srp.c,v 1.2 2005/07/05 05:27:45 richardv Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gmodule.h>
+#include <glib.h>
+#include <epan/bitswap.h>
+#include <epan/circuit.h>
+#include <epan/packet.h>
+#include <epan/stream.h>
+#include <epan/reassemble.h>
+#include <epan/crc16.h>
+
+#include "packet-srp.h"
+
+/* Ethereal ID of the protocols */
+static int proto_srp = -1;
+static int proto_ccsrl = -1;
+
+/* The following hf_* variables are used to hold the ethereal IDs of
+ * our header fields; they are filled out when we call
+ * proto_register_field_array() in proto_register_srp()
+ */
+static int hf_srp_header = -1;
+static int hf_srp_seqno = -1;
+static int hf_srp_crc = -1;
+static int hf_srp_crc_bad = -1;
+static int hf_ccsrl_ls = -1;
+
+/* These are the ids of the subtrees that we may be creating */
+static gint ett_srp = -1;
+static gint ett_ccsrl = -1;
+
+static dissector_handle_t data_handle=NULL;
+static dissector_handle_t ccsrl_handle=NULL;
+static dissector_handle_t h245dg_handle=NULL;
+
+/*****************************************************************************/
+#define SRP_SRP_COMMAND 249
+#define SRP_SRP_RESPONSE 251
+#define SRP_NSRP_RESPONSE 247
+
+static const value_string srp_frame_types[] = {
+ {SRP_SRP_COMMAND, "SRP command"},
+ {SRP_SRP_RESPONSE, "SRP response"},
+ {SRP_NSRP_RESPONSE, "NSRP response"},
+ {0,NULL}
+};
+
+static const value_string ccsrl_ls_vals[] = {
+ {0xFF, "Yes"},
+ {0x00, "No"},
+ {0,NULL}
+};
+
+/*****************************************************************************/
+
+static void dissect_ccsrl(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+ proto_item *ccsrl_item;
+ proto_tree *ccsrl_tree=NULL;
+ guint8 lastseg = tvb_get_guint8(tvb,0);
+ tvbuff_t *next_tvb;
+
+ /* add the 'ccsrl' tree to the main tree */
+ if (tree) {
+ ccsrl_item = proto_tree_add_item (tree, proto_ccsrl, tvb, 0, -1, FALSE);
+ ccsrl_tree = proto_item_add_subtree (ccsrl_item, ett_ccsrl);
+ proto_tree_add_uint(ccsrl_tree,hf_ccsrl_ls,tvb,0,1,lastseg);
+ }
+
+ /* XXX add support for reassembly of fragments */
+
+ /* XXX currently, we always dissect as H245. It's not necessarily
+ that though.
+ */
+ next_tvb = tvb_new_subset(tvb, 1, -1, -1 );
+ call_dissector( h245dg_handle, next_tvb, pinfo, ccsrl_tree );
+}
+
+static void dissect_srp_command(tvbuff_t * tvb, packet_info * pinfo, proto_tree * srp_tree)
+{
+ tvbuff_t *next_tvb;
+ guint payload_len;
+
+ if( srp_tree )
+ proto_tree_add_item(srp_tree,hf_srp_seqno,tvb,1,1,FALSE);
+
+ payload_len = tvb_reported_length_remaining(tvb,4);
+ next_tvb = tvb_new_subset(tvb, 2, payload_len, payload_len );
+
+ /* XXX currently, we always dissect as CCSRL. It's only that in
+ * H324/Annex C though.
+ */
+ call_dissector(ccsrl_handle, next_tvb, pinfo, srp_tree );
+}
+
+static void dissect_srp (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+ proto_item *srp_item = NULL;
+ proto_tree *srp_tree = NULL;
+
+ guint8 header = tvb_get_guint8(tvb,0);
+
+ /* add the 'srp' tree to the main tree */
+ if (tree) {
+ srp_item = proto_tree_add_item (tree, proto_srp, tvb, 0, -1, FALSE);
+ srp_tree = proto_item_add_subtree (srp_item, ett_srp);
+ proto_tree_add_uint(srp_tree,hf_srp_header,tvb,0,1,header);
+ }
+
+ switch( header ) {
+ case SRP_SRP_COMMAND:
+ dissect_srp_command(tvb,pinfo,srp_tree);
+ break;
+
+ case SRP_SRP_RESPONSE:
+ break;
+
+ case SRP_NSRP_RESPONSE:
+ if( srp_tree )
+ proto_tree_add_item(srp_tree,hf_srp_seqno,tvb,1,1,FALSE);
+ break;
+
+ default:
+ break;
+ }
+
+ if( srp_tree ) {
+ guint16 crc, calc_crc;
+ guint crc_offset = tvb_reported_length(tvb)-2;
+ crc = tvb_get_letohs(tvb,-2);
+
+ /* crc includes the header */
+ calc_crc = crc16_ccitt_tvb(tvb,crc_offset);
+
+ if( crc == calc_crc ) {
+ proto_tree_add_uint_format(srp_tree, hf_srp_crc, tvb,
+ crc_offset, 2, crc,
+ "CRC: 0x%04x (correct)", crc);
+ } else {
+ proto_tree_add_boolean_hidden(srp_tree, hf_srp_crc_bad, tvb,
+ crc_offset, 2, TRUE);
+ proto_tree_add_uint_format(srp_tree, hf_srp_crc, tvb,
+ crc_offset, 2, crc,
+ "CRC: 0x%04x (incorrect, should be 0x%04x)",
+ crc,
+ calc_crc);
+ }
+ }
+
+}
+
+void proto_register_ccsrl (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_ccsrl_ls,
+ { "Last Segment","ccsrl.ls",FT_UINT8, BASE_HEX, ccsrl_ls_vals, 0x0,
+ "Last segment indicator", HFILL}},
+ };
+
+ static gint *ett[] = {
+ &ett_ccsrl,
+ };
+
+ if (proto_ccsrl == -1) { /* execute protocol initialization only once */
+ proto_ccsrl =
+ proto_register_protocol ("H.324/CCSRL", "CCSRL", "ccsrl");
+
+ proto_register_field_array (proto_ccsrl, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ register_dissector("ccsrl", dissect_ccsrl, proto_ccsrl);
+ }
+}
+
+void proto_register_srp (void)
+{
+ static hf_register_info hf[] = {
+ {&hf_srp_header,
+ { "Header", "srp.header", FT_UINT8, BASE_DEC, srp_frame_types, 0x0,
+ "SRP header octet", HFILL }},
+ {&hf_srp_seqno,
+ { "Sequence Number", "srp.seqno", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Sequence Number", HFILL }},
+ {&hf_srp_crc,
+ { "CRC", "srp.crc", FT_UINT16, BASE_HEX, NULL, 0x0,
+ "CRC", HFILL }},
+ { &hf_srp_crc_bad,
+ { "Bad CRC","srp.crc_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+ };
+
+ static gint *ett[] = {
+ &ett_srp,
+ };
+
+ if (proto_srp == -1) { /* execute protocol initialization only once */
+ proto_srp =
+ proto_register_protocol ("H.324/SRP", "SRP", "srp");
+
+ proto_register_field_array (proto_srp, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ register_dissector("srp", dissect_srp, proto_srp);
+
+ /* register our init routine to be called at the start of a capture,
+ to clear out our hash tables etc */
+ // register_init_routine(&srp_init_protocol);
+
+ }
+}
+
+
+void proto_reg_handoff_srp(void) {
+ data_handle = find_dissector("data");
+ ccsrl_handle = find_dissector("ccsrl");
+ h245dg_handle = find_dissector("h245dg");
+}
--- plugins/h223/packet-srp.h 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/packet-srp.h 2004-05-18 16:10:49.000000000 +0100
@@ -0,0 +1,33 @@
+/* $Id: packet-srp.h,v 1.1 2004/05/18 15:10:49 richardv Exp $
+ *
+ * H.324/SRP dissection
+ *
+ * 2004 Richard van der Hoff <richardv@xxxxxxxxxxxxx>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_SRP_H__
+#define __PACKET_SRP_H__
+
+void proto_register_srp (void);
+void proto_register_ccsrl (void);
+void proto_reg_handoff_srp(void);
+
+#endif /* __PACKET_SRP_H__ */
--- configure.in 2005-09-29 16:07:01.958062392 +0100
+++ configure.in 2005-09-29 17:30:06.807250128 +0100
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.1.1.9 2005/09/29 13:18:51 jeff Exp $
+# $Id: configure.in,v 1.9 2005/09/29 15:51:24 jeff Exp $
#
AC_INIT(cfile.h)
@@ -1238,6 +1238,7 @@
plugins/enttec/Makefile
plugins/giop/Makefile
plugins/gryphon/Makefile
+ plugins/h223/Makefile
plugins/irda/Makefile
plugins/lwres/Makefile
plugins/mate/Makefile
--- plugins/h223/AUTHORS 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/AUTHORS 2004-04-15 15:07:43.000000000 +0100
@@ -0,0 +1,4 @@
+Author :
+Richard van der Hoff <richardv@xxxxxxxxxxxxx>
+
+
--- plugins/h223/ChangeLog 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/ChangeLog 2004-04-15 15:07:43.000000000 +0100
@@ -0,0 +1,5 @@
+2004-04-14 Richard van der Hoff <richardv@xxxxxxxxxxxxx>
+
+ * initial version
+
+
--- plugins/h223/COPYING 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/COPYING 2004-04-15 15:07:43.000000000 +0100
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- plugins/h223/Makefile.am 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/Makefile.am 2004-05-24 12:38:55.000000000 +0100
@@ -0,0 +1,52 @@
+# Makefile.am
+# Automake file for Ethereal/H223
+#
+# $Id: Makefile.am,v 1.3 2004/05/24 11:38:55 richardv Exp $
+#
+# Ethereal - Network traffic analyzer
+# By Gerald Combs <gerald@xxxxxxxxxxxx>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+INCLUDES = -I$(top_srcdir)
+
+plugindir = @plugindir@
+
+plugin_LTLIBRARIES = h223.la
+h223_la_SOURCES = \
+ golay.h \
+ golay.c \
+ moduleinfo.h \
+ packet-h223.c \
+ packet-h223.h \
+ packet-srp.c \
+ packet-srp.h \
+ plugin.c
+
+h223_la_LDFLAGS = -module -avoid-version
+
+# Libs must be cleared, or else libtool won't create a shared module.
+# If your module needs to be linked against any particular libraries,
+# add them here.
+LIBS =
+
+CLEANFILES = \
+ h223 \
+ *~
+
+EXTRA_DIST = \
+ Makefile.nmake
--- plugins/h223/Makefile.nmake 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/Makefile.nmake 2004-05-24 12:38:55.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# $Id: Makefile.nmake,v 1.4 2004/05/24 11:38:55 richardv Exp $
+#
+
+include ..\..\config.nmake
+
+############### no need to modify below this line #########
+
+CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \
+ /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+
+OBJECTS=packet-h223.obj packet-srp.obj plugin.obj golay.obj
+
+h223.dll h223.exp h223.lib : $(OBJECTS) ..\plugin_api.obj
+ link -dll /out:h223.dll $(OBJECTS) ..\plugin_api.obj \
+ $(GLIB_LIBS)
+
+clean:
+ rm -f $(OBJECTS) h223.dll h223.exp h223.lib $(PDB_FILE)
+
+distclean: clean
--- plugins/h223/moduleinfo.h 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/moduleinfo.h 2004-04-15 15:07:43.000000000 +0100
@@ -0,0 +1,18 @@
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "h223"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "0.0.1"
+
+
--- plugins/h223/plugin.c 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/plugin.c 2005-07-05 06:28:02.000000000 +0100
@@ -0,0 +1,51 @@
+/* $Id: plugin.c,v 1.2 2005/07/05 05:28:02 richardv Exp $
+ *
+ * Routines for H.223 packet dissection
+ * Copyright (c) 2005 MX Telecom Ltd <richardv@xxxxxxxxxxxxx>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gmodule.h>
+#include <glib.h>
+#include "moduleinfo.h"
+
+#include "packet-h223.h"
+#include "packet-srp.h"
+
+#ifndef ENABLE_STATIC
+G_MODULE_EXPORT const gchar version[] = VERSION;
+
+G_MODULE_EXPORT void plugin_register(void)
+{
+ /* register the new protocol, protocol fields, and subtrees */
+ proto_register_h223();
+ proto_register_srp();
+ proto_register_ccsrl();
+}
+
+G_MODULE_EXPORT void plugin_reg_handoff(void){
+ proto_reg_handoff_h223();
+ proto_reg_handoff_srp();
+}
+#endif
--- plugins/Makefile.am 2005-09-29 16:07:20.009318184 +0100
+++ plugins/Makefile.am 2005-09-29 17:30:21.047085344 +0100
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.1.1.6 2005/09/29 13:18:56 jeff Exp $
+# $Id: Makefile.am,v 1.7 2005/09/29 15:51:26 jeff Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -31,6 +31,7 @@
enttec \
giop \
gryphon \
+ h223 \
irda \
lwres \
mate \
--- plugins/Makefile.nmake 2005-09-29 16:07:20.050311952 +0100
+++ plugins/Makefile.nmake 2005-09-29 17:30:21.061083216 +0100
@@ -1,5 +1,5 @@
#
-# $Id: Makefile.nmake,v 1.1.1.6 2005/09/29 13:18:56 jeff Exp $
+# $Id: Makefile.nmake,v 1.7 2005/09/29 15:51:26 jeff Exp $
#
include ..\config.nmake
@@ -77,6 +77,11 @@
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
cd ..
+h223::
+ cd h223
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
+ cd ..
+
irda::
cd irda
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake
--- plugins/h223/golay.c 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/golay.c 2004-05-24 12:38:55.000000000 +0100
@@ -0,0 +1,257 @@
+/* $Id: golay.c,v 1.2 2004/05/24 11:38:55 richardv Exp $
+ *
+ * Provides routines for encoding and decoding the extended Golay
+ * (24,12,8) code.
+ *
+ * This implementation will detect up to 4 errors in a codeword (without
+ * being able to correct them); it will correct up to 3 errors.
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include "golay.h"
+
+
+/* Encoding matrix, H
+
+ These entries are formed from the matrix specified in H.223/B.3.2.1.3;
+ it's first transposed so we have:
+
+ [P1 ] [111110010010] [MC1 ]
+ [P2 ] [011111001001] [MC2 ]
+ [P3 ] [110001110110] [MC3 ]
+ [P4 ] [011000111011] [MC4 ]
+ [P5 ] [110010001111] [MPL1]
+ [P6 ] = [100111010101] [MPL2]
+ [P7 ] [101101111000] [MPL3]
+ [P8 ] [010110111100] [MPL4]
+ [P9 ] [001011011110] [MPL5]
+ [P10] [000101101111] [MPL6]
+ [P11] [111100100101] [MPL7]
+ [P12] [101011100011] [MPL8]
+
+ So according to the equation, P1 = MC1+MC2+MC3+MC4+MPL1+MPL4+MPL7
+
+ Looking down the first column, we see that if MC1 is set, we toggle bits
+ 1,3,5,6,7,11,12 of the parity: in binary, 110001110101 = 0xE3A
+
+ Similarly, to calculate the inverse, we read across the top of the table and
+ see that P1 is affected by bits MC1,MC2,MC3,MC4,MPL1,MPL4,MPL7: in binary,
+ 111110010010 = 0x49F.
+
+ I've seen cunning implementations of this which only use one table. That
+ technique doesn't seem to work with these numbers though.
+*/
+
+static const guint golay_encode_matrix[12] = {
+ 0xC75,
+ 0x49F,
+ 0xD4B,
+ 0x6E3,
+ 0x9B3,
+ 0xB66,
+ 0xECC,
+ 0x1ED,
+ 0x3DA,
+ 0x7B4,
+ 0xB1D,
+ 0xE3A,
+};
+
+static const guint golay_decode_matrix[12] = {
+ 0x49F,
+ 0x93E,
+ 0x6E3,
+ 0xDC6,
+ 0xF13,
+ 0xAB9,
+ 0x1ED,
+ 0x3DA,
+ 0x7B4,
+ 0xF68,
+ 0xA4F,
+ 0xC75,
+};
+
+
+
+/* Function to compute the Hamming weight of a 12-bit integer */
+static guint weight12(guint vector)
+{
+ guint w=0;
+ guint i;
+ for( i=0; i<12; i++ )
+ if( vector & 1<<i )
+ w++;
+ return w;
+}
+
+/* returns the golay coding of the given 12-bit word */
+static guint golay_coding(guint w)
+{
+ guint out=0;
+ guint i;
+
+ for( i = 0; i<12; i++ ) {
+ if( w & 1<<i )
+ out ^= golay_encode_matrix[i];
+ }
+ return out;
+}
+
+/* encodes a 12-bit word to a 24-bit codeword */
+guint32 golay_encode(guint w)
+{
+ return ((guint32)w) | ((guint32)golay_coding(w))<<12;
+}
+
+
+
+/* returns the golay coding of the given 12-bit word */
+static guint golay_decoding(guint w)
+{
+ guint out=0;
+ guint i;
+
+ for( i = 0; i<12; i++ ) {
+ if( w & 1<<(i) )
+ out ^= golay_decode_matrix[i];
+ }
+ return out;
+}
+
+
+/* return a mask showing the bits which are in error in a received
+ * 24-bit codeword, or -1 if 4 errors were detected.
+ */
+gint32 golay_errors(guint32 codeword)
+{
+ guint received_data, received_parity;
+ guint syndrome;
+ guint w,i;
+ guint inv_syndrome = 0;
+
+ received_parity = (guint)(codeword>>12);
+ received_data = (guint)codeword & 0xfff;
+
+ /* We use the C notation ^ for XOR to represent addition modulo 2.
+ *
+ * Model the received codeword (r) as the transmitted codeword (u)
+ * plus an error vector (e).
+ *
+ * r = e ^ u
+ *
+ * Then we calculate a syndrome (s):
+ *
+ * s = r * H, where H = [ P ], where I12 is the identity matrix
+ * [ I12 ]
+ *
+ * (In other words, we calculate the parity check for the received
+ * data bits, and add them to the received parity bits)
+ */
+
+ syndrome = received_parity ^ (golay_coding(received_data));
+ w = weight12(syndrome);
+
+ /*
+ * The properties of the golay code are such that the Hamming distance (ie,
+ * the minimum distance between codewords) is 8; that means that one bit of
+ * error in the data bits will cause 7 errors in the parity bits.
+ *
+ * In particular, if we find 3 or fewer errors in the parity bits, either:
+ * - there are no errors in the data bits, or
+ * - there are at least 5 errors in the data bits
+ * we hope for the former (we don't profess to deal with the
+ * latter).
+ */
+ if( w <= 3 ) {
+ return ((gint32) syndrome)<<12;
+ }
+
+ /* the next thing to try is one error in the data bits.
+ * we try each bit in turn and see if an error in that bit would have given
+ * us anything like the parity bits we got. At this point, we tolerate two
+ * errors in the parity bits, but three or more errors would give a total
+ * error weight of 4 or more, which means it's actually uncorrectable or
+ * closer to another codeword. */
+
+ for( i = 0; i<12; i++ ) {
+ guint error = 1<<i;
+ guint coding_error = golay_encode_matrix[i];
+ if( weight12(syndrome^coding_error) <= 2 ) {
+ return (gint32)((((guint32)(syndrome^coding_error))<<12) | (guint32)error) ;
+ }
+ }
+
+ /* okay then, let's see whether the parity bits are error free, and all the
+ * errors are in the data bits. model this as follows:
+ *
+ * [r | pr] = [u | pu] + [e | 0]
+ *
+ * pr = pu
+ * pu = H * u => u = H' * pu = H' * pr , where H' is inverse of H
+ *
+ * we already have s = H*r + pr, so pr = s - H*r = s ^ H*r
+ * e = u ^ r
+ * = (H' * ( s ^ H*r )) ^ r
+ * = H'*s ^ r ^ r
+ * = H'*s
+ *
+ * Once again, we accept up to three error bits...
+ */
+
+ inv_syndrome = golay_decoding(syndrome);
+ w = weight12(inv_syndrome);
+ if( w <=3 ) {
+ return (gint32)inv_syndrome;
+ }
+
+ /* Final shot: try with 2 errors in the data bits, and 1 in the parity
+ * bits; as before we try each of the bits in the parity in turn */
+ for( i = 0; i<12; i++ ) {
+ guint error = 1<<i;
+ guint coding_error = golay_decode_matrix[i];
+ if( weight12(inv_syndrome^coding_error) <= 2 ) {
+ guint32 error_word = ((guint32)(inv_syndrome^coding_error)) | ((guint32)error)<<12;
+ return (gint32)error_word;
+ }
+ }
+
+ /* uncorrectable error */
+ return -1;
+}
+
+
+
+/* decode a received codeword. Up to 3 errors are corrected for; 4
+ errors are detected as uncorrectable (return -1); 5 or more errors
+ cause an incorrect correction.
+*/
+gint golay_decode(guint32 w)
+{
+ guint data = (guint)w & 0xfff;
+ gint32 errors = golay_errors(w);
+ guint data_errors;
+
+ if( errors == -1 )
+ return -1;
+ data_errors = (guint)errors & 0xfff;
+ return (gint)(data ^ data_errors);
+}
--- plugins/h223/golay.h 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/golay.h 2004-05-24 12:38:55.000000000 +0100
@@ -0,0 +1,49 @@
+/* $Id: golay.h,v 1.1 2004/05/24 11:38:55 richardv Exp $
+ *
+ * Provides routines for encoding and decoding the extended Golay
+ * (24,12,8) code.
+ *
+ * This implementation will detect up to 4 errors in a codeword (without
+ * being able to correct them); it will correct up to 3 errors.
+ *
+ * We use guint32s to hold the 24-bit codewords, with the data part in
+ * the bottom 12 bits and the parity in bits 12-23.
+ *
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __GOLAY_H__
+#define __GOLAY_H__
+
+/* encodes a 12-bit word to a 24-bit codeword
+ */
+guint32 golay_encode(guint w);
+
+/* return a mask showing the bits which are in error in a received
+ * 24-bit codeword, or -1 if 4 errors were detected.
+ */
+gint32 golay_errors(guint32 codeword);
+
+/* decode a received codeword. Up to 3 errors are corrected for; 4
+ errors are detected as uncorrectable (return -1); 5 or more errors
+ cause an incorrect correction.
+*/
+gint golay_decode(guint32 w);
+
+#endif
--- epan/address.h 2005-09-29 16:07:07.482222592 +0100
+++ epan/address.h 2005-09-29 17:30:11.279570232 +0100
@@ -2,7 +2,7 @@
* Definitions for structures storing addresses, and for the type of
* variables holding port-type values
*
- * $Id: address.h,v 1.1.1.4 2005/09/29 13:18:52 jeff Exp $
+ * $Id: address.h,v 1.5 2005/09/29 15:51:24 jeff Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxxxx>
@@ -126,7 +126,8 @@
CT_ISDN, /* ISDN channel number */
CT_X25, /* X.25 logical channel number */
CT_ISUP, /* ISDN User Part CIC */
- CT_IAX2 /* IAX2 call id */
+ CT_IAX2, /* IAX2 call id */
+ CT_H223 /* H.223 logical channel number */
/* Could also have ATM VPI/VCI pairs */
} circuit_type;
--- plugins/h223/packet-h223.c 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/packet-h223.c 2005-09-30 11:46:09.459807328 +0100
@@ -0,0 +1,1423 @@
+/* packet-h223.c
+ * Routines for H.223 packet dissection
+ * Copyright (c) 2004-5 MX Telecom Ltd <richardv@xxxxxxxxxxxxx>
+ *
+ * $Id: packet-h223.c,v 1.34 2005/09/30 10:40:16 jeff Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <execinfo.h>
+
+#include <gmodule.h>
+#include <glib.h>
+#include <epan/emem.h>
+#include <epan/bitswap.h>
+#include <epan/circuit.h>
+#include <epan/conversation.h>
+#include <epan/packet.h>
+#include <epan/stream.h>
+#include <epan/reassemble.h>
+#include <epan/iax2_codec_type.h>
+#include <epan/dissectors/packet-frame.h>
+#include <epan/dissectors/packet-h245.h>
+
+#include "packet-h223.h"
+#include "golay.h"
+
+#include <string.h>
+
+#define PROTO_TAG_H223 "H223"
+
+/* Ethereal ID of the H.223 protocol */
+static int proto_h223 = -1;
+
+/* The following hf_* variables are used to hold the ethereal IDs of
+ * our header fields; they are filled out when we call
+ * proto_register_field_array() in proto_register_h223()
+ */
+static int hf_h223_non_h223_data = -1;
+static int hf_h223_mux_stuffing_pdu = -1;
+static int hf_h223_mux_pdu = -1;
+static int hf_h223_mux_header = -1;
+static int hf_h223_mux_rawhdr = -1;
+static int hf_h223_mux_correctedhdr = -1;
+static int hf_h223_mux_mc = -1;
+static int hf_h223_mux_mpl = -1;
+static int hf_h223_mux_deact = -1;
+static int hf_h223_mux_vc = -1;
+static int hf_h223_mux_extra = -1;
+static int hf_h223_mux_hdlc2 = -1;
+static int hf_h223_mux_fragments = -1;
+static int hf_h223_mux_fragment = -1;
+static int hf_h223_mux_fragment_overlap = -1;
+static int hf_h223_mux_fragment_overlap_conflict = -1;
+static int hf_h223_mux_fragment_multiple_tails = -1;
+static int hf_h223_mux_fragment_too_long_fragment = -1;
+static int hf_h223_mux_fragment_error = -1;
+static int hf_h223_mux_reassembled_in = -1;
+
+static int hf_h223_al_fragments = -1;
+static int hf_h223_al_fragment = -1;
+static int hf_h223_al_fragment_overlap = -1;
+static int hf_h223_al_fragment_overlap_conflict = -1;
+static int hf_h223_al_fragment_multiple_tails = -1;
+static int hf_h223_al_fragment_too_long_fragment = -1;
+static int hf_h223_al_fragment_error = -1;
+static int hf_h223_al_reassembled_in = -1;
+
+static int hf_h223_al1 = -1;
+static int hf_h223_al1_framed = -1;
+static int hf_h223_al2 = -1;
+static int hf_h223_al2_sequenced = -1;
+static int hf_h223_al2_seqno = -1;
+static int hf_h223_al2_crc = -1;
+static int hf_h223_al2_crc_bad = -1;
+
+static int hf_h223_al_payload = -1;
+
+/* These are the ids of the subtrees that we may be creating */
+static gint ett_h223 = -1;
+static gint ett_h223_non_h223_data = -1;
+static gint ett_h223_mux_stuffing_pdu = -1;
+static gint ett_h223_mux_pdu = -1;
+static gint ett_h223_mux_header = -1;
+static gint ett_h223_mux_deact = -1;
+static gint ett_h223_mux_vc = -1;
+static gint ett_h223_mux_extra = -1;
+static gint ett_h223_mux_fragments = -1;
+static gint ett_h223_mux_fragment = -1;
+static gint ett_h223_al_fragments = -1;
+static gint ett_h223_al_fragment = -1;
+static gint ett_h223_al1 = -1;
+static gint ett_h223_al2 = -1;
+static gint ett_h223_al_payload = -1;
+
+/* These are the handles of our subdissectors */
+static dissector_handle_t data_handle=NULL;
+static dissector_handle_t srp_handle=NULL;
+static dissector_handle_t h245dg_handle=NULL;
+
+static const fragment_items h223_mux_frag_items = {
+ &ett_h223_mux_fragment,
+ &ett_h223_mux_fragments,
+ &hf_h223_mux_fragments,
+ &hf_h223_mux_fragment,
+ &hf_h223_mux_fragment_overlap,
+ &hf_h223_mux_fragment_overlap_conflict,
+ &hf_h223_mux_fragment_multiple_tails,
+ &hf_h223_mux_fragment_too_long_fragment,
+ &hf_h223_mux_fragment_error,
+ &hf_h223_mux_reassembled_in,
+ "fragments"
+};
+
+static const fragment_items h223_al_frag_items = {
+ &ett_h223_al_fragment,
+ &ett_h223_al_fragments,
+ &hf_h223_al_fragments,
+ &hf_h223_al_fragment,
+ &hf_h223_al_fragment_overlap,
+ &hf_h223_al_fragment_overlap_conflict,
+ &hf_h223_al_fragment_multiple_tails,
+ &hf_h223_al_fragment_too_long_fragment,
+ &hf_h223_al_fragment_error,
+ &hf_h223_al_reassembled_in,
+ "fragments"
+};
+
+static guint32 pdu_offset; // offset of the last pdu to start being dissected in the last packet to start being dissected
+
+/***************************************************************************
+ *
+ * virtual circuit number handling
+ *
+ * we have to be able to manage more than one H.223 call at a time,
+ * so have a hash which maps {call,vc} to an integer.
+ */
+
+typedef struct _h223_call_info h223_call_info;
+
+typedef struct {
+ const h223_call_info* call; /* h223 call */
+ guint32 vc; /* child circuit */
+} circuit_chain_key;
+
+static GHashTable *circuit_chain_hashtable = NULL;
+static guint circuit_chain_count = 1;
+
+/* Hash Functions */
+static gint circuit_chain_equal(gconstpointer v, gconstpointer w)
+{
+ const circuit_chain_key *v1 = (const circuit_chain_key *)v;
+ const circuit_chain_key *v2 = (const circuit_chain_key *)w;
+ gint result;
+ result = ( v1->call == v2->call &&
+ v1->vc == v2 -> vc );
+ return result;;
+}
+
+static guint circuit_chain_hash (gconstpointer v)
+{
+ const circuit_chain_key *key = (const circuit_chain_key *)v;
+ guint hash_val = ((guint32)(key->call))^(((guint32)key->vc) << 16);
+ return hash_val;
+}
+
+static guint32 circuit_chain_lookup(const h223_call_info* call_info,
+ guint32 child_vc)
+{
+ circuit_chain_key key, *new_key;
+ guint32 circuit_id;
+ key.call = call_info;
+ key.vc = child_vc;
+ circuit_id = GPOINTER_TO_UINT(g_hash_table_lookup( circuit_chain_hashtable, &key ));
+ if( circuit_id == 0 ) {
+ new_key = se_alloc(sizeof(circuit_chain_key));
+ *new_key = key;
+ circuit_id = ++circuit_chain_count;
+ g_hash_table_insert(circuit_chain_hashtable, new_key, GUINT_TO_POINTER(circuit_id));
+ }
+ return circuit_id;
+}
+
+static void circuit_chain_init(void)
+{
+ if (circuit_chain_hashtable)
+ g_hash_table_destroy(circuit_chain_hashtable);
+ circuit_chain_hashtable = g_hash_table_new(circuit_chain_hash, circuit_chain_equal);
+ circuit_chain_count = 1;
+}
+
+
+/***************************************************************************
+ *
+ * Call information management
+ *
+ */
+
+/* we keep information on each call in an h223_call_info structure
+ *
+ * We attach the h223_call_info structures to individual calls with
+ * circuit_add_proto_data().
+*/
+
+typedef struct _h223_mux_element_listitem h223_mux_element_listitem;
+struct _h223_mux_element_listitem {
+ h223_mux_element *me;
+ guint32 first_frame;
+ guint32 pdu_offset;
+ h223_mux_element_listitem *next;
+};
+
+/* we have this information for each stream */
+typedef struct {
+ gboolean current_pdu_header_parsed;
+
+ guint32 current_pdu_minlen;
+ guint32 current_pdu_read;
+
+ guint32 header_buf;
+ guint32 tail_buf;
+
+ gboolean first_pdu;
+
+ h223_mux_element_listitem* mux_table[16];
+} h223_call_direction_data;
+
+
+struct _h223_call_info {
+ /* H.223 specifies that the least-significant bit is transmitted first;
+ however this is at odds with IAX which transmits the MSB first, so
+ in general, all of our bytes are reversed. */
+ gboolean bitswapped;
+
+ /* H.223 level: 0 for standard H223, 1, 2 or 3 for the enhanced protocols
+ specified in the annexes
+ */
+ int h223_level;
+
+ /* for H.223 streams over TCP (as opposed to IAX), this
+ stores the source address and port of the first packet spotted,
+ so that we can differentiate directions.
+ */
+ address srcaddress;
+ guint32 srcport;
+
+ h223_call_direction_data direction_data[2];
+};
+
+typedef struct _h223_lc_params_listitem h223_lc_params_listitem;
+struct _h223_lc_params_listitem
+{
+ h223_lc_params *lc_params;
+ guint32 first_frame;
+ guint32 last_frame;
+ h223_lc_params_listitem *next;
+};
+
+typedef struct {
+ h223_lc_params_listitem *lc_params[2];
+ h223_call_info *call_info;
+} h223_vc_info;
+
+static void add_h223_mux_element(h223_call_direction_data *direct, guint8 mc, h223_mux_element *me, guint32 framenum)
+{
+ h223_mux_element_listitem *li = se_alloc(sizeof(h223_mux_element_listitem));
+ h223_mux_element_listitem **old_li_ptr = &(direct->mux_table[mc]);
+ h223_mux_element_listitem *old_li = *old_li_ptr;
+ if( !old_li ) {
+ direct->mux_table[mc] = li;
+ } else {
+ while( old_li->next ) {
+ old_li_ptr = &(old_li->next);
+ old_li = *old_li_ptr;
+ }
+ if( framenum < old_li->first_frame || (framenum == old_li->first_frame && pdu_offset < old_li->pdu_offset) )
+ return;
+ else if ( framenum == old_li->first_frame && pdu_offset == old_li->pdu_offset )
+ *old_li_ptr = li; // replace the tail of the list with the new item, since
+ // a single h223 pdu has just set the same MC twice..
+ else
+ old_li->next = li;
+ }
+ li->first_frame = framenum;
+ li->pdu_offset = pdu_offset;
+ li->next = 0;
+ li->me = me;
+}
+
+static h223_mux_element* find_h223_mux_element(h223_call_direction_data* direct, guint8 mc, guint32 framenum)
+{
+ h223_mux_element_listitem* li = direct->mux_table[mc];
+ while( li && li->next && li->next->first_frame < framenum )
+ li = li->next;
+ while( li && li->next && li->next->first_frame == framenum && li->next->pdu_offset < pdu_offset )
+ li = li->next;
+ if( li ) {
+ return li->me;
+ } else {
+ return NULL;
+ }
+}
+
+static void add_h223_lc_params(h223_vc_info* vc_info, int direction, h223_lc_params *lc_params, guint32 framenum )
+{
+ h223_lc_params_listitem *li = se_alloc(sizeof(h223_lc_params_listitem));
+ h223_lc_params_listitem **old_li_ptr = &(vc_info->lc_params[direction]);
+ h223_lc_params_listitem *old_li = *old_li_ptr;
+ if( !old_li ) {
+ vc_info->lc_params[direction] = li;
+ } else {
+ while( old_li->next ) {
+ old_li_ptr = &(old_li->next);
+ old_li = *old_li_ptr;
+ }
+ if( framenum < old_li->first_frame )
+ return;
+ else if( framenum == old_li->first_frame )
+ *old_li_ptr = li;
+ else {
+ old_li->next = li;
+ old_li->last_frame = framenum - 1;
+ }
+ }
+ li->first_frame = framenum;
+ li->last_frame = 0;
+ li->next = 0;
+ li->lc_params = lc_params;
+}
+
+static h223_lc_params* find_h223_lc_params(h223_vc_info* vc_info, int direction, guint32 framenum)
+{
+ h223_lc_params_listitem* li = vc_info->lc_params[direction];
+ while( li && li->next && li->next->first_frame <= framenum )
+ li = li->next;
+ if( li )
+ return li->lc_params;
+ else
+ return NULL;
+}
+
+static void init_direction_data(h223_call_direction_data *direct)
+{
+ int i;
+
+ direct -> first_pdu = TRUE;
+
+ for ( i = 0; i < 16; ++i )
+ direct->mux_table[i] = NULL;
+
+ /* set up MC 0 to contain just VC 0 */
+ h223_mux_element *mc0_element = se_alloc(sizeof(h223_mux_element));
+ add_h223_mux_element( direct, 0, mc0_element, 0 );
+ mc0_element->sublist = NULL;
+ mc0_element->vc = 0;
+ mc0_element->repeat_count = 0; /* until closing flag */
+ mc0_element->next = NULL;
+}
+
+static h223_vc_info* h223_vc_info_new( h223_call_info* call_info )
+{
+ h223_vc_info *vc_info = se_alloc(sizeof(h223_vc_info));
+ vc_info->lc_params[0] = vc_info->lc_params[1] = NULL;
+ vc_info->call_info = call_info;
+ return vc_info;
+}
+
+static void init_logical_channel( packet_info* pinfo, h223_call_info* call_info, int vc, int direction, h223_lc_params* params )
+{
+ guint32 circuit_id = circuit_chain_lookup(call_info, vc);
+ circuit_t *subcircuit;
+ h223_vc_info *vc_info;
+ subcircuit = find_circuit( CT_H223, circuit_id, pinfo->fd->num );
+
+ if( subcircuit == NULL ) {
+ subcircuit = circuit_new( CT_H223, circuit_id, pinfo->fd->num );
+ vc_info = h223_vc_info_new( call_info );
+ circuit_add_proto_data( subcircuit, proto_h223, vc_info );
+ } else {
+ vc_info = circuit_get_proto_data( subcircuit, proto_h223 );
+ }
+ add_h223_lc_params( vc_info, direction, params, pinfo->fd->num );
+}
+
+static void init_control_channels( packet_info* pinfo, h223_call_info* call_info )
+{
+ h223_lc_params *vc0_params = se_alloc(sizeof(h223_lc_params));
+ vc0_params->al_type = al1Framed;
+ vc0_params->al_params = NULL;
+ vc0_params->segmentable = TRUE;
+ vc0_params->subdissector = srp_handle;
+ init_logical_channel( pinfo, call_info, 0, P2P_DIR_SENT, vc0_params );
+ init_logical_channel( pinfo, call_info, 0, P2P_DIR_RECV, vc0_params );
+}
+
+static h223_call_info *find_or_create_call_info ( packet_info * pinfo )
+{
+ circuit_t *circ;
+ conversation_t *conv = NULL;
+ h223_call_info *data;
+
+ // look for a circuit (eg, IAX call) first
+ circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
+ if( circ == NULL ) {
+ // assume we're running atop TCP; use the converstion support
+ conv = find_conversation( pinfo->fd->num,
+ &pinfo->src,&pinfo->dst,
+ pinfo->ptype,
+ pinfo->srcport,pinfo->destport, 0 );
+ if( conv == NULL ) {
+ conv = conversation_new( pinfo->fd->num,
+ &pinfo->src,&pinfo->dst,
+ pinfo->ptype,
+ pinfo->srcport,pinfo->destport, 0 );
+ }
+
+ }
+
+ if( circ )
+ data = (h223_call_info *)circuit_get_proto_data(circ, proto_h223);
+ else
+ data = (h223_call_info *)conversation_get_proto_data(conv, proto_h223);
+
+ if( data == NULL ) {
+ data = se_alloc(sizeof(h223_call_info));
+
+ if( circ ) {
+ circuit_add_proto_data(circ, proto_h223, data);
+
+ /* circuit-switched H.223 conversations are bitswapped */
+ data -> bitswapped = TRUE;
+ } else {
+ conversation_add_proto_data(conv, proto_h223, data);
+ /* add the source details so we can distinguish directions
+ * in future */
+ COPY_ADDRESS(&(data -> srcaddress), &(pinfo->src));
+ data -> srcport = pinfo->srcport;
+
+ /* packet-switched H.223 conversations are NOT bitswapped */
+ data -> bitswapped = FALSE;
+ }
+
+ /* initialise the call info */
+ init_direction_data(&data -> direction_data[0]);
+ init_direction_data(&data -> direction_data[1]);
+
+ /* FIXME shouldn't this be figured out dynamically? */
+ data -> h223_level = 2;
+
+ init_control_channels( pinfo, data );
+ }
+
+ /* work out what direction we're really going in */
+ if( circ ) {
+ if( pinfo->p2p_dir < 0 || pinfo->p2p_dir > 1)
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ } else {
+ if( ADDRESSES_EQUAL( &(pinfo->src), &(data->srcaddress))
+ && pinfo->srcport == data->srcport )
+ pinfo->p2p_dir = P2P_DIR_SENT;
+ else
+ pinfo->p2p_dir = P2P_DIR_RECV;
+ }
+
+ return data;
+}
+
+void h223_set_mc( packet_info* pinfo, guint8 mc, h223_mux_element* me )
+{
+ circuit_t *circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
+ h223_vc_info* vc_info;
+ g_assert( circ );
+ vc_info = circuit_get_proto_data(circ, proto_h223);
+ add_h223_mux_element( &(vc_info->call_info->direction_data[pinfo->p2p_dir]), mc, me, pinfo->fd->num );
+}
+
+void h223_add_lc( packet_info* pinfo, guint16 lc, h223_lc_params* params )
+{
+ circuit_t *circ = find_circuit( pinfo->ctype, pinfo->circuit_id, pinfo->fd->num );
+ h223_vc_info* vc_info;
+ g_assert( circ );
+ vc_info = circuit_get_proto_data(circ, proto_h223);
+ init_logical_channel( pinfo, vc_info->call_info, lc, pinfo->p2p_dir, params );
+}
+
+/************************************************************************************
+ *
+ * AL-PDU dissection
+ */
+
+char crctable[256] = {
+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf };
+
+static guint8 h223_al2_crc8bit( tvbuff_t *tvb ) {
+ guint32 len = tvb_reported_length(tvb) - 1;
+ const guint8* data = tvb_get_ptr( tvb, 0, len );
+ unsigned char crc = 0;
+ guint32 pos = 0;
+ while ( len-- )
+ crc = crctable[crc^data[pos++]];
+ return crc;
+}
+
+static void dissect_mux_al_pdu( tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *vc_tree,
+// circuit_t* vc_circuit,
+ h223_lc_params* lc_params )
+{
+ proto_tree *al_tree = NULL;
+ proto_item *al_item;
+ proto_tree *al_subtree;
+ proto_item *al_subitem = NULL;
+ tvbuff_t *next_tvb = NULL;
+ dissector_handle_t subdissector = lc_params->subdissector;
+ guint32 len = tvb_reported_length(tvb);
+ gboolean all_done = FALSE;
+
+ guint8 calc_checksum;
+ guint8 real_checksum;
+ gboolean al2_sequenced;
+
+ switch( lc_params->al_type ) {
+ case al1Framed:
+ case al1NotFramed:
+ al_item = proto_tree_add_none_format(vc_tree, hf_h223_al1, tvb, 0, -1, "H.223 AL1 (%sframed)",
+ (lc_params->al_type==al1Framed)?"":"not ");
+ al_tree = proto_item_add_subtree (al_item, ett_h223_al1);
+ if(lc_params->al_type == al1Framed)
+ proto_tree_add_boolean_hidden(al_tree, hf_h223_al1_framed, tvb, 0, 1, TRUE );
+ next_tvb = tvb;
+ break;
+ case al2WithoutSequenceNumbers:
+ case al2WithSequenceNumbers:
+ if( lc_params->al_type == al2WithoutSequenceNumbers ) {
+ next_tvb = tvb_new_subset( tvb, 0, len-1, len-1 );
+ al2_sequenced = FALSE;
+ } else {
+ next_tvb = tvb_new_subset( tvb, 1, len-2, len-2 );
+ al2_sequenced = TRUE;
+ }
+
+ al_item = proto_tree_add_none_format(vc_tree, hf_h223_al2, tvb, 0, -1, "H223 AL2 (with%s sequence numbers)",
+ al2_sequenced?"":"out" );
+ al_tree = proto_item_add_subtree (al_item, ett_h223_al2);
+
+ if( al2_sequenced ) {
+ proto_tree_add_boolean_hidden(al_tree, hf_h223_al2_sequenced, tvb, 0, 1, TRUE );
+ proto_tree_add_uint_format(al_tree, hf_h223_al2_seqno, tvb, 0, 1, tvb_get_guint8( tvb, 0 ),
+ "Sequence number: %u", tvb_get_guint8( tvb, 0 ) );
+ }
+
+ calc_checksum = h223_al2_crc8bit(tvb);
+ real_checksum = tvb_get_guint8(tvb, len - 1);
+ if( calc_checksum == real_checksum ) {
+ al_subitem = proto_tree_add_item(al_tree, hf_h223_al_payload, next_tvb, 0, -1, FALSE);
+ proto_tree_add_uint_format(al_tree, hf_h223_al2_crc, tvb, len - 1, 1, real_checksum,
+ "CRC: 0x%02x (correct)", real_checksum );
+ } else {
+ call_dissector(data_handle, tvb, pinfo, al_tree);
+ proto_tree_add_boolean_hidden( al_tree, hf_h223_al2_crc_bad, tvb, len - 1, 1, TRUE );
+ proto_tree_add_uint_format(al_tree, hf_h223_al2_crc, tvb, len - 1, 1, real_checksum,
+ "CRC: 0x%02x (incorrect, should be 0x%02x)", real_checksum, calc_checksum );
+ all_done = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!subdissector)
+ subdissector = data_handle;
+
+ if(next_tvb && al_tree && !al_subitem && !all_done)
+ al_subitem = proto_tree_add_item(al_tree, hf_h223_al_payload, next_tvb, 0, -1, FALSE);
+
+ if(next_tvb && al_subitem && !all_done) {
+ al_subtree = proto_item_add_subtree(al_subitem, ett_h223_al_payload);
+ call_dissector(subdissector, next_tvb, pinfo, al_subtree);
+ } else if ( !all_done )
+ call_dissector(data_handle, tvb, pinfo, vc_tree);
+}
+
+/************************************************************************************
+ *
+ * MUX-PDU dissection
+ */
+
+
+/* dissect a fragment of a MUX-PDU which belongs to a particular VC
+ *
+ * tvb buffer containing the whole MUX-PDU
+ * offset offset within the MUX-PDU of this fragment
+ * pinfo info on the packet containing the last fragment of the MUX-PDU
+ * pkt_offset offset within that packet of the start of the final fragment of
+ * the MUX_PDU
+ * pdu_tree dissection tree for the PDU; a single item will be added (with
+ * its own subtree)
+ * vc VC for this SDU
+ * frag_len length of the MUX-SDU fragment
+ * end_of_mux_sdu true if this is a segmentable VC and this is the last
+ * fragment in an SDU
+ */
+static void dissect_mux_sdu_fragment(tvbuff_t *tvb, guint32 offset,
+ packet_info *pinfo,
+ guint32 pkt_offset,
+ proto_tree *pdu_tree,
+ h223_call_info* call_info,
+ guint16 vc, gint frag_len, gboolean end_of_mux_sdu)
+{
+ /* update the circuit details before passing to a subdissector */
+ guint32 orig_circuit = pinfo->circuit_id;
+ guint32 orig_ctype = pinfo->ctype;
+ pinfo->circuit_id=circuit_chain_lookup(call_info, vc);
+ pinfo->ctype=CT_H223;
+
+ TRY {
+ tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, frag_len, frag_len);
+ circuit_t *subcircuit=find_circuit(pinfo->ctype,pinfo->circuit_id,pinfo->fd->num);
+ dissector_handle_t subdissector = NULL;
+ proto_tree *vc_tree = NULL;
+ proto_item *vc_item;
+ h223_vc_info *vc_info = NULL;
+ h223_lc_params *lc_params = NULL;
+ gboolean stuffing = ( vc == 0 && frag_len == 0 );
+
+ if(pdu_tree && !stuffing) {
+ vc_item = proto_tree_add_uint(pdu_tree, hf_h223_mux_vc, next_tvb, 0, frag_len, vc);
+ vc_tree = proto_item_add_subtree (vc_item, ett_h223_mux_vc);
+ }
+
+ if( stuffing ) {
+ next_tvb = NULL;
+ subdissector = data_handle;
+ } else if( subcircuit == NULL ) {
+ g_message( "Frame %d: no subcircuit id %d found for circuit %d id %d, vc %d", pinfo->fd->num,
+ pinfo->circuit_id, orig_ctype, orig_circuit, vc );
+ subdissector = data_handle;
+ } else {
+ vc_info = circuit_get_proto_data(subcircuit, proto_h223);
+ if( vc_info != NULL ) {
+ lc_params = find_h223_lc_params( vc_info, pinfo->p2p_dir, pinfo->fd->num );
+ }
+ if( lc_params == NULL ) {
+ subdissector = data_handle;
+ } else {
+ if( lc_params->segmentable && lc_params->al_type != al1NotFramed ) {
+ stream_t *substream;
+ stream_pdu_fragment_t *frag;
+
+ substream = find_stream_circ(subcircuit,pinfo->p2p_dir);
+ if(substream == NULL )
+ substream = stream_new_circ(subcircuit,pinfo->p2p_dir);
+ frag = stream_find_frag(substream,pinfo->fd->num,offset+pkt_offset);
+ if(frag == NULL ) {
+ frag = stream_add_frag(substream,pinfo->fd->num,offset+pkt_offset,
+ next_tvb,pinfo,!end_of_mux_sdu);
+ }
+ next_tvb = stream_process_reassembled(
+ next_tvb, 0, pinfo,
+ "Reassembled H.223 AL-PDU",
+ frag, &h223_al_frag_items,
+ NULL, vc_tree);
+ }
+ }
+ }
+
+ if(next_tvb) {
+ if(lc_params)
+ dissect_mux_al_pdu(next_tvb, pinfo, vc_tree,/* subcircuit,*/ lc_params );
+ else
+ call_dissector(subdissector,next_tvb,pinfo,vc_tree);
+ }
+ }
+
+ /* restore the original circuit details for future PDUs */
+ FINALLY {
+ pinfo->ctype=orig_ctype;
+ pinfo->circuit_id=orig_circuit;
+ }
+ ENDTRY;
+}
+
+static guint32 mux_element_sublist_size( h223_mux_element* me )
+{
+ h223_mux_element *current_me = me;
+ guint32 length = 0;
+ while ( current_me ) {
+ current_me = current_me->next;
+ if ( current_me->sublist )
+ length += current_me->repeat_count * mux_element_sublist_size( current_me->sublist );
+ else
+ length += current_me->repeat_count;
+ }
+ if ( length == 0 ) { /* should never happen, but to avoid infinite loops... */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ length = 1;
+ }
+ return length;
+}
+
+static guint32 dissect_mux_payload_by_me_list( tvbuff_t *tvb, packet_info *pinfo, guint32 pkt_offset, proto_tree *pdu_tree,
+ h223_call_info* call_info, h223_mux_element* me, guint32 offset, gboolean endOfMuxSdu )
+{
+ guint32 len = tvb_reported_length(tvb);
+ guint32 frag_len;
+ guint32 sublist_len;
+ int i;
+ while ( me ) {
+ if ( me->sublist ) {
+ if ( me->repeat_count == 0 ) {
+ for(sublist_len = mux_element_sublist_size( me->sublist );
+ offset + sublist_len <= len;
+ offset = dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree,
+ call_info, me->sublist, offset, endOfMuxSdu ) );
+ } else {
+ for(i = 0; i < me->repeat_count; ++i)
+ offset = dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree,
+ call_info, me->sublist, offset, endOfMuxSdu );
+ }
+ } else {
+ if ( me->repeat_count == 0 )
+ frag_len = len - offset;
+ else
+ frag_len = me->repeat_count;
+ dissect_mux_sdu_fragment( tvb, offset, pinfo, pkt_offset, pdu_tree,
+ call_info, me->vc, frag_len, (offset+frag_len==len) && endOfMuxSdu);
+ offset += frag_len;
+ }
+ me = me->next;
+ }
+ return offset;
+}
+
+/* dissect the payload of a MUX-PDU */
+static void dissect_mux_payload( tvbuff_t *tvb, packet_info *pinfo, guint32 pkt_offset, proto_tree *pdu_tree,
+ h223_call_info* call_info, guint8 mc, gboolean endOfMuxSdu )
+{
+ guint32 len = tvb_reported_length(tvb);
+
+ h223_mux_element* me = find_h223_mux_element( &(call_info->direction_data[pinfo->p2p_dir]), mc, pinfo->fd->num );
+
+ if( me ) {
+ dissect_mux_payload_by_me_list( tvb, pinfo, pkt_offset, pdu_tree, call_info, me, 0, endOfMuxSdu );
+ } else {
+ /* no entry found in mux-table. ignore packet and dissect as data */
+ proto_tree *vc_tree = NULL;
+
+ if(pdu_tree) {
+ proto_item *vc_item = proto_tree_add_item(pdu_tree, hf_h223_mux_deact, tvb, 0, len, FALSE);
+ vc_tree = proto_item_add_subtree(vc_item, ett_h223_mux_deact);
+ }
+ call_dissector(data_handle,tvb,pinfo,vc_tree);
+ }
+}
+
+/* dissect a reassembled mux-pdu
+ *
+ * tvb buffer containing mux-pdu, including header and closing flag
+ * pinfo packet info for packet containing the end of the mux-pdu
+ * pkt_offset offset within that packet of the start of the last fragment
+ * h223_tree dissection tree for h223 protocol; a single item will be added
+ * (with a sub-tree)
+ * call_info h223 info structure for this h223 call
+ * pdu_no index of this pdu within the call
+ */
+static void dissect_mux_pdu( tvbuff_t *tvb, packet_info * pinfo,
+ guint32 pkt_offset,
+ proto_tree *h223_tree,
+ h223_call_info *call_info)
+{
+ guint32 offset = 0;
+ /* actual (as opposed to reported) payload len */
+ guint32 len;
+ guint32 raw_hdr = 0, correct_hdr = 0;
+ gint32 errors = 0;
+ guint16 closing_flag = 0;
+ guint8 mc = 0;
+ guint8 mpl = 0;
+ gboolean end_of_mux_sdu = FALSE;
+ tvbuff_t *pdu_tvb;
+
+ proto_item *pdu_item = NULL;
+ proto_tree *pdu_tree = NULL;
+
+ switch(call_info->h223_level) {
+ case 0: case 1:
+ raw_hdr = tvb_get_guint8(tvb,0);
+ mc = (guint8)((raw_hdr>>1) & 0xf);
+ end_of_mux_sdu = raw_hdr & 1;
+ offset++;
+ /* closing flag is one byte long for h223 level 0, two for level 1 */
+ len = mpl = tvb_length_remaining(tvb, offset)-(call_info->h223_level+1);
+
+ /* XXX should ignore pdus with incorrect HECs */
+ break;
+
+ case 2:
+ raw_hdr = tvb_get_letoh24(tvb,0);
+ errors = golay_errors(raw_hdr);
+ correct_hdr = ((errors == -1) ? raw_hdr : raw_hdr ^ (guint32)errors);
+
+ mc = (guint8)(correct_hdr & 0xf);
+ mpl = (guint8)((correct_hdr >> 4) & 0xff);
+
+ offset += 3;
+ len = tvb_length_remaining(tvb,offset)-2;
+ closing_flag = tvb_get_ntohs(tvb,offset+len);
+ end_of_mux_sdu = (closing_flag==(0xE14D ^ 0xFFFF));
+ break;
+
+ case 3:
+ /* XXX not implemented */
+ default:
+ len=0;
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+
+
+ if( h223_tree ) {
+ if( mpl == 0 ) {
+ pdu_item = proto_tree_add_item (h223_tree, hf_h223_mux_stuffing_pdu, tvb, 0, -1, FALSE);
+ pdu_tree = proto_item_add_subtree (pdu_item, ett_h223_mux_stuffing_pdu);
+ } else {
+ pdu_item = proto_tree_add_item (h223_tree, hf_h223_mux_pdu, tvb, 0, -1, FALSE);
+ pdu_tree = proto_item_add_subtree (pdu_item, ett_h223_mux_pdu);
+ }
+ }
+
+ if( pdu_tree ) {
+ proto_item *item = proto_tree_add_item (pdu_tree, hf_h223_mux_header, tvb, 0, offset, FALSE);
+ proto_tree *hdr_tree = proto_item_add_subtree (item, ett_h223_mux_header);
+
+ switch(call_info->h223_level) {
+ case 0: case 1:
+ proto_tree_add_uint(hdr_tree,hf_h223_mux_mc,tvb,0,1,mc);
+ break;
+
+ case 2:
+ if( errors == -1 ) {
+ proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
+ 0, 3, raw_hdr,
+ "Raw value: 0x%06x (uncorrectable errors)", raw_hdr );
+ } else if( errors == 0 ) {
+ proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
+ 0, 3, raw_hdr,
+ "Raw value: 0x%06x (correct)", raw_hdr );
+ } else {
+ proto_tree_add_uint_format(hdr_tree, hf_h223_mux_rawhdr, tvb,
+ 0, 3, raw_hdr,
+ "Raw value: 0x%06x (errors are 0x%06x)", raw_hdr, errors );
+ }
+ item = proto_tree_add_uint(hdr_tree,hf_h223_mux_correctedhdr,tvb,0,3,
+ correct_hdr);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ proto_tree_add_uint(hdr_tree,hf_h223_mux_mc,tvb,0,1,mc);
+ proto_tree_add_uint(hdr_tree,hf_h223_mux_mpl,tvb,0,2,mpl);
+ break;
+
+ case 3:
+ /* XXX not implemented */
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+ }
+
+ pdu_tvb = tvb_new_subset(tvb, offset, len, mpl);
+ dissect_mux_payload(pdu_tvb,pinfo,offset+pkt_offset,pdu_tree,call_info,mc,end_of_mux_sdu);
+ offset += mpl;
+
+ /* any extra data in the PDU, beyond that indictated by the mpl, is
+ dissected as data. */
+ len -= mpl;
+ if( len > 0 ) {
+ tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, len, len);
+ proto_tree *vc_tree = NULL;
+
+ if( pdu_tree ) {
+ proto_item *vc_item = proto_tree_add_item(pdu_tree, hf_h223_mux_extra, next_tvb, 0, len, FALSE);
+ vc_tree = proto_item_add_subtree(vc_item, ett_h223_mux_deact);
+ }
+ call_dissector(data_handle,next_tvb,pinfo,vc_tree);
+
+ offset += len;
+ }
+
+ /* add the closing HDLC flag */
+ if( pdu_tree )
+ proto_tree_add_item(pdu_tree,hf_h223_mux_hdlc2,tvb,offset,2,FALSE);
+}
+
+
+/************************************************************************************
+ *
+ * MUX-PDU delineation and defragmentation
+ */
+
+/* attempt to parse the header of a mux pdu */
+static void attempt_mux_level0_header_parse(h223_call_direction_data *dirdata)
+{
+ /* level 0 isn't byte-aligned, so is a complete pain to implement */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ dirdata = dirdata;
+}
+
+static void attempt_mux_level1_header_parse(h223_call_direction_data *dirdata)
+{
+ guint32 hdr;
+
+ if(dirdata->current_pdu_read != 2)
+ return;
+
+ hdr = dirdata->header_buf & 0xffff;
+ /* don't interpret a repeated hdlc as a header */
+ if(hdr == 0xE14D)
+ return;
+
+ /* + 1 byte of header and 2 bytes of closing HDLC */
+ dirdata -> current_pdu_minlen = (guint8)((hdr >> 12) & 0xff) + 3;
+ dirdata -> current_pdu_header_parsed = TRUE;
+}
+
+static void attempt_mux_level2_3_header_parse(h223_call_direction_data *dirdata)
+{
+ guint32 hdr;
+ gint32 errors;
+
+ if(dirdata->current_pdu_read != 3)
+ return;
+
+ /* + 3 bytes of header and 2 bytes of closing HDLC */
+ dirdata -> current_pdu_minlen = 5;
+
+ hdr = dirdata->header_buf;
+ hdr =
+ ((hdr & 0xFF0000) >> 16) |
+ (hdr & 0x00FF00) |
+ ((hdr & 0x0000FF) << 16);
+
+ errors = golay_errors(hdr);
+ if(errors != -1) {
+ hdr ^= errors;
+ dirdata -> current_pdu_minlen += ((hdr >> 4) & 0xff);
+ }
+
+ dirdata -> current_pdu_header_parsed = TRUE;
+}
+
+static void (* const attempt_mux_header_parse[])(h223_call_direction_data *dirdata) = {
+ attempt_mux_level0_header_parse,
+ attempt_mux_level1_header_parse,
+ attempt_mux_level2_3_header_parse,
+ attempt_mux_level2_3_header_parse
+};
+
+static gboolean h223_mux_check_hdlc(int h223_level, h223_call_direction_data *dirdata)
+{
+ guint32 masked;
+
+ switch(h223_level) {
+ case 0:
+ /* level 0 isn't byte-aligned, so is a complete pain to implement */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return FALSE;
+ break;
+
+ case 1:
+ masked = dirdata->tail_buf & 0xffff;
+ return masked == 0xE14D;
+
+ case 2: case 3:
+ masked = dirdata->tail_buf & 0xffff;
+ return masked == 0xE14D || masked == (0xE14D ^ 0xFFFF);
+
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return FALSE;
+ }
+}
+
+/* read a pdu (or the end of a pdu) from the tvb, and dissect it
+ *
+ * returns an offset to the next byte
+ *
+ * *pdu_found is set TRUE if a pdu was found, or FALSE if we reached the
+ * end of the tvb without completing one.
+ */
+
+static guint32 dissect_mux_pdu_fragment( tvbuff_t *tvb, guint32 start_offset, packet_info * pinfo,
+ guint32* pkt_offset,
+ proto_tree *tree,
+ proto_tree **h223_tree_p,
+ h223_call_info *call_info,
+ gboolean *pdu_found)
+{
+ proto_item *h223_item = NULL;
+ proto_tree *volatile h223_tree = *h223_tree_p;
+ tvbuff_t *volatile next_tvb;
+ volatile guint32 offset = start_offset;
+ gboolean more_frags = TRUE;
+ h223_call_direction_data *dirdata = &call_info -> direction_data[pinfo->p2p_dir];
+
+ dirdata -> current_pdu_read = 0;
+ dirdata -> current_pdu_minlen = 0;
+ dirdata -> current_pdu_header_parsed = FALSE;
+
+ while( more_frags && offset < tvb_reported_length( tvb )) {
+ guint8 byte = tvb_get_guint8(tvb, offset++);
+ dirdata -> current_pdu_read++;
+
+ /* read a byte into the header buf, if necessary */
+ if(dirdata -> current_pdu_read <= 4) {
+ dirdata -> header_buf <<= 8;
+ dirdata -> header_buf |= byte;
+ }
+
+ /* read the byte into the tail buf */
+ dirdata -> tail_buf <<= 8;
+ dirdata -> tail_buf |= byte;
+
+ /* if we haven't parsed the header yet, attempt to do so now */
+ if(!dirdata -> current_pdu_header_parsed)
+ /* this sets current_pdu_header parsed if current_pdu_read == 3 */
+ (attempt_mux_header_parse[call_info->h223_level])(dirdata);
+
+ if(dirdata -> current_pdu_read >= dirdata -> current_pdu_minlen) {
+ if(h223_mux_check_hdlc(call_info->h223_level,dirdata)) {
+ dirdata -> current_pdu_minlen = 0;
+ dirdata -> current_pdu_read = 0;
+ dirdata -> current_pdu_header_parsed = FALSE;
+ more_frags = FALSE;
+ }
+ }
+ }
+
+ if( more_frags ) {
+ /* offset = tvb_reported length now */
+ pinfo->desegment_offset = offset - dirdata->current_pdu_read;
+ if(dirdata->current_pdu_read > dirdata->current_pdu_minlen)
+ pinfo->desegment_len = 1;
+ else
+ pinfo->desegment_len = dirdata->current_pdu_minlen - dirdata->current_pdu_read;
+ return offset;
+ }
+
+ if(!*h223_tree_p) {
+ /* add the 'h223' tree to the main tree */
+ if (tree) {
+ h223_item = proto_tree_add_item (tree, proto_h223, tvb, 0, -1, FALSE);
+ h223_tree = proto_item_add_subtree (h223_item, ett_h223);
+ *h223_tree_p = h223_tree;
+ }
+ }
+ *pdu_found = TRUE;
+
+ /* create a tvb for the fragment */
+ next_tvb = tvb_new_subset(tvb, start_offset, offset-start_offset,
+ offset-start_offset);
+
+
+ *pkt_offset += tvb_reported_length( next_tvb );
+
+ /* the first PDU isn't real H.223 data. */
+ if( dirdata->first_pdu ) {
+ dirdata->first_pdu = FALSE;
+ proto_tree *pdu_tree = NULL;
+ if( h223_tree ) {
+ proto_item *pdu_item = proto_tree_add_item (h223_tree, hf_h223_non_h223_data, tvb, 0, -1, FALSE);
+ pdu_tree = proto_item_add_subtree (pdu_item, ett_h223_non_h223_data);
+ }
+ call_dissector(data_handle,tvb, pinfo, pdu_tree);
+ return offset;
+ }
+
+ /* we catch boundserrors on the pdu so that errors on an
+ * individual pdu don't screw up the whole of the rest of the
+ * stream */
+ pdu_offset = *pkt_offset - tvb_reported_length( next_tvb );
+ TRY {
+ dissect_mux_pdu( next_tvb, pinfo, *pkt_offset - tvb_reported_length( next_tvb ), h223_tree, call_info);
+ }
+
+ CATCH2(BoundsError,ReportedBoundsError) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO,
+ "[Malformed Packet]");
+ proto_tree_add_protocol_format(h223_tree, proto_malformed,
+ tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto);
+ }
+
+ ENDTRY;
+
+ return offset;
+}
+
+/************************************************************************************
+ *
+ * main dissector entry point
+ */
+
+static void dissect_h223 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+ proto_tree *h223_tree = NULL;
+ h223_call_info *call_info = NULL;
+ guint32 offset = 0;
+
+ /* pkt_offset becomes different from offset if we reassemble a pdu:
+ *
+ * before: offset = a, pkt_offset = b
+ * offset = dissect_h223_mux_pdu_fragment(ending fragment, offset, &pkt_offset)
+ * after: offset = a + sizeof(ending frament), pkt_offset = b + sizeof(reassembled pdu)
+ *
+ * This lets us get a value "pkt_offset + offset_into_pdu" which will never decrease
+ * as we walk through a packet
+ */
+ guint32 pkt_offset = 0;
+ gboolean pdu_found = FALSE;
+
+ if (check_col (pinfo->cinfo, COL_INFO))
+ col_clear (pinfo->cinfo, COL_INFO);
+
+
+ /* find or create the call_info for this call */
+ call_info = find_or_create_call_info(pinfo);
+
+ /* we may need to reverse the bit ordering before we go any further. */
+ if( call_info -> bitswapped ) {
+ tvbuff_t *reversed_tvb;
+ guint8 *data;
+ guint len;
+ guint i;
+
+ len = tvb_length(tvb);
+ data = g_malloc(len);
+ for( i=0; i<len; i++)
+ data[i]=BIT_SWAP(tvb_get_guint8(tvb,i));
+
+
+ reversed_tvb = tvb_new_real_data(data,len,tvb_reported_length(tvb));
+
+ /*
+ * Add the reversed tvbuff to the list of tvbuffs to which
+ * the tvbuff we were handed refers, so it'll get
+ * cleaned up when that tvbuff is cleaned up.
+ */
+ tvb_set_child_real_data_tvbuff(tvb, reversed_tvb);
+
+
+ /* Add a freer */
+ tvb_set_free_cb(reversed_tvb, g_free);
+
+ /* Add the reversed data to the data source list. */
+ add_new_data_source(pinfo, reversed_tvb, "Bit-swapped H.223 frame" );
+
+ tvb = reversed_tvb;
+ }
+
+ while( offset < tvb_reported_length( tvb )) {
+ gboolean pdu_found_this_fragment = FALSE;
+ offset = dissect_mux_pdu_fragment( tvb, offset, pinfo, &pkt_offset, tree,
+ &h223_tree, call_info,
+ &pdu_found_this_fragment );
+ if( pdu_found_this_fragment )
+ pdu_found = TRUE;
+ }
+
+ if( !pdu_found && check_col (pinfo->cinfo, COL_INFO))
+ col_set_str (pinfo->cinfo, COL_INFO, "(No complete PDUs)");
+
+ /* set up the protocol and info fields in the summary pane */
+ if (check_col (pinfo->cinfo, COL_PROTOCOL))
+ col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_H223);
+}
+
+static void h223_init_protocol (void)
+{
+ circuit_chain_init();
+}
+
+
+void proto_register_h223 (void)
+{
+ /* A header field is something you can search/filter on.
+ *
+ * We create a structure to register our fields. It consists of an
+ * array of hf_register_info structures, each of which are of the format
+ * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
+ */
+
+ static hf_register_info hf[] = {
+ { &hf_h223_non_h223_data,
+ { "Non-H.223 data", "h223.non-h223", FT_NONE, BASE_NONE, NULL, 0x0,
+ "Initial data in stream, not a PDU", HFILL }},
+
+ { &hf_h223_mux_stuffing_pdu,
+ { "H.223 stuffing PDU", "h223.mux.stuffing", FT_NONE, BASE_NONE, NULL, 0x0,
+ "Empty PDU used for stuffing when no data available", HFILL }},
+
+ { &hf_h223_mux_pdu,
+ { "H.223 MUX-PDU", "h223.mux", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 MUX-PDU", HFILL }},
+
+ { &hf_h223_mux_header,
+ { "Header", "h223.mux.header", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 MUX header", HFILL }},
+
+ { &hf_h223_mux_rawhdr,
+ { "Raw value", "h223.mux.rawhdr", FT_UINT24, BASE_HEX, NULL, 0x0,
+ "Raw header bytes", HFILL }},
+
+ { &hf_h223_mux_correctedhdr,
+ { "Corrected value", "h223.mux.correctedhdr", FT_UINT24, BASE_HEX, NULL, 0x0,
+ "Corrected header bytes", HFILL }},
+
+ { &hf_h223_mux_mc,
+ { "Multiplex Code", "h223.mux.mc", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "H.223 MUX multiplex code", HFILL }},
+
+ { &hf_h223_mux_mpl,
+ { "Multiplex Payload Length", "h223.mux.mpl", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "H.223 MUX multiplex Payload Length", HFILL }},
+
+ { &hf_h223_mux_deact,
+ { "Deactivated multiplex table entry", "h223.mux.deactivated", FT_NONE, BASE_NONE, NULL, 0x0,
+ "mpl refers to an entry in the multiplex table which is not active", HFILL }},
+
+ { &hf_h223_mux_vc,
+ { "H.223 virtual circuit", "h223.mux.vc", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "H.223 Virtual Circuit", HFILL }},
+
+ { &hf_h223_mux_extra,
+ { "Extraneous data", "h223.mux.extra", FT_NONE, BASE_DEC, NULL, 0x0,
+ "data beyond mpl", HFILL }},
+
+ { &hf_h223_mux_hdlc2,
+ { "HDLC flag", "h223.mux.hdlc", FT_UINT16, BASE_HEX, NULL, 0x0,
+ "framing flag", HFILL }},
+
+ /* fields for h.223-mux fragments */
+ { &hf_h223_mux_fragment_overlap,
+ { "Fragment overlap", "h223.mux.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }},
+
+ { &hf_h223_mux_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "h223.mux.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }},
+
+ { &hf_h223_mux_fragment_multiple_tails,
+ { "Multiple tail fragments found", "h223.mux.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }},
+
+ { &hf_h223_mux_fragment_too_long_fragment,
+ { "Fragment too long", "h223.mux.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }},
+
+ { &hf_h223_mux_fragment_error,
+ { "Defragmentation error", "h223.mux.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }},
+
+ { &hf_h223_mux_fragment,
+ { "H.223 MUX-PDU Fragment", "h223.mux.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "H.223 MUX-PDU Fragment", HFILL }},
+
+ { &hf_h223_mux_fragments,
+ { "H.223 MUX-PDU Fragments", "h223.mux.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 MUX-PDU Fragments", HFILL }},
+
+ { &hf_h223_mux_reassembled_in,
+ { "MUX-PDU fragment, reassembled in frame", "h223.mux.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This H.223 MUX-PDU packet is reassembled in this frame", HFILL }},
+
+ /* fields for h.223-al fragments */
+ { &hf_h223_al_fragment_overlap,
+ { "Fragment overlap", "h223.al.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }},
+
+ { &hf_h223_al_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "h223.al.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }},
+
+ { &hf_h223_al_fragment_multiple_tails,
+ { "Multiple tail fragments found", "h223.al.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }},
+
+ { &hf_h223_al_fragment_too_long_fragment,
+ { "Fragment too long", "h223.al.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }},
+
+ { &hf_h223_al_fragment_error,
+ { "Defragmentation error", "h223.al.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }},
+
+ { &hf_h223_al_fragment,
+ { "H.223 AL-PDU Fragment", "h223.al.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "H.223 AL-PDU Fragment", HFILL }},
+
+ { &hf_h223_al_fragments,
+ { "H.223 AL-PDU Fragments", "h223.al.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 AL-PDU Fragments", HFILL }},
+
+ { &hf_h223_al_reassembled_in,
+ { "AL-PDU fragment, reassembled in frame", "h223.al.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This H.223 AL-PDU packet is reassembled in this frame", HFILL }},
+
+ /* h223-als */
+
+ { &hf_h223_al1,
+ { "H.223 AL1", "h223.al1", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 AL-PDU using AL1", HFILL }},
+
+ { &hf_h223_al1_framed,
+ { "H.223 AL1 framing", "h223.al1.framed", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ { &hf_h223_al2,
+ { "H.223 AL2", "h223.al2", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 AL-PDU using AL2", HFILL }},
+
+ { &hf_h223_al2_sequenced,
+ { "H.223 AL2 sequenced", "h223.al2.sequenced", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ { &hf_h223_al2_seqno,
+ { "Sequence Number", "h223.al2.seqno", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "H.223 AL2 sequence number", HFILL }},
+
+ { &hf_h223_al2_crc,
+ { "CRC", "h223.al2.crc", FT_UINT8, BASE_HEX, NULL, 0x0,
+ "CRC", HFILL }},
+
+ { &hf_h223_al2_crc_bad,
+ { "Bad CRC","h223.al2.crc_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "", HFILL }},
+
+ { &hf_h223_al_payload,
+ { "H.223 AL Payload", "h223.al.payload", FT_NONE, BASE_NONE, NULL, 0x0,
+ "H.223 AL-PDU Payload", HFILL }},
+
+ };
+
+ static gint *ett[] = {
+ &ett_h223,
+ &ett_h223_non_h223_data,
+ &ett_h223_mux_stuffing_pdu,
+ &ett_h223_mux_pdu,
+ &ett_h223_mux_header,
+ &ett_h223_mux_deact,
+ &ett_h223_mux_vc,
+ &ett_h223_mux_extra,
+ &ett_h223_mux_fragments,
+ &ett_h223_mux_fragment,
+ &ett_h223_al_fragments,
+ &ett_h223_al_fragment,
+ &ett_h223_al1,
+ &ett_h223_al2,
+ &ett_h223_al_payload
+ };
+
+ if (proto_h223 == -1) { /* execute protocol initialization only once */
+ proto_h223 =
+ proto_register_protocol ("ITU-T Recommendation H.223", "H.223", "h223");
+
+ proto_register_field_array (proto_h223, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ register_dissector("h223", dissect_h223, proto_h223);
+
+ /* register our init routine to be called at the start of a capture,
+ to clear out our hash tables etc */
+ register_init_routine(&h223_init_protocol);
+ }
+
+ h245_set_h223_set_mc_handle( &h223_set_mc );
+ h245_set_h223_add_lc_handle( &h223_add_lc );
+}
+
+void proto_reg_handoff_h223(void)
+{
+ dissector_handle_t h223 = find_dissector("h223");
+ data_handle = find_dissector("data");
+ h245dg_handle = find_dissector("h245dg");
+ srp_handle = find_dissector("srp");
+
+ dissector_add_handle("tcp.port", h223);
+ dissector_add("iax2.dataformat", AST_DATAFORMAT_H223_H245, h223);
+}
+/* vim:set ts=8 et: */
--- plugins/h223/packet-h223.h 1970-01-01 01:00:00.000000000 +0100
+++ plugins/h223/packet-h223.h 2005-08-23 16:57:38.000000000 +0100
@@ -0,0 +1,31 @@
+/* $Id: packet-h223.h,v 1.3 2005/08/23 15:57:38 jeff Exp $
+ *
+ * Routines for H.223 packet dissection
+ * 2004 Richard van der Hoff <richardv@xxxxxxxxxxxxx>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PACKET_H223_H__
+#define __PACKET_H223_H__
+
+void proto_register_h223 (void);
+void proto_reg_handoff_h223(void);
+
+#endif /* __PACKET_H223_H__ */
- Prev by Date: Re: [Ethereal-dev] Interest check: state/event graphs?
- Next by Date: [Ethereal-dev] Enhancement
- Previous by thread: Re: [Ethereal-dev] Interest check: state/event graphs?
- Next by thread: [Ethereal-dev] nettl (HP-UX) patch: uid and pduin/pduout
- Index(es):





