- Remove GLIB1 code
[obnox/wireshark/wip.git] / asn1 / h245 / packet-h245-template.c
index 5ee2de2907439f7c07d4032380f9529e41cb35f6..6dac48ad54433cade03ced37e24a1a8a8a8ffe4c 100644 (file)
@@ -4,8 +4,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@
  * to hack it by hand, but it is incomplete and buggy and it is good when
  * it will go away."
  * Ronnie did a great job and all the VoIP users had made good use of it!
- * Credit to Tomas Kukosa for developing the Asn2eth compiler.
+ * Credit to Tomas Kukosa for developing the asn2wrs compiler.
  *
  */
 
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/conversation.h>
+#include <epan/strutil.h>
 
 #include <stdio.h>
 #include <string.h>
 
 #include <epan/prefs.h>
+#include <epan/t35.h>
+#include <epan/emem.h>
+#include <epan/oids.h>
+#include <epan/asn1.h>
 #include "tap.h"
-#include "packet-h245.h"
 #include "packet-tpkt.h"
 #include "packet-per.h"
-#include <epan/t35.h>
+#include "packet-h323.h"
+#include "packet-h245.h"
 #include "packet-rtp.h"
 #include "packet-rtcp.h"
-#include "packet-ber.h"
+#include "packet-t38.h"
 
-#define PNAME  "h245"
-#define PSNAME "h245"
+#define PNAME  "MULTIMEDIA-SYSTEM-CONTROL"
+#define PSNAME "H.245"
 #define PFNAME "h245"
 
 static dissector_handle_t rtp_handle=NULL;
 static dissector_handle_t rtcp_handle=NULL;
+static dissector_handle_t t38_handle=NULL;
 static dissector_table_t nsp_object_dissector_table;
 static dissector_table_t nsp_h221_dissector_table;
+static dissector_table_t gef_name_dissector_table;
+static dissector_table_t gef_content_dissector_table;
 static dissector_handle_t nsp_handle;
 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 void init_h245_packet_info(h245_packet_info *pi);
 static int hf_h245_pdu_type = -1;
 static int hf_h245Manufacturer = -1;
 static int h245_tap = -1;
-static int ett_h245 = -1;
 static int h245dg_tap = -1;
-static h245_packet_info pi_arr[5]; /* We assuming a maximum of 5 H245 messaages per packet */
-static int pi_current=0;
 h245_packet_info *h245_pi=NULL;
 
 static gboolean h245_reassembly = TRUE;
 static gboolean h245_shorttypes = FALSE;
+
+#include "packet-h245-val.h"
+
 static const value_string h245_RequestMessage_short_vals[] = {
-       {  0,   "NSM" },
-       {  1,   "MSD" },
-       {  2,   "TCS" },
-       {  3,   "OLC" },
-       {  4,   "CLC" },
-       {  5,   "RCC" },
-       {  6,   "MES" },
-       {  7,   "RME" },
-       {  8,   "RM" },
-       {  9,   "RTDR" },
-       { 10,   "MLR" },
-       { 11,   "CMR" },
-       { 12,   "CR" },
-       { 13,   "MR" },
-       { 14,   "LCRR" },
-       { 15,   "GR" },
+       { RequestMessage_nonStandard              ,     "NSM" },
+       { RequestMessage_masterSlaveDetermination ,     "MSD" },
+       { RequestMessage_terminalCapabilitySet    ,     "TCS" },
+       { RequestMessage_openLogicalChannel       ,     "OLC" },
+       { RequestMessage_closeLogicalChannel      ,     "CLC" },
+       { RequestMessage_requestChannelClose      ,     "RCC" },
+       { RequestMessage_multiplexEntrySend       ,     "MES" },
+       { RequestMessage_requestMultiplexEntry    ,     "RME" },
+       { RequestMessage_requestMode              ,     "RM"  },
+       { RequestMessage_roundTripDelayRequest    ,     "RTDR" },
+       { RequestMessage_maintenanceLoopRequest   ,     "MLR" },
+       { RequestMessage_communicationModeRequest ,     "CMR" },
+       { RequestMessage_conferenceRequest        ,     "CR"  },
+       { RequestMessage_multilinkRequest         ,     "MR"  },
+       { RequestMessage_logicalChannelRateRequest,     "LCRR" },
+       { RequestMessage_genericRequest           ,     "GR"  },
        {  0, NULL }
 };
 static const value_string h245_ResponseMessage_short_vals[] = {
-       {  0,   "NSM" },
-       {  1,   "MSDAck" },
-       {  2,   "MSDReject" },
-       {  3,   "TCSAck" },
-       {  4,   "TCSReject" },
-       {  5,   "OLCAck" },
-       {  6,   "OLCReject" },
-       {  7,   "CLCAck" },
-       {  8,   "RCCAck" },
-       {  9,   "RCCReject" },
-       { 10,   "MESAck" },
-       { 11,   "MESReject" },
-       { 12,   "RMEAck" },
-       { 13,   "RMEReject" },
-       { 14,   "RMAck" },
-       { 15,   "RMReject" },
-       { 16,   "RTDResponse" },
-       { 17,   "MLAck" },
-       { 18,   "MLReject" },
-       { 19,   "CMResponse" },
-       { 20,   "CResponse" },
-       { 21,   "MResponse" },
-       { 22,   "LCRAck" },
-       { 23,   "LCRReject" },
-       { 24,   "GR" },
+       { ResponseMessage_nonStandard                   ,       "NSM" },
+       { ResponseMessage_masterSlaveDeterminationAck   ,       "MSDAck" },
+       { ResponseMessage_masterSlaveDeterminationReject,       "MSDReject" },
+       { ResponseMessage_terminalCapabilitySetAck      ,       "TCSAck" },
+       { ResponseMessage_terminalCapabilitySetReject   ,       "TCSReject" },
+       { ResponseMessage_openLogicalChannelAck         ,       "OLCAck" },
+       { ResponseMessage_openLogicalChannelReject      ,       "OLCReject" },
+       { ResponseMessage_closeLogicalChannelAck        ,       "CLCAck" },
+       { ResponseMessage_requestChannelCloseAck        ,       "RCCAck" },
+       { ResponseMessage_requestChannelCloseReject     ,       "RCCReject" },
+       { ResponseMessage_multiplexEntrySendAck         ,       "MESAck" },
+       { ResponseMessage_multiplexEntrySendReject      ,       "MESReject" },
+       { ResponseMessage_requestMultiplexEntryAck      ,       "RMEAck" },
+       { ResponseMessage_requestMultiplexEntryReject   ,       "RMEReject" },
+       { ResponseMessage_requestModeAck                ,       "RMAck" },
+       { ResponseMessage_requestModeReject             ,       "RMReject" },
+       { ResponseMessage_roundTripDelayResponse        ,       "RTDResponse" },
+       { ResponseMessage_maintenanceLoopAck            ,       "MLAck" },
+       { ResponseMessage_maintenanceLoopReject         ,       "MLReject" },
+       { ResponseMessage_communicationModeResponse     ,       "CMResponse" },
+       { ResponseMessage_conferenceResponse            ,       "CResponse" },
+       { ResponseMessage_multilinkResponse             ,       "MResponse" },
+       { ResponseMessage_logicalChannelRateAcknowledge ,       "LCRAck" },
+       { ResponseMessage_logicalChannelRateReject      ,       "LCRReject" },
+       { ResponseMessage_genericResponse               ,       "GR" },
        {  0, NULL }
 };
 static const value_string h245_IndicationMessage_short_vals[] = {
-       {  0,   "NSM" },
-       {  1,   "FNU" },
-       {  2,   "MSDRelease" },
-       {  3,   "TCSRelease" },
-       {  4,   "OLCConfirm" },
-       {  5,   "RCCRelease" },
-       {  6,   "MESRelease" },
-       {  7,   "RMERelease" },
-       {  8,   "RMRelease" },
-       {  9,   "MI" },
-       { 10,   "JI" },
-       { 11,   "H223SI" },
-       { 12,   "NATMVCI" },
-       { 13,   "UII" },
-       { 14,   "H2250MSI" },
-       { 15,   "MCLI" },
-       { 16,   "CI" },
-       { 17,   "VI" },
-       { 18,   "FNS" },
-       { 19,   "MultilinkIndication" },
-       { 20,   "LCRRelease" },
-       { 21,   "FCIndication" },
-       { 22,   "MMRI" },
-       { 22,   "GI" },
+       { IndicationMessage_nonStandard                             ,   "NSM" },
+       { IndicationMessage_functionNotUnderstood                   ,   "FNU" },
+       { IndicationMessage_masterSlaveDeterminationRelease         ,   "MSDRelease" },
+       { IndicationMessage_terminalCapabilitySetRelease            ,   "TCSRelease" },
+       { IndicationMessage_openLogicalChannelConfirm               ,   "OLCConfirm" },
+       { IndicationMessage_requestChannelCloseRelease              ,   "RCCRelease" },
+       { IndicationMessage_multiplexEntrySendRelease               ,   "MESRelease" },
+       { IndicationMessage_requestMultiplexEntryRelease            ,   "RMERelease" },
+       { IndicationMessage_requestModeRelease                      ,   "RMRelease" },
+       { IndicationMessage_miscellaneousIndication                 ,   "MI" },
+       { IndicationMessage_jitterIndication                        ,   "JI" },
+       { IndicationMessage_h223SkewIndication                      ,   "H223SI" },
+       { IndicationMessage_newATMVCIndication                      ,   "NATMVCI" },
+       { IndicationMessage_userInput                               ,   "UII" },
+       { IndicationMessage_h2250MaximumSkewIndication              ,   "H2250MSI" },
+       { IndicationMessage_mcLocationIndication                    ,   "MCLI" },
+       { IndicationMessage_conferenceIndication                    ,   "CI" },
+       { IndicationMessage_vendorIdentification                    ,   "VI" },
+       { IndicationMessage_functionNotSupported                    ,   "FNS" },
+       { IndicationMessage_multilinkIndication                     ,   "MultilinkIndication" },
+       { IndicationMessage_logicalChannelRateRelease               ,   "LCRRelease" },
+       { IndicationMessage_flowControlIndication                   ,   "FCIndication" },
+       { IndicationMessage_mobileMultilinkReconfigurationIndication,   "MMRI" },
+       { IndicationMessage_genericIndication                       ,   "GI" },
        {  0, NULL }
 };
 static const value_string h245_CommandMessage_short_vals[] = {
-       {  0,   "NSM" },
-       {  1,   "MLOC" },
-       {  2,   "STCS" },
-       {  3,   "EC" },
-       {  4,   "FCC" },
-       {  5,   "ESC" },
-       {  6,   "MC" },
-       {  7,   "CMC" },
-       {  8,   "CC" },
-       {  9,   "H223MR" },
-       { 10,   "NATMVCC" },
-       { 11,   "MMRC" },
-       { 12,   "GC" },
+       { CommandMessage_nonStandard                          , "NSM" },
+       { CommandMessage_maintenanceLoopOffCommand            , "MLOC" },
+       { CommandMessage_sendTerminalCapabilitySet            , "STCS" },
+       { CommandMessage_encryptionCommand                    , "EC" },
+       { CommandMessage_flowControlCommand                   , "FCC" },
+       { CommandMessage_endSessionCommand                    , "ESC" },
+       { CommandMessage_miscellaneousCommand                 , "MC" },
+       { CommandMessage_communicationModeCommand             , "CMC" },
+       { CommandMessage_conferenceCommand                    , "CC" },
+       { CommandMessage_h223MultiplexReconfiguration         , "H223MR" },
+       { CommandMessage_newATMVCCommand                      , "NATMVCC" },
+       { CommandMessage_mobileMultilinkReconfigurationCommand, "MMRC" },
+       { CommandMessage_genericCommand                       , "GC" },
        {  0, NULL }
 };
+
 static const value_string h245_AudioCapability_short_vals[] = {
-        {  0, "nonStd" },
-        {  1, "g711A" },
-        {  2, "g711A56k" },
-        {  3, "g711U" },
-        {  4, "g711U56k" },
-        {  5, "g722-64k" },
-        {  6, "g722-56k" },
-        {  7, "g722-48k" },
-        {  8, "g7231" },
-        {  9, "g728" },
-        { 10, "g729" },
-        { 11, "g729A" },
-        { 12, "is11172" },
-        { 13, "is13818" },
-        { 14, "g729B" },
-        { 15, "g729AB" },
-        { 16, "g7231C" },
-        { 17, "gsmFR" },
-        { 18, "gsmHR" },
-        { 19, "gsmEFR" },
-        { 20, "generic" },
-        { 21, "g729Ext" },
-        { 22, "vbd" },
-        { 23, "audioTelEvent" },
-        { 24, "audioTone" },
-        {  0, NULL }
+  { AudioCapability_nonStandard           , "nonStd" },
+  { AudioCapability_g711Alaw64k           , "g711A" },
+  { AudioCapability_g711Alaw56k           , "g711A56k" },
+  { AudioCapability_g711Ulaw64k           , "g711U" },
+  { AudioCapability_g711Ulaw56k           , "g711U56k" },
+  { AudioCapability_g722_64k              , "g722-64k" },
+  { AudioCapability_g722_56k              , "g722-56k" },
+  { AudioCapability_g722_48k              , "g722-48k" },
+  { AudioCapability_g7231                 , "g7231" },
+  { AudioCapability_g728                  , "g728" },
+  { AudioCapability_g729                  , "g729" },
+  { AudioCapability_g729AnnexA            , "g729A" },
+  { AudioCapability_is11172AudioCapability, "is11172" },
+  { AudioCapability_is13818AudioCapability, "is13818" },
+  { AudioCapability_g729wAnnexB           , "g729B" },
+  { AudioCapability_g729AnnexAwAnnexB     , "g729AB" },
+  { AudioCapability_g7231AnnexCCapability , "g7231C" },
+  { AudioCapability_gsmFullRate           , "gsmFR" },
+  { AudioCapability_gsmHalfRate           , "gsmHR" },
+  { AudioCapability_gsmEnhancedFullRate   , "gsmEFR" },
+  { AudioCapability_genericAudioCapability, "generic" },
+  { AudioCapability_g729Extensions        , "g729Ext" },
+  { AudioCapability_vbd                   , "vbd" },
+  { AudioCapability_audioTelephonyEvent   , "audioTelEvent" },
+  { AudioCapability_audioTone             , "audioTone" },
+  {  0, NULL }
 };
 
 /* To put the codec type only in COL_INFO when
    an OLC is read */
-
 const char* codec_type = NULL;
-static char standard_oid_str[MAX_OID_STR_LEN];
-static guint32 ipv4_address;
-static guint32 ipv4_port;
-static guint32 rtcp_ipv4_address;
-static guint32 rtcp_ipv4_port;
-static gboolean media_channel;
-static gboolean media_control_channel;
+static guint32 rfc_number;
+
+typedef struct _unicast_addr_t {
+  address addr;
+  guint8 addr_buf[16];
+  guint32 port;
+} unicast_addr_t;
+
+typedef struct _channel_info_t {
+  gchar data_type_str[32];
+  unicast_addr_t *upcoming_addr;
+  unicast_addr_t media_addr;
+  unicast_addr_t media_control_addr;
+  unsigned int rfc2198;
+  gboolean srtp_flag;
+} channel_info_t;
+
+typedef struct _olc_info_t {
+  guint16 fwd_lc_num;
+  channel_info_t fwd_lc;
+  channel_info_t rev_lc;
+} olc_info_t;
+
+static GHashTable* h245_pending_olc_reqs = NULL;
+static gboolean fast_start = FALSE;
+static olc_info_t *upcoming_olc = NULL;
+static channel_info_t *upcoming_channel = NULL;
 
 /* NonStandardParameter */
-static char nsiOID[MAX_OID_STR_LEN];
+static const char *nsiOID;
 static guint32 h221NonStandard;
 static guint32 t35CountryCode;
 static guint32 t35Extension;
@@ -218,75 +248,204 @@ static guint32 manufacturerCode;
 
 static const value_string h245_RFC_number_vals[] = {
        {  2190,        "RFC 2190 - H.263 Video Streams" },
+       {  2198,        "RFC 2198 - RTP Payload for Redundant Audio Data" },
        {  2429,        "RFC 2429 - 1998 Version of ITU-T Rec. H.263 Video (H.263+)" },
+       {  3016,        "RFC 3016 - RTP Payload Format for MPEG-4 Audio/Visual Streams" },
        {  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( void )
+{
+       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;
+}
+
+static void h245_init(void) 
+{
+       if ( h245_pending_olc_reqs)
+               g_hash_table_destroy(h245_pending_olc_reqs);
+       h245_pending_olc_reqs = g_hash_table_new(g_str_hash, g_str_equal);
+
+       h223_lc_init();
+}
+
+void h245_set_h223_add_lc_handle( h223_add_lc_handle_t handle )
+{
+       h223_add_lc_handle = handle;
+}
+
+static const gchar *gen_olc_key(guint16 lc_num, address *dst_addr, address *src_addr)
+{
+  return ep_strdup_printf("%s/%s/%u", address_to_str(dst_addr), address_to_str(src_addr), lc_num);
+}
+
+static void update_unicast_addr(unicast_addr_t *req_addr, unicast_addr_t *ack_addr)
+{
+  if (ack_addr->addr.type!=AT_NONE && ack_addr->port!=0) {
+    memcpy(req_addr->addr_buf, ack_addr->addr_buf, sizeof(req_addr->addr_buf));
+    SET_ADDRESS(&req_addr->addr, ack_addr->addr.type, ack_addr->addr.len, req_addr->addr_buf);
+    req_addr->port = ack_addr->port;
+  }
+}
+
+static void h245_setup_channels(packet_info *pinfo, channel_info_t *upcoming_channel)
+{
+       gint *key;
+       GHashTable *rtp_dyn_payload = NULL;
+       struct srtp_info *dummy_srtp_info = NULL;
+
+       if (!upcoming_channel) return;
+
+       /* T.38 */
+       if (!strcmp(upcoming_channel->data_type_str, "t38fax")) {
+               if (upcoming_channel->media_addr.addr.type!=AT_NONE && upcoming_channel->media_addr.port!=0 && t38_handle) {
+                       t38_add_address(pinfo, &upcoming_channel->media_addr.addr, 
+                                                       upcoming_channel->media_addr.port, 0, 
+                                                       "H245", pinfo->fd->num);
+               }
+               return;
+       }
+
+       /* (S)RTP, (S)RTCP */
+       if (upcoming_channel->rfc2198 > 0) {
+               rtp_dyn_payload = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+               key = g_malloc(sizeof(gint));
+               *key = upcoming_channel->rfc2198;
+               g_hash_table_insert(rtp_dyn_payload, key, g_strdup("red"));
+       }
+
+       if (upcoming_channel->srtp_flag) {
+               struct srtp_info *dummy_srtp_info = se_alloc0(sizeof(struct srtp_info));
+       }
+       if (upcoming_channel->media_addr.addr.type!=AT_NONE && upcoming_channel->media_addr.port!=0 && rtp_handle) {
+               srtp_add_address(pinfo, &upcoming_channel->media_addr.addr, 
+                                               upcoming_channel->media_addr.port, 0, 
+                                               "H245", pinfo->fd->num, rtp_dyn_payload, dummy_srtp_info);
+       }
+       if (upcoming_channel->media_control_addr.addr.type!=AT_NONE && upcoming_channel->media_control_addr.port!=0 && rtcp_handle) {
+               srtcp_add_address(pinfo, &upcoming_channel->media_control_addr.addr, 
+                                               upcoming_channel->media_control_addr.port, 0, 
+                                               "H245", pinfo->fd->num, dummy_srtp_info);
+       }
+}
+
 /* Initialize the protocol and registered fields */
 int proto_h245 = -1;
 #include "packet-h245-hf.c"
 
 /* Initialize the subtree pointers */
+static int ett_h245 = -1;
+static int ett_h245_returnedFunction = -1;
 #include "packet-h245-ett.c"
 
+/* Forward declarations */
+static int dissect_h245_MultimediaSystemControlMessage(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
+static void reset_h245_pi(void *dummy _U_)
+{
+       h245_pi = NULL; /* Make sure we don't leave ep_alloc()ated memory lying around */
+}
+
 #include "packet-h245-fn.c"
 
 static void
 dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 {
-    pi_current++;
-    if(pi_current==5){
-        pi_current=0;
-    }
-    h245_pi=&pi_arr[pi_current];
-
-    reset_h245_packet_info(h245_pi);
-       h245_pi->msg_type = H245_OTHER;
-
+       /*
+        * MultimediaSystemControlMessage_handle is the handle for
+        * dissect_h245_h245, so we don't want to do any h245_pi or tap stuff here.
+        */
        dissect_tpkt_encap(tvb, pinfo, parent_tree, h245_reassembly, MultimediaSystemControlMessage_handle);
-
-       tap_queue_packet(h245_tap, pinfo, h245_pi);
 }
 
+
 static void
 dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 {
        proto_item *it;
        proto_tree *tr;
        guint32 offset=0;
+       asn1_ctx_t asn1_ctx;
 
-    pi_current++;
-    if(pi_current==5){
-      pi_current=0;
-    }
-    h245_pi=&pi_arr[pi_current];
-
-    reset_h245_packet_info(h245_pi);
-    h245_pi->msg_type = H245_OTHER;
+       fast_start = FALSE;
+       /* Clean up from any previous packet dissection */
+       upcoming_olc = NULL;
+       upcoming_channel = NULL;
+       codec_type = NULL;
 
        if (check_col(pinfo->cinfo, COL_PROTOCOL)){
-               col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.245");
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
        }
 
-       it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), "H.245");
+       it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), PSNAME);
        tr=proto_item_add_subtree(it, ett_h245);
-       dissect_h245_MultimediaSystemControlMessage(tvb, offset, pinfo ,tr, hf_h245_pdu_type);
-       tap_queue_packet(h245dg_tap, pinfo, h245_pi);
+
+       /* assume that whilst there is more tvb data, there are more h245 commands */
+       while ( tvb_length_remaining( tvb, offset>>3 )>0 ){
+               CLEANUP_PUSH(reset_h245_pi, NULL);
+               h245_pi=ep_alloc(sizeof(h245_packet_info));
+               init_h245_packet_info(h245_pi);
+               asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
+               offset = dissect_h245_MultimediaSystemControlMessage(tvb, offset, &asn1_ctx, tr, hf_h245_pdu_type);
+               tap_queue_packet(h245dg_tap, pinfo, h245_pi);
+               offset = (offset+0x07) & 0xfffffff8;
+               CLEANUP_CALL_AND_POP;
+       }
 }
 
-int
-dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *codec_str) {
-  offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
-                                ett_h245_OpenLogicalChannel, OpenLogicalChannel_sequence);
+void
+dissect_h245_FastStart_OLC(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, char *codec_str) {
+
+  fast_start = TRUE;
+  /* Clean up from any previous packet dissection */
+  upcoming_olc = NULL;
+  upcoming_channel = NULL;
+  codec_type = NULL;
 
+  dissect_OpenLogicalChannel_PDU(tvb, pinfo, tree);
 
-  if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
+  if (h245_pi != NULL) 
+         h245_pi->msg_type = H245_OpenLogChn;
 
   if (codec_str && codec_type){
-        strncpy(codec_str, codec_type, 50);
+        g_strlcpy(codec_str, codec_type, 50);
   }
 
-  return offset;
 }
 
 /*--- proto_register_h245 -------------------------------------------*/
@@ -306,18 +465,20 @@ void proto_register_h245(void) {
   /* List of subtrees */
   static gint *ett[] = {
          &ett_h245,
+         &ett_h245_returnedFunction,
 #include "packet-h245-ettarr.c"
   };
   module_t *h245_module;
 
   /* Register protocol */
   proto_h245 = proto_register_protocol(PNAME, PSNAME, PFNAME);
+  register_init_routine(h245_init);
   /* Register fields and subtrees */
   proto_register_field_array(proto_h245, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 
   /* From Ronnie Sahlbergs original H245 dissector */
-       
+
   h245_module = prefs_register_protocol(proto_h245, NULL);
   prefs_register_bool_preference(h245_module, "reassembly",
                "Reassemble H.245 messages spanning multiple TCP segments",
@@ -333,26 +494,61 @@ void proto_register_h245(void) {
 
   nsp_object_dissector_table = register_dissector_table("h245.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
   nsp_h221_dissector_table = register_dissector_table("h245.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
+  gef_name_dissector_table = register_dissector_table("h245.gef.name", "H.245 Generic Extensible Framework (names)", FT_STRING, BASE_NONE);
+  gef_content_dissector_table = register_dissector_table("h245.gef.content", "H.245 Generic Extensible Framework", FT_STRING, BASE_NONE);
+
   h245_tap = register_tap("h245");
   h245dg_tap = register_tap("h245dg");
 
-  register_ber_oid_name("0.0.8.239.1.1","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ControlCapability(1)");
-  register_ber_oid_name("0.0.8.239.1.2","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ExtendedVideoCapability(2)");
-  register_ber_oid_name("0.0.8.239.2","itu-t(0) recommendation(0) h(8) h239(239) generic-message(2)");
-  register_ber_oid_name("0.0.8.245.0.3","itu-t(0) recommendation(0) h(8) h245(245) version(0) 3");
-  register_ber_oid_name("0.0.8.245.0.4","itu-t(0) recommendation(0) h(8) h245(245) version(0) 4");
-  register_ber_oid_name("0.0.8.245.0.5","itu-t(0) recommendation(0) h(8) h245(245) version(0) 5");
-  register_ber_oid_name("0.0.8.245.0.6","itu-t(0) recommendation(0) h(8) h245(245) version(0) 6");
-  register_ber_oid_name("0.0.8.245.0.7","itu-t(0) recommendation(0) h(8) h245(245) version(0) 7");
-  register_ber_oid_name("0.0.8.245.0.8","itu-t(0) recommendation(0) h(8) h245(245) version(0) 8");
-  register_ber_oid_name("0.0.8.245.0.10","itu-t(0) recommendation(0) h(8) h245(245) version(0) 10");
-  register_ber_oid_name("0.0.8.245.1.0.0","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) video (0) ISO/IEC 14496-2 (0)= MPEG-4 video");
-  register_ber_oid_name("0.0.8.245.1.1.0","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) audio (1) ISO/IEC 14496-3 (0)= MPEG-4 audio");
-  register_ber_oid_name("0.0.8.245.1.1.1","itu-t(0) recommendation(0) h(8) h245(245) generic-capabilities(1) audio(1) amr(1)");
-
-  register_ber_oid_name("0.0.8.241.0.0.1","itu-t(0) recommendation(0) h(8) h241(241) specificVideoCodecCapabilities(0) h264(0) generic-capabilities(1)");
-
-
+  oid_add_from_string("h239ControlCapability","0.0.8.239.1.1");
+  oid_add_from_string("h239ExtendedVideoCapability","0.0.8.239.1.2");
+  oid_add_from_string("generic-message","0.0.8.239.2");
+  oid_add_from_string("h245 version 3","0.0.8.245.0.3");
+  oid_add_from_string("h245 version 4","0.0.8.245.0.4");
+  oid_add_from_string("h245 version 5","0.0.8.245.0.5");
+  oid_add_from_string("h245 version 6","0.0.8.245.0.6");
+  oid_add_from_string("h245 version 7","0.0.8.245.0.7");
+  oid_add_from_string("h245 version 8","0.0.8.245.0.8");
+  oid_add_from_string("h245 version 9","0.0.8.245.0.9");
+  oid_add_from_string("h245 version 10","0.0.8.245.0.10");
+  oid_add_from_string("h245 version 11","0.0.8.245.0.11");
+  oid_add_from_string("h245 version 12","0.0.8.245.0.12");
+  oid_add_from_string("h245 version 13","0.0.8.245.0.13");
+  /* This capability is defined in Annex E. */
+  oid_add_from_string("ISO/IEC 14496-2 MPEG-4 video","0.0.8.245.1.0.0");
+  /* This capability is defined in Annex H. */
+  oid_add_from_string("ISO/IEC 14496-3 MPEG-4 audio","0.0.8.245.1.1.0");
+  /* This capability is defined in Annex I. */ 
+  oid_add_from_string("AMR","0.0.8.245.1.1.1");
+  /* This capability is defined in Annex J. */
+  oid_add_from_string("acelp","0.0.8.245.1.1.2");
+  /* This capability is defined in Annex K. */
+  oid_add_from_string("us1","0.0.8.245.1.1.3");
+  /* This capability is defined in Annex L. */
+  oid_add_from_string("is127evrc","0.0.8.245.1.1.4");
+  /* This capability is defined in Annex M. */
+  oid_add_from_string("ISO/IEC 13818-7","0.0.8.245.1.1.5");
+  /* This capability is defined in Annex N. */
+  oid_add_from_string("rfc3389","0.0.8.245.1.1.6");
+  /* This capability is defined in Annex O. */
+  oid_add_from_string("L-16","0.0.8.245.1.1.7");
+  /* This capability is defined in Annex P. */
+  oid_add_from_string("bounded-audio-stream","0.0.8.245.1.1.8");
+  /* This capability is defined in Annex R. */
+  oid_add_from_string("AMR-NB","0.0.8.245.1.1.9");
+  /* This capability is defined in Annex R. */
+  oid_add_from_string("AMR-WB","0.0.8.245.1.1.10");
+  /* This capability is defined in Annex S. */
+  oid_add_from_string("ilbc","0.0.8.245.1.1.11");
+  
+  oid_add_from_string("ISO/IEC 14496-1","0.0.8.245.1.2.0");
+  oid_add_from_string("Nx64","0.0.8.245.1.2.1");
+  oid_add_from_string("logical-channel-bit-ratemanagement","0.0.8.245.1.3.0");
+
+  oid_add_from_string("h264 generic-capabilities","0.0.8.241.0.0.1");
+  oid_add_from_string("iPpacketization_h241AnnexA(single NAL unit mode)","0.0.8.241.0.0.0.0");
+  oid_add_from_string("iPpacketization_RFC3984NonInterleaved","0.0.8.241.0.0.0.1");
+  oid_add_from_string("iPpacketization_RFC3984Interleaved","0.0.8.241.0.0.0.2");
 }
 
 
@@ -360,7 +556,10 @@ void proto_register_h245(void) {
 void proto_reg_handoff_h245(void) {
        rtp_handle = find_dissector("rtp");
        rtcp_handle = find_dissector("rtcp");
+       t38_handle = find_dissector("t38");
        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);
@@ -369,7 +568,7 @@ void proto_reg_handoff_h245(void) {
        dissector_add_handle("udp.port", MultimediaSystemControlMessage_handle);
 }
 
-static void reset_h245_packet_info(h245_packet_info *pi)
+static void init_h245_packet_info(h245_packet_info *pi)
 {
         if(pi == NULL) {
                 return;
@@ -377,6 +576,6 @@ static void reset_h245_packet_info(h245_packet_info *pi)
 
         pi->msg_type = H245_OTHER;
                pi->frame_label[0] = '\0';
-               sprintf(pi->comment, "H245 ");
+               g_snprintf(pi->comment, sizeof(pi->comment), "H245 ");
 }