2005-01-08 14:36:10 +00:00
/* packet-h225.c
2005-01-02 22:01:32 +00:00
* Routines for h225 packet dissection
* Copyright 2005 , Anders Broman < anders . broman @ ericsson . com >
*
2006-05-21 05:12:17 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2005-01-02 22:01:32 +00:00
* 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
2012-06-28 22:56:06 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
2005-01-02 22:01:32 +00:00
*
* To quote the author of the previous H323 / H225 / H245 dissector :
* " This is a complete replacement of the previous limitied dissector
* that Ronnie was crazy enough to write by hand . It was a lot of time
* 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 !
2006-05-23 15:17:14 +00:00
* Credit to Tomas Kukosa for developing the asn2wrs compiler .
2005-01-02 22:01:32 +00:00
*
*/
2012-09-20 01:29:52 +00:00
# include "config.h"
2005-01-02 22:01:32 +00:00
# include <epan/packet.h>
# include <epan/conversation.h>
# include <epan/prefs.h>
2007-08-25 01:14:24 +00:00
# include <epan/oids.h>
2006-06-13 13:21:12 +00:00
# include <epan/next_tvb.h>
2007-05-01 22:05:11 +00:00
# include <epan/asn1.h>
2014-12-23 05:32:58 +00:00
# include <epan/t35.h>
2009-08-21 20:32:50 +00:00
# include <epan/tap.h>
2015-08-03 17:30:04 +00:00
# include <epan/stat_tap_ui.h>
2015-06-23 00:51:20 +00:00
# include <epan/rtd_table.h>
2005-01-02 22:01:32 +00:00
# include "packet-tpkt.h"
# include "packet-per.h"
# include "packet-h225.h"
# include "packet-h235.h"
# include "packet-h245.h"
2007-10-17 10:25:21 +00:00
# include "packet-h323.h"
2005-01-17 22:27:39 +00:00
# include "packet-q931.h"
2006-08-28 07:05:02 +00:00
# include "packet-ssl.h"
2005-01-02 22:01:32 +00:00
2005-09-22 14:40:26 +00:00
2005-08-31 15:03:12 +00:00
# define PNAME "H323-MESSAGES"
# define PSNAME "H.225.0"
2005-01-02 22:01:32 +00:00
# define PFNAME "h225"
# define UDP_PORT_RAS1 1718
# define UDP_PORT_RAS2 1719
# define TCP_PORT_CS 1720
2006-08-28 07:05:02 +00:00
# define TLS_PORT_CS 1300
2005-01-02 22:01:32 +00:00
2013-12-17 22:07:32 +00:00
void proto_register_h225 ( void ) ;
2005-01-02 22:01:32 +00:00
static void reset_h225_packet_info ( h225_packet_info * pi ) ;
2015-01-25 22:32:40 +00:00
static void h225_init_routine ( void ) ;
2005-01-02 22:01:32 +00:00
static void ras_call_matching ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , h225_packet_info * pi ) ;
2015-01-25 22:32:40 +00:00
/* Item of ras request list*/
typedef struct _h225ras_call_t {
guint32 requestSeqNum ;
e_guid_t guid ;
guint32 req_num ; /* frame number request seen */
guint32 rsp_num ; /* frame number response seen */
nstime_t req_time ; /* arrival time of request */
gboolean responded ; /* true, if request has been responded */
struct _h225ras_call_t * next_call ; /* pointer to next ras request with same SequenceNumber and conversation handle */
} h225ras_call_t ;
/* Item of ras-request key list*/
typedef struct _h225ras_call_info_key {
guint reqSeqNum ;
conversation_t * conversation ;
} h225ras_call_info_key ;
2015-08-03 17:30:04 +00:00
static h225_packet_info pi_arr [ 5 ] ; /* We assuming a maximum of 5 H.225 messages per packet */
2005-02-01 12:12:35 +00:00
static int pi_current = 0 ;
2015-01-25 22:32:40 +00:00
static h225_packet_info * h225_pi = & pi_arr [ 0 ] ;
/* Global Memory Chunks for lists and Global hash tables*/
static GHashTable * ras_calls [ 7 ] = { NULL , NULL , NULL , NULL , NULL , NULL , NULL } ;
/* functions, needed using ras-request and halfcall matching*/
static h225ras_call_t * find_h225ras_call ( h225ras_call_info_key * h225ras_call_key , int category ) ;
static h225ras_call_t * new_h225ras_call ( h225ras_call_info_key * h225ras_call_key , packet_info * pinfo , e_guid_t * guid , int category ) ;
static h225ras_call_t * append_h225ras_call ( h225ras_call_t * prev_call , packet_info * pinfo , e_guid_t * guid , int category ) ;
2005-01-02 22:01:32 +00:00
static dissector_handle_t data_handle ;
/* Subdissector tables */
static dissector_table_t nsp_object_dissector_table ;
static dissector_table_t nsp_h221_dissector_table ;
static dissector_table_t tp_dissector_table ;
2007-10-17 10:25:21 +00:00
static dissector_table_t gef_name_dissector_table ;
static dissector_table_t gef_content_dissector_table ;
2005-01-02 22:01:32 +00:00
static dissector_handle_t h245_handle = NULL ;
static dissector_handle_t h245dg_handle = NULL ;
static dissector_handle_t h4501_handle = NULL ;
2005-01-19 22:43:15 +00:00
static dissector_handle_t nsp_handle ;
static dissector_handle_t tp_handle ;
2005-09-22 14:40:26 +00:00
static next_tvb_list_t h245_list ;
static next_tvb_list_t tp_list ;
2005-01-02 22:01:32 +00:00
/* Initialize the protocol and registered fields */
static int h225_tap = - 1 ;
static int proto_h225 = - 1 ;
static int hf_h221Manufacturer = - 1 ;
static int hf_h225_ras_req_frame = - 1 ;
static int hf_h225_ras_rsp_frame = - 1 ;
static int hf_h225_ras_dup = - 1 ;
static int hf_h225_ras_deltatime = - 1 ;
2014-08-08 13:19:29 +00:00
static int hf_h225_debug_dissector_try_string = - 1 ;
2005-01-02 22:01:32 +00:00
# include "packet-h225-hf.c"
/* Initialize the subtree pointers */
static gint ett_h225 = - 1 ;
# include "packet-h225-ett.c"
2005-09-27 10:05:42 +00:00
/* Preferences */
2006-08-28 07:05:02 +00:00
static guint h225_tls_port = TLS_PORT_CS ;
2005-09-27 10:05:42 +00:00
static gboolean h225_reassembly = TRUE ;
static gboolean h225_h245_in_tree = TRUE ;
static gboolean h225_tp_in_tree = TRUE ;
2005-01-02 22:01:32 +00:00
/* Global variables */
static guint32 ipv4_address ;
static guint32 ipv4_port ;
static gboolean contains_faststart = FALSE ;
2009-01-22 19:48:12 +00:00
static e_guid_t * call_id_guid ;
2005-01-02 22:01:32 +00:00
2005-01-20 12:02:08 +00:00
/* NonStandardParameter */
2005-09-20 14:14:07 +00:00
static const char * nsiOID ;
2005-01-20 12:02:08 +00:00
static guint32 h221NonStandard ;
static guint32 t35CountryCode ;
static guint32 t35Extension ;
static guint32 manufacturerCode ;
/* TunnelledProtocol */
2005-09-20 14:14:07 +00:00
static const char * tpOID ;
2005-01-20 12:02:08 +00:00
2015-06-23 00:51:20 +00:00
static const value_string ras_message_category [ ] = {
{ 0 , " Gatekeeper " } ,
{ 1 , " Registration " } ,
{ 2 , " UnRegistration " } ,
{ 3 , " Admission " } ,
{ 4 , " Bandwidth " } ,
{ 5 , " Disengage " } ,
{ 6 , " Location " } ,
{ 0 , NULL }
} ;
typedef enum _ras_type {
RAS_REQUEST ,
RAS_CONFIRM ,
RAS_REJECT ,
RAS_OTHER
} ras_type ;
typedef enum _ras_category {
RAS_GATEKEEPER ,
RAS_REGISTRATION ,
RAS_UNREGISTRATION ,
RAS_ADMISSION ,
RAS_BANDWIDTH ,
RAS_DISENGAGE ,
RAS_LOCATION ,
RAS_OTHERS
} ras_category ;
# define NUM_RAS_STATS 7
2015-08-03 17:30:04 +00:00
static gboolean
2015-06-23 00:51:20 +00:00
h225rassrt_packet ( void * phs , packet_info * pinfo _U_ , epan_dissect_t * edt _U_ , const void * phi )
{
2015-08-03 17:30:04 +00:00
rtd_data_t * rtd_data = ( rtd_data_t * ) phs ;
rtd_stat_table * rs = & rtd_data - > stat_table ;
2015-06-23 00:51:20 +00:00
const h225_packet_info * pi = ( const h225_packet_info * ) phi ;
ras_type rasmsg_type = RAS_OTHER ;
ras_category rascategory = RAS_OTHERS ;
if ( pi - > msg_type ! = H225_RAS | | pi - > msg_tag = = - 1 ) {
/* No RAS Message or uninitialized msg_tag -> return */
2015-08-03 17:30:04 +00:00
return FALSE ;
2015-06-23 00:51:20 +00:00
}
if ( pi - > msg_tag < 21 ) {
/* */
rascategory = ( ras_category ) ( pi - > msg_tag / 3 ) ;
rasmsg_type = ( ras_type ) ( pi - > msg_tag % 3 ) ;
}
else {
/* No SRT yet (ToDo) */
2015-08-03 17:30:04 +00:00
return FALSE ;
2015-06-23 00:51:20 +00:00
}
switch ( rasmsg_type ) {
case RAS_REQUEST :
if ( pi - > is_duplicate ) {
rs - > time_stats [ rascategory ] . req_dup_num + + ;
}
else {
rs - > time_stats [ rascategory ] . open_req_num + + ;
}
break ;
case RAS_CONFIRM :
/* no break - delay stats are identical for Confirm and Reject */
case RAS_REJECT :
if ( pi - > is_duplicate ) {
/* Duplicate is ignored */
rs - > time_stats [ rascategory ] . rsp_dup_num + + ;
}
else if ( ! pi - > request_available ) {
/* no request was seen, ignore response */
rs - > time_stats [ rascategory ] . disc_rsp_num + + ;
}
else {
rs - > time_stats [ rascategory ] . open_req_num - - ;
time_stat_update ( & ( rs - > time_stats [ rascategory ] . rtd [ 0 ] ) , & ( pi - > delta_time ) , pinfo ) ;
}
break ;
default :
2015-08-03 17:30:04 +00:00
return FALSE ;
2015-06-23 00:51:20 +00:00
}
2015-08-03 17:30:04 +00:00
return TRUE ;
2015-06-23 00:51:20 +00:00
}
2005-01-02 22:01:32 +00:00
# include "packet-h225-fn.c"
2006-08-28 07:05:02 +00:00
/* Forward declaration we need below */
void proto_reg_handoff_h225 ( void ) ;
2015-01-25 22:32:40 +00:00
/*
* Functions needed for Ras - Hash - Table
*/
/* compare 2 keys */
static gint h225ras_call_equal ( gconstpointer k1 , gconstpointer k2 )
{
const h225ras_call_info_key * key1 = ( const h225ras_call_info_key * ) k1 ;
const h225ras_call_info_key * key2 = ( const h225ras_call_info_key * ) k2 ;
return ( key1 - > reqSeqNum = = key2 - > reqSeqNum & &
key1 - > conversation = = key2 - > conversation ) ;
}
/* calculate a hash key */
static guint h225ras_call_hash ( gconstpointer k )
{
const h225ras_call_info_key * key = ( const h225ras_call_info_key * ) k ;
return key - > reqSeqNum + GPOINTER_TO_UINT ( key - > conversation ) ;
}
h225ras_call_t * find_h225ras_call ( h225ras_call_info_key * h225ras_call_key , int category )
{
h225ras_call_t * h225ras_call = NULL ;
h225ras_call = ( h225ras_call_t * ) g_hash_table_lookup ( ras_calls [ category ] , h225ras_call_key ) ;
return h225ras_call ;
}
h225ras_call_t * new_h225ras_call ( h225ras_call_info_key * h225ras_call_key , packet_info * pinfo , e_guid_t * guid , int category )
{
h225ras_call_info_key * new_h225ras_call_key ;
h225ras_call_t * h225ras_call = NULL ;
/* Prepare the value data.
" req_num " and " rsp_num " are frame numbers ;
frame numbers are 1 - origin , so we use 0
to mean " we don't yet know in which frame
the reply for this call appears " . */
new_h225ras_call_key = wmem_new ( wmem_file_scope ( ) , h225ras_call_info_key ) ;
new_h225ras_call_key - > reqSeqNum = h225ras_call_key - > reqSeqNum ;
new_h225ras_call_key - > conversation = h225ras_call_key - > conversation ;
h225ras_call = wmem_new ( wmem_file_scope ( ) , h225ras_call_t ) ;
h225ras_call - > req_num = pinfo - > fd - > num ;
h225ras_call - > rsp_num = 0 ;
h225ras_call - > requestSeqNum = h225ras_call_key - > reqSeqNum ;
h225ras_call - > responded = FALSE ;
h225ras_call - > next_call = NULL ;
h225ras_call - > req_time = pinfo - > fd - > abs_ts ;
h225ras_call - > guid = * guid ;
/* store it */
g_hash_table_insert ( ras_calls [ category ] , new_h225ras_call_key , h225ras_call ) ;
return h225ras_call ;
}
h225ras_call_t * append_h225ras_call ( h225ras_call_t * prev_call , packet_info * pinfo , e_guid_t * guid , int category _U_ )
{
h225ras_call_t * h225ras_call = NULL ;
/* Prepare the value data.
" req_num " and " rsp_num " are frame numbers ;
frame numbers are 1 - origin , so we use 0
to mean " we don't yet know in which frame
the reply for this call appears " . */
h225ras_call = wmem_new ( wmem_file_scope ( ) , h225ras_call_t ) ;
h225ras_call - > req_num = pinfo - > fd - > num ;
h225ras_call - > rsp_num = 0 ;
h225ras_call - > requestSeqNum = prev_call - > requestSeqNum ;
h225ras_call - > responded = FALSE ;
h225ras_call - > next_call = NULL ;
h225ras_call - > req_time = pinfo - > fd - > abs_ts ;
h225ras_call - > guid = * guid ;
prev_call - > next_call = h225ras_call ;
return h225ras_call ;
}
/* Init routine for hash tables and delay calculation
This routine will be called by Wireshark , before it
is ( re - ) dissecting a trace file from beginning .
We need to discard and init any state we ' ve saved */
2015-06-27 22:33:42 +00:00
static void
2015-01-25 22:32:40 +00:00
h225_init_routine ( void )
{
int i ;
2015-06-27 22:33:42 +00:00
/* create new hash-tables for RAS SRT */
2015-01-25 22:32:40 +00:00
for ( i = 0 ; i < 7 ; i + + ) {
2015-06-27 22:33:42 +00:00
ras_calls [ i ] = g_hash_table_new ( h225ras_call_hash , h225ras_call_equal ) ;
2015-01-25 22:32:40 +00:00
}
2015-06-27 22:33:42 +00:00
}
2015-01-25 22:32:40 +00:00
2015-06-27 22:33:42 +00:00
static void
h225_cleanup_routine ( void )
{
int i ;
/* free hash-tables for RAS SRT */
2015-01-25 22:32:40 +00:00
for ( i = 0 ; i < 7 ; i + + ) {
2015-06-27 22:33:42 +00:00
g_hash_table_destroy ( ras_calls [ i ] ) ;
2015-01-25 22:32:40 +00:00
}
}
2005-01-02 22:01:32 +00:00
static int
2012-09-10 21:40:21 +00:00
dissect_h225_H323UserInformation ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2005-01-02 22:01:32 +00:00
{
proto_item * it ;
proto_tree * tr ;
int offset = 0 ;
2008-11-04 22:01:35 +00:00
pi_current + + ;
if ( pi_current = = 5 ) {
pi_current = 0 ;
}
h225_pi = & pi_arr [ pi_current ] ;
2005-02-01 12:12:35 +00:00
2005-01-05 02:25:34 +00:00
/* Init struct for collecting h225_packet_info */
2008-11-04 22:01:35 +00:00
reset_h225_packet_info ( h225_pi ) ;
h225_pi - > msg_type = H225_CS ;
2005-01-05 02:25:34 +00:00
2005-09-22 14:40:26 +00:00
next_tvb_init ( & h245_list ) ;
next_tvb_init ( & tp_list ) ;
2010-01-13 21:27:44 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , PSNAME ) ;
2009-08-09 08:14:59 +00:00
col_clear ( pinfo - > cinfo , COL_INFO ) ;
2005-01-02 22:01:32 +00:00
2014-06-21 01:35:40 +00:00
it = proto_tree_add_protocol_format ( tree , proto_h225 , tvb , 0 , - 1 , PSNAME " CS " ) ;
2005-01-02 22:01:32 +00:00
tr = proto_item_add_subtree ( it , ett_h225 ) ;
2012-09-10 21:40:21 +00:00
offset = dissect_H323_UserInformation_PDU ( tvb , pinfo , tr , NULL ) ;
2005-01-02 22:01:32 +00:00
2010-01-13 21:27:44 +00:00
if ( h245_list . count ) {
2005-09-22 14:40:26 +00:00
col_append_str ( pinfo - > cinfo , COL_PROTOCOL , " / " ) ;
col_set_fence ( pinfo - > cinfo , COL_PROTOCOL ) ;
}
next_tvb_call ( & h245_list , pinfo , tree , h245dg_handle , data_handle ) ;
next_tvb_call ( & tp_list , pinfo , tree , NULL , data_handle ) ;
2005-02-01 12:12:35 +00:00
tap_queue_packet ( h225_tap , pinfo , h225_pi ) ;
2005-01-05 02:25:34 +00:00
2005-01-02 22:01:32 +00:00
return offset ;
}
static int
2012-09-10 21:40:21 +00:00
dissect_h225_h225_RasMessage ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ ) {
2005-01-02 22:01:32 +00:00
proto_item * it ;
proto_tree * tr ;
guint32 offset = 0 ;
2008-11-04 22:01:35 +00:00
pi_current + + ;
if ( pi_current = = 5 ) {
pi_current = 0 ;
}
h225_pi = & pi_arr [ pi_current ] ;
2005-02-01 12:12:35 +00:00
2005-01-02 22:01:32 +00:00
/* Init struct for collecting h225_packet_info */
2008-11-04 22:01:35 +00:00
reset_h225_packet_info ( h225_pi ) ;
h225_pi - > msg_type = H225_RAS ;
2005-01-02 22:01:32 +00:00
2010-01-13 21:27:44 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , PSNAME ) ;
2005-01-02 22:01:32 +00:00
2014-06-21 01:35:40 +00:00
it = proto_tree_add_protocol_format ( tree , proto_h225 , tvb , offset , - 1 , PSNAME " RAS " ) ;
2005-01-02 22:01:32 +00:00
tr = proto_item_add_subtree ( it , ett_h225 ) ;
2012-09-10 21:40:21 +00:00
offset = dissect_RasMessage_PDU ( tvb , pinfo , tr , NULL ) ;
2005-01-02 22:01:32 +00:00
2005-02-01 12:12:35 +00:00
ras_call_matching ( tvb , pinfo , tr , h225_pi ) ;
2005-01-02 22:01:32 +00:00
2005-02-01 12:12:35 +00:00
tap_queue_packet ( h225_tap , pinfo , h225_pi ) ;
2005-01-02 22:01:32 +00:00
return offset ;
}
2005-02-01 12:12:35 +00:00
2015-08-03 17:30:04 +00:00
/* The following values represent the size of their valuestring arrays */
# define RAS_MSG_TYPES (sizeof(h225_RasMessage_vals) / sizeof(value_string))
# define CS_MSG_TYPES (sizeof(T_h323_message_body_vals) / sizeof(value_string))
# define GRJ_REASONS (sizeof(GatekeeperRejectReason_vals) / sizeof(value_string))
# define RRJ_REASONS (sizeof(RegistrationRejectReason_vals) / sizeof(value_string))
# define URQ_REASONS (sizeof(UnregRequestReason_vals) / sizeof(value_string))
# define URJ_REASONS (sizeof(UnregRejectReason_vals) / sizeof(value_string))
# define ARJ_REASONS (sizeof(AdmissionRejectReason_vals) / sizeof(value_string))
# define BRJ_REASONS (sizeof(BandRejectReason_vals) / sizeof(value_string))
# define DRQ_REASONS (sizeof(DisengageReason_vals) / sizeof(value_string))
# define DRJ_REASONS (sizeof(DisengageRejectReason_vals) / sizeof(value_string))
# define LRJ_REASONS (sizeof(LocationRejectReason_vals) / sizeof(value_string))
# define IRQNAK_REASONS (sizeof(InfoRequestNakReason_vals) / sizeof(value_string))
# define REL_CMP_REASONS (sizeof(h225_ReleaseCompleteReason_vals) / sizeof(value_string))
# define FACILITY_REASONS (sizeof(FacilityReason_vals) / sizeof(value_string))
/* TAP STAT INFO */
typedef enum
{
MESSAGE_TYPE_COLUMN = 0 ,
COUNT_COLUMN
} h225_stat_columns ;
typedef struct _h225_table_item {
guint count ; /* Message count */
guint table_idx ; /* stat_table index */
} h225_table_item_t ;
static stat_tap_table_item h225_stat_fields [ ] = { { TABLE_ITEM_STRING , TAP_ALIGN_LEFT , " Message Type or Reason " , " %-25s " } , { TABLE_ITEM_UINT , TAP_ALIGN_RIGHT , " Count " , " %d " } } ;
static guint ras_msg_idx [ RAS_MSG_TYPES ] ;
static guint cs_msg_idx [ CS_MSG_TYPES ] ;
static guint grj_reason_idx [ GRJ_REASONS ] ;
static guint rrj_reason_idx [ RRJ_REASONS ] ;
static guint urq_reason_idx [ URQ_REASONS ] ;
static guint urj_reason_idx [ URJ_REASONS ] ;
static guint arj_reason_idx [ ARJ_REASONS ] ;
static guint brj_reason_idx [ BRJ_REASONS ] ;
static guint drq_reason_idx [ DRQ_REASONS ] ;
static guint drj_reason_idx [ DRJ_REASONS ] ;
static guint lrj_reason_idx [ LRJ_REASONS ] ;
static guint irqnak_reason_idx [ IRQNAK_REASONS ] ;
static guint rel_cmp_reason_idx [ REL_CMP_REASONS ] ;
static guint facility_reason_idx [ FACILITY_REASONS ] ;
static guint other_idx ;
2015-08-08 14:55:15 +00:00
static void h225_stat_init ( new_stat_tap_ui * new_stat , new_stat_tap_gui_init_cb gui_callback , void * gui_data )
2015-08-03 17:30:04 +00:00
{
int num_fields = sizeof ( h225_stat_fields ) / sizeof ( stat_tap_table_item ) ;
new_stat_tap_table * table = new_stat_tap_init_table ( " H.225 Messages and Message Reasons " , num_fields , 0 , NULL , gui_callback , gui_data ) ;
int row_idx = 0 , msg_idx ;
stat_tap_table_item_type items [ sizeof ( h225_stat_fields ) / sizeof ( stat_tap_table_item ) ] ;
new_stat_tap_add_table ( new_stat , table ) ;
items [ MESSAGE_TYPE_COLUMN ] . type = TABLE_ITEM_STRING ;
items [ COUNT_COLUMN ] . type = TABLE_ITEM_UINT ;
items [ COUNT_COLUMN ] . value . uint_value = 0 ;
/* Add a row for each value type */
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
h225_RasMessage_vals [ msg_idx ] . strptr
? h225_RasMessage_vals [ msg_idx ] . strptr
: " Unknown RAS message " ;
ras_msg_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( h225_RasMessage_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
T_h323_message_body_vals [ msg_idx ] . strptr
? T_h323_message_body_vals [ msg_idx ] . strptr
: " Unknown CS message " ;
cs_msg_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( T_h323_message_body_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
GatekeeperRejectReason_vals [ msg_idx ] . strptr
? GatekeeperRejectReason_vals [ msg_idx ] . strptr
: " Unknown gatekeeper reject reason " ;
grj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( GatekeeperRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
RegistrationRejectReason_vals [ msg_idx ] . strptr
? RegistrationRejectReason_vals [ msg_idx ] . strptr
: " Unknown registration reject reason " ;
rrj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( RegistrationRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
UnregRequestReason_vals [ msg_idx ] . strptr
? UnregRequestReason_vals [ msg_idx ] . strptr
: " Unknown unregistration request reason " ;
urq_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( UnregRequestReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
UnregRejectReason_vals [ msg_idx ] . strptr
? UnregRejectReason_vals [ msg_idx ] . strptr
: " Unknown unregistration reject reason " ;
urj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( UnregRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
AdmissionRejectReason_vals [ msg_idx ] . strptr
? AdmissionRejectReason_vals [ msg_idx ] . strptr
: " Unknown admission reject reason " ;
arj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( AdmissionRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
BandRejectReason_vals [ msg_idx ] . strptr
? BandRejectReason_vals [ msg_idx ] . strptr
: " Unknown band reject reason " ;
brj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( BandRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
DisengageReason_vals [ msg_idx ] . strptr
? DisengageReason_vals [ msg_idx ] . strptr
: " Unknown disengage reason " ;
drq_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( DisengageReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
DisengageRejectReason_vals [ msg_idx ] . strptr
? DisengageRejectReason_vals [ msg_idx ] . strptr
: " Unknown disengage reject reason " ;
drj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( DisengageRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
LocationRejectReason_vals [ msg_idx ] . strptr
? LocationRejectReason_vals [ msg_idx ] . strptr
: " Unknown location reject reason " ;
lrj_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( LocationRejectReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
InfoRequestNakReason_vals [ msg_idx ] . strptr
? InfoRequestNakReason_vals [ msg_idx ] . strptr
: " Unknown info request nak reason " ;
irqnak_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( InfoRequestNakReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
h225_ReleaseCompleteReason_vals [ msg_idx ] . strptr
? h225_ReleaseCompleteReason_vals [ msg_idx ] . strptr
: " Unknown release complete reason " ;
rel_cmp_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( h225_ReleaseCompleteReason_vals [ msg_idx ] . strptr ) ;
msg_idx = 0 ;
do
{
items [ MESSAGE_TYPE_COLUMN ] . value . string_value =
FacilityReason_vals [ msg_idx ] . strptr
? FacilityReason_vals [ msg_idx ] . strptr
: " Unknown facility reason " ;
facility_reason_idx [ msg_idx ] = row_idx ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
row_idx + + ;
msg_idx + + ;
} while ( FacilityReason_vals [ msg_idx ] . strptr ) ;
items [ MESSAGE_TYPE_COLUMN ] . value . string_value = " Unknown H.225 message " ;
new_stat_tap_init_table_row ( table , row_idx , num_fields , items ) ;
other_idx = row_idx ;
}
static gboolean
h225_stat_packet ( void * tapdata , packet_info * pinfo _U_ , epan_dissect_t * edt _U_ , const void * hpi_ptr )
{
new_stat_data_t * stat_data = ( new_stat_data_t * ) tapdata ;
const h225_packet_info * hpi = ( const h225_packet_info * ) hpi_ptr ;
int tag_idx = - 1 ;
int reason_idx = - 1 ;
if ( hpi - > msg_tag < 0 ) { /* uninitialized */
return FALSE ;
}
switch ( hpi - > msg_type ) {
case H225_RAS :
tag_idx = ras_msg_idx [ MIN ( hpi - > msg_tag , ( int ) RAS_MSG_TYPES - 1 ) ] ;
/* Look for reason tag */
if ( hpi - > reason < 0 ) { /* uninitialized */
break ;
}
switch ( hpi - > msg_tag ) {
case 2 : /* GRJ */
reason_idx = grj_reason_idx [ MIN ( hpi - > reason , ( int ) GRJ_REASONS - 1 ) ] ;
break ;
case 5 : /* RRJ */
reason_idx = rrj_reason_idx [ MIN ( hpi - > reason , ( int ) RRJ_REASONS - 1 ) ] ;
break ;
case 6 : /* URQ */
reason_idx = urq_reason_idx [ MIN ( hpi - > reason , ( int ) URQ_REASONS - 1 ) ] ;
break ;
case 8 : /* URJ */
reason_idx = urj_reason_idx [ MIN ( hpi - > reason , ( int ) URJ_REASONS - 1 ) ] ;
break ;
case 11 : /* ARJ */
reason_idx = arj_reason_idx [ MIN ( hpi - > reason , ( int ) ARJ_REASONS - 1 ) ] ;
break ;
case 14 : /* BRJ */
reason_idx = brj_reason_idx [ MIN ( hpi - > reason , ( int ) BRJ_REASONS - 1 ) ] ;
break ;
case 15 : /* DRQ */
reason_idx = drq_reason_idx [ MIN ( hpi - > reason , ( int ) DRQ_REASONS - 1 ) ] ;
break ;
case 17 : /* DRJ */
reason_idx = drj_reason_idx [ MIN ( hpi - > reason , ( int ) DRJ_REASONS - 1 ) ] ;
break ;
case 20 : /* LRJ */
reason_idx = lrj_reason_idx [ MIN ( hpi - > reason , ( int ) LRJ_REASONS - 1 ) ] ;
break ;
case 29 : /* IRQ Nak */
reason_idx = irqnak_reason_idx [ MIN ( hpi - > reason , ( int ) IRQNAK_REASONS - 1 ) ] ;
break ;
default :
/* do nothing */
break ;
}
break ;
case H225_CS :
tag_idx = cs_msg_idx [ MIN ( hpi - > msg_tag , ( int ) CS_MSG_TYPES - 1 ) ] ;
/* Look for reason tag */
if ( hpi - > reason < 0 ) { /* uninitialized */
break ;
}
switch ( hpi - > msg_tag ) {
case 5 : /* ReleaseComplete */
reason_idx = rel_cmp_reason_idx [ MIN ( hpi - > reason , ( int ) REL_CMP_REASONS - 1 ) ] ;
break ;
case 6 : /* Facility */
reason_idx = facility_reason_idx [ MIN ( hpi - > reason , ( int ) FACILITY_REASONS - 1 ) ] ;
break ;
default :
/* do nothing */
break ;
}
break ;
case H225_OTHERS :
default :
tag_idx = other_idx ;
}
if ( tag_idx > = 0 ) {
new_stat_tap_table * table = g_array_index ( stat_data - > new_stat_tap_data - > tables , new_stat_tap_table * , 0 ) ;
stat_tap_table_item_type * msg_data = new_stat_tap_get_field_data ( table , tag_idx , COUNT_COLUMN ) ; ;
msg_data - > value . uint_value + + ;
new_stat_tap_set_field_data ( table , tag_idx , COUNT_COLUMN , msg_data ) ;
if ( reason_idx > = 0 ) {
msg_data = new_stat_tap_get_field_data ( table , reason_idx , COUNT_COLUMN ) ; ;
msg_data - > value . uint_value + + ;
new_stat_tap_set_field_data ( table , reason_idx , COUNT_COLUMN , msg_data ) ;
}
return TRUE ;
}
return FALSE ;
}
static void
h225_stat_reset ( new_stat_tap_table * table )
{
guint element ;
stat_tap_table_item_type * item_data ;
for ( element = 0 ; element < table - > num_elements ; element + + )
{
item_data = new_stat_tap_get_field_data ( table , element , COUNT_COLUMN ) ;
item_data - > value . uint_value = 0 ;
new_stat_tap_set_field_data ( table , element , COUNT_COLUMN , item_data ) ;
}
}
2005-01-02 22:01:32 +00:00
/*--- proto_register_h225 -------------------------------------------*/
void proto_register_h225 ( void ) {
/* List of fields */
static hf_register_info hf [ ] = {
{ & hf_h221Manufacturer ,
2015-01-25 22:32:40 +00:00
{ " H.225 Manufacturer " , " h225.Manufacturer " , FT_UINT32 , BASE_HEX ,
VALS ( H221ManufacturerCode_vals ) , 0 , " h225.H.221 Manufacturer " , HFILL } } ,
2005-01-02 22:01:32 +00:00
{ & hf_h225_ras_req_frame ,
{ " RAS Request Frame " , " h225.ras.reqframe " , FT_FRAMENUM , BASE_NONE ,
2009-06-24 01:40:54 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-01-02 22:01:32 +00:00
{ & hf_h225_ras_rsp_frame ,
{ " RAS Response Frame " , " h225.ras.rspframe " , FT_FRAMENUM , BASE_NONE ,
2009-06-24 01:40:54 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-01-02 22:01:32 +00:00
{ & hf_h225_ras_dup ,
{ " Duplicate RAS Message " , " h225.ras.dup " , FT_UINT32 , BASE_DEC ,
2009-06-24 01:40:54 +00:00
NULL , 0 , NULL , HFILL } } ,
2005-01-02 22:01:32 +00:00
{ & hf_h225_ras_deltatime ,
{ " RAS Service Response Time " , " h225.ras.timedelta " , FT_RELATIVE_TIME , BASE_NONE ,
NULL , 0 , " Timedelta between RAS-Request and RAS-Response " , HFILL } } ,
2014-08-08 13:19:29 +00:00
{ & hf_h225_debug_dissector_try_string ,
{ " *** DEBUG dissector_try_string " , " h225.debug.dissector_try_string " , FT_STRING , BASE_NONE ,
NULL , 0 , NULL , HFILL } } ,
2005-01-02 22:01:32 +00:00
# include "packet-h225-hfarr.c"
2015-08-03 17:30:04 +00:00
} ;
2005-01-02 22:01:32 +00:00
/* List of subtrees */
2015-08-03 17:30:04 +00:00
static gint * ett [ ] = {
& ett_h225 ,
2005-01-02 22:01:32 +00:00
# include "packet-h225-ettarr.c"
2015-08-03 17:30:04 +00:00
} ;
static tap_param h225_stat_params [ ] = {
{ PARAM_FILTER , " filter " , " Filter " , NULL , TRUE }
} ;
static new_stat_tap_ui h225_stat_table = {
REGISTER_STAT_GROUP_TELEPHONY ,
" H.225 " ,
PFNAME ,
" h225,counter " ,
h225_stat_init ,
h225_stat_packet ,
h225_stat_reset ,
NULL ,
NULL ,
sizeof ( h225_stat_fields ) / sizeof ( stat_tap_table_item ) , h225_stat_fields ,
sizeof ( h225_stat_params ) / sizeof ( tap_param ) , h225_stat_params ,
NULL
} ;
2015-06-23 00:51:20 +00:00
module_t * h225_module ;
int proto_h225_ras ;
/* Register protocol */
proto_h225 = proto_register_protocol ( PNAME , PSNAME , PFNAME ) ;
/* Create a "fake" protocol to get proper display strings for SRT dialogs */
proto_h225_ras = proto_register_protocol ( " H.225 RAS " , " H.225 RAS " , " h225_ras " ) ;
/* Register fields and subtrees */
proto_register_field_array ( proto_h225 , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
h225_module = prefs_register_protocol ( proto_h225 , proto_reg_handoff_h225 ) ;
prefs_register_uint_preference ( h225_module , " tls.port " ,
" H.225 TLS Port " ,
" H.225 Server TLS Port " ,
10 , & h225_tls_port ) ;
prefs_register_bool_preference ( h225_module , " reassembly " ,
2005-01-02 22:01:32 +00:00
" Reassemble H.225 messages spanning multiple TCP segments " ,
" Whether the H.225 dissector should reassemble messages spanning multiple TCP segments. "
" To use this option, you must also enable \" Allow subdissectors to reassemble TCP streams \" in the TCP protocol settings. " ,
& h225_reassembly ) ;
2015-06-23 00:51:20 +00:00
prefs_register_bool_preference ( h225_module , " h245_in_tree " ,
2005-09-27 10:05:42 +00:00
" Display tunnelled H.245 inside H.225.0 tree " ,
" ON - display tunnelled H.245 inside H.225.0 tree, OFF - display tunnelled H.245 in root tree after H.225.0 " ,
& h225_h245_in_tree ) ;
2015-06-23 00:51:20 +00:00
prefs_register_bool_preference ( h225_module , " tp_in_tree " ,
2005-09-27 10:05:42 +00:00
" Display tunnelled protocols inside H.225.0 tree " ,
" ON - display tunnelled protocols inside H.225.0 tree, OFF - display tunnelled protocols in root tree after H.225.0 " ,
& h225_tp_in_tree ) ;
2005-01-02 22:01:32 +00:00
2015-08-03 17:30:04 +00:00
new_register_dissector ( PFNAME , dissect_h225_H323UserInformation , proto_h225 ) ;
2015-06-23 00:51:20 +00:00
new_register_dissector ( " h323ui " , dissect_h225_H323UserInformation , proto_h225 ) ;
new_register_dissector ( " h225.ras " , dissect_h225_h225_RasMessage , proto_h225 ) ;
2005-01-02 22:01:32 +00:00
2015-06-23 00:51:20 +00:00
nsp_object_dissector_table = register_dissector_table ( " h225.nsp.object " , " H.225 NonStandardParameter (object) " , FT_STRING , BASE_NONE ) ;
nsp_h221_dissector_table = register_dissector_table ( " h225.nsp.h221 " , " H.225 NonStandardParameter (h221) " , FT_UINT32 , BASE_HEX ) ;
tp_dissector_table = register_dissector_table ( " h225.tp " , " H.225 TunnelledProtocol " , FT_STRING , BASE_NONE ) ;
gef_name_dissector_table = register_dissector_table ( " h225.gef.name " , " H.225 Generic Extensible Framework (names) " , FT_STRING , BASE_NONE ) ;
gef_content_dissector_table = register_dissector_table ( " h225.gef.content " , " H.225 Generic Extensible Framework " , FT_STRING , BASE_NONE ) ;
2005-01-02 22:01:32 +00:00
2015-06-23 00:51:20 +00:00
register_init_routine ( & h225_init_routine ) ;
2015-06-27 22:33:42 +00:00
register_cleanup_routine ( & h225_cleanup_routine ) ;
2015-08-03 17:30:04 +00:00
h225_tap = register_tap ( PFNAME ) ;
register_rtd_table ( proto_h225_ras , PFNAME , NUM_RAS_STATS , 1 , ras_message_category , h225rassrt_packet , NULL ) ;
2005-01-02 22:01:32 +00:00
2015-08-03 17:30:04 +00:00
register_new_stat_tap_ui ( & h225_stat_table ) ;
2005-01-02 22:01:32 +00:00
2015-06-23 00:51:20 +00:00
oid_add_from_string ( " Version 1 " , " 0.0.8.2250.0.1 " ) ;
oid_add_from_string ( " Version 2 " , " 0.0.8.2250.0.2 " ) ;
oid_add_from_string ( " Version 3 " , " 0.0.8.2250.0.3 " ) ;
oid_add_from_string ( " Version 4 " , " 0.0.8.2250.0.4 " ) ;
oid_add_from_string ( " Version 5 " , " 0.0.8.2250.0.5 " ) ;
oid_add_from_string ( " Version 6 " , " 0.0.8.2250.0.6 " ) ;
2005-01-02 22:01:32 +00:00
}
/*--- proto_reg_handoff_h225 ---------------------------------------*/
void
proto_reg_handoff_h225 ( void )
{
2006-08-28 07:05:02 +00:00
static gboolean h225_prefs_initialized = FALSE ;
2008-11-04 22:01:35 +00:00
static dissector_handle_t h225ras_handle ;
static guint saved_h225_tls_port ;
if ( ! h225_prefs_initialized ) {
h225ras_handle = find_dissector ( " h225.ras " ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " udp.port " , UDP_PORT_RAS1 , h225ras_handle ) ;
dissector_add_uint ( " udp.port " , UDP_PORT_RAS2 , h225ras_handle ) ;
2008-11-04 22:01:35 +00:00
h245_handle = find_dissector ( " h245 " ) ;
h245dg_handle = find_dissector ( " h245dg " ) ;
h4501_handle = find_dissector ( " h4501 " ) ;
data_handle = find_dissector ( " data " ) ;
h225_prefs_initialized = TRUE ;
} else {
ssl_dissector_delete ( saved_h225_tls_port , " q931.tpkt " , TRUE ) ;
}
2006-08-28 07:05:02 +00:00
2008-11-04 22:01:35 +00:00
saved_h225_tls_port = h225_tls_port ;
ssl_dissector_add ( saved_h225_tls_port , " q931.tpkt " , TRUE ) ;
2005-01-02 22:01:32 +00:00
}
static void reset_h225_packet_info ( h225_packet_info * pi )
{
if ( pi = = NULL ) {
return ;
}
pi - > msg_type = H225_OTHERS ;
pi - > cs_type = H225_OTHER ;
pi - > msg_tag = - 1 ;
pi - > reason = - 1 ;
pi - > requestSeqNum = 0 ;
2006-03-19 20:45:45 +00:00
memset ( & pi - > guid , 0 , sizeof pi - > guid ) ;
2005-01-02 22:01:32 +00:00
pi - > is_duplicate = FALSE ;
pi - > request_available = FALSE ;
pi - > is_faststart = FALSE ;
pi - > is_h245 = FALSE ;
2005-02-01 12:12:35 +00:00
pi - > is_h245Tunneling = FALSE ;
2005-01-02 22:01:32 +00:00
pi - > h245_address = 0 ;
pi - > h245_port = 0 ;
2005-02-01 12:12:35 +00:00
pi - > frame_label [ 0 ] = ' \0 ' ;
2005-02-07 21:09:23 +00:00
pi - > dialedDigits [ 0 ] = ' \0 ' ;
pi - > is_destinationInfo = FALSE ;
2005-01-02 22:01:32 +00:00
}
/*
The following function contains the routines for RAS request / response matching .
A RAS response matches with a request , if both messages have the same
RequestSequenceNumber , belong to the same IP conversation and belong to the same
RAS " category " ( e . g . Admission , Registration ) .
We use hashtables to access the lists of RAS calls ( request / response pairs ) .
We have one hashtable for each RAS category . The hashkeys consist of the
non - unique 16 - bit RequestSequenceNumber and values representing the conversation .
In big capture files , we might get different requests with identical keys .
These requests aren ' t necessarily duplicates . They might be valid new requests .
At the moment we just use the timedelta between the last valid and the new request
to decide if the new request is a duplicate or not . There might be better ways .
Two thresholds are defined below .
However the decision is made , another problem arises . We can ' t just add those
requests to our hashtables . Instead we create lists of RAS calls with identical keys .
The hashtables for RAS calls contain now pointers to the first RAS call in a list of
RAS calls with identical keys .
These lists aren ' t expected to contain more than 3 items and are usually single item
lists . So we don ' t need an expensive but intelligent way to access these lists
( e . g . hashtables ) . Just walk through such a list .
*/
# define THRESHOLD_REPEATED_RESPONDED_CALL 300
# define THRESHOLD_REPEATED_NOT_RESPONDED_CALL 1800
static void ras_call_matching ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , h225_packet_info * pi )
{
2008-05-21 05:41:39 +00:00
proto_item * hidden_item ;
2005-01-02 22:01:32 +00:00
conversation_t * conversation = NULL ;
h225ras_call_info_key h225ras_call_key ;
h225ras_call_t * h225ras_call = NULL ;
nstime_t delta ;
guint msg_category ;
if ( pi - > msg_type = = H225_RAS & & pi - > msg_tag < 21 ) {
/* make RAS request/response matching only for tags from 0 to 20 for now */
msg_category = pi - > msg_tag / 3 ;
if ( pi - > msg_tag % 3 = = 0 ) { /* Request Message */
2010-05-13 18:55:31 +00:00
conversation = find_or_create_conversation ( pinfo ) ;
2005-01-02 22:01:32 +00:00
/* prepare the key data */
h225ras_call_key . reqSeqNum = pi - > requestSeqNum ;
h225ras_call_key . conversation = conversation ;
/* look up the request */
h225ras_call = find_h225ras_call ( & h225ras_call_key , msg_category ) ;
if ( h225ras_call ! = NULL ) {
/* We've seen requests with this reqSeqNum, with the same
source and destination , before - do we have
* this * request already ? */
/* Walk through list of ras requests with identical keys */
do {
if ( pinfo - > fd - > num = = h225ras_call - > req_num ) {
/* We have seen this request before -> do nothing */
break ;
}
/* if end of list is reached, exit loop and decide if request is duplicate or not. */
if ( h225ras_call - > next_call = = NULL ) {
if ( ( pinfo - > fd - > num > h225ras_call - > rsp_num & & h225ras_call - > rsp_num ! = 0
2005-08-26 12:15:49 +00:00
& & pinfo - > fd - > abs_ts . secs > ( h225ras_call - > req_time . secs + THRESHOLD_REPEATED_RESPONDED_CALL ) )
2005-01-02 22:01:32 +00:00
| | ( pinfo - > fd - > num > h225ras_call - > req_num & & h225ras_call - > rsp_num = = 0
2005-08-26 12:15:49 +00:00
& & pinfo - > fd - > abs_ts . secs > ( h225ras_call - > req_time . secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL ) ) )
2005-01-02 22:01:32 +00:00
{
/* if last request has been responded
and this request appears after last response ( has bigger frame number )
2013-02-26 04:42:26 +00:00
and last request occurred more than 300 seconds ago ,
2005-01-02 22:01:32 +00:00
or if last request hasn ' t been responded
and this request appears after last request ( has bigger frame number )
2013-02-26 04:42:26 +00:00
and last request occurred more than 1800 seconds ago ,
2005-01-02 22:01:32 +00:00
we decide that we have a new request */
/* Append new ras call to list */
2006-03-19 20:45:45 +00:00
h225ras_call = append_h225ras_call ( h225ras_call , pinfo , & pi - > guid , msg_category ) ;
2005-01-02 22:01:32 +00:00
} else {
/* No, so it's a duplicate request.
Mark it as such . */
pi - > is_duplicate = TRUE ;
2008-05-21 05:41:39 +00:00
hidden_item = proto_tree_add_uint ( tree , hf_h225_ras_dup , tvb , 0 , 0 , pi - > requestSeqNum ) ;
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2005-01-02 22:01:32 +00:00
}
break ;
}
h225ras_call = h225ras_call - > next_call ;
} while ( h225ras_call ! = NULL ) ;
}
else {
2006-03-19 20:45:45 +00:00
h225ras_call = new_h225ras_call ( & h225ras_call_key , pinfo , & pi - > guid , msg_category ) ;
2005-01-02 22:01:32 +00:00
}
/* add link to response frame, if available */
2009-08-05 00:36:27 +00:00
if ( h225ras_call & & h225ras_call - > rsp_num ! = 0 ) {
2005-01-02 22:01:32 +00:00
proto_item * ti =
proto_tree_add_uint_format ( tree , hf_h225_ras_rsp_frame , tvb , 0 , 0 , h225ras_call - > rsp_num ,
" The response to this request is in frame %u " ,
h225ras_call - > rsp_num ) ;
PROTO_ITEM_SET_GENERATED ( ti ) ;
}
/* end of request message handling*/
}
else { /* Confirm or Reject Message */
2005-02-02 20:02:46 +00:00
conversation = find_conversation ( pinfo - > fd - > num , & pinfo - > src ,
2005-01-02 22:01:32 +00:00
& pinfo - > dst , pinfo - > ptype , pinfo - > srcport ,
pinfo - > destport , 0 ) ;
if ( conversation ! = NULL ) {
/* look only for matching request, if
matching conversation is available . */
h225ras_call_key . reqSeqNum = pi - > requestSeqNum ;
h225ras_call_key . conversation = conversation ;
h225ras_call = find_h225ras_call ( & h225ras_call_key , msg_category ) ;
if ( h225ras_call ) {
/* find matching ras_call in list of ras calls with identical keys */
do {
if ( pinfo - > fd - > num = = h225ras_call - > rsp_num ) {
/* We have seen this response before -> stop now with matching ras call */
break ;
}
/* Break when list end is reached */
if ( h225ras_call - > next_call = = NULL ) {
break ;
}
h225ras_call = h225ras_call - > next_call ;
} while ( h225ras_call ! = NULL ) ;
2010-05-13 18:55:31 +00:00
2009-08-05 00:36:27 +00:00
if ( ! h225ras_call ) {
return ;
}
2005-01-02 22:01:32 +00:00
/* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
if ( msg_category = = 3 | | msg_category = = 5 ) {
2006-03-19 20:45:45 +00:00
pi - > guid = h225ras_call - > guid ;
2008-05-21 05:41:39 +00:00
hidden_item = proto_tree_add_guid ( tree , hf_h225_guid , tvb , 0 , GUID_LEN , & pi - > guid ) ;
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2005-01-02 22:01:32 +00:00
}
if ( h225ras_call - > rsp_num = = 0 ) {
/* We have not yet seen a response to that call, so
this must be the first response ; remember its
frame number . */
h225ras_call - > rsp_num = pinfo - > fd - > num ;
}
else {
/* We have seen a response to this call - but was it
* this * response ? */
if ( h225ras_call - > rsp_num ! = pinfo - > fd - > num ) {
/* No, so it's a duplicate response.
Mark it as such . */
pi - > is_duplicate = TRUE ;
2008-05-21 05:41:39 +00:00
hidden_item = proto_tree_add_uint ( tree , hf_h225_ras_dup , tvb , 0 , 0 , pi - > requestSeqNum ) ;
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2005-01-02 22:01:32 +00:00
}
}
if ( h225ras_call - > req_num ! = 0 ) {
proto_item * ti ;
h225ras_call - > responded = TRUE ;
pi - > request_available = TRUE ;
/* Indicate the frame to which this is a reply. */
ti = proto_tree_add_uint_format ( tree , hf_h225_ras_req_frame , tvb , 0 , 0 , h225ras_call - > req_num ,
" This is a response to a request in frame %u " , h225ras_call - > req_num ) ;
PROTO_ITEM_SET_GENERATED ( ti ) ;
/* Calculate RAS Service Response Time */
2005-08-26 12:15:49 +00:00
nstime_delta ( & delta , & pinfo - > fd - > abs_ts , & h225ras_call - > req_time ) ;
pi - > delta_time = delta ; /* give it to tap */
2005-01-02 22:01:32 +00:00
/* display Ras Service Response Time and make it filterable */
ti = proto_tree_add_time ( tree , hf_h225_ras_deltatime , tvb , 0 , 0 , & ( pi - > delta_time ) ) ;
PROTO_ITEM_SET_GENERATED ( ti ) ;
}
}
}
}
}
}