From Lars Roland: H.225 message and reason tag counter taps.

svn path=/trunk/; revision=8794
This commit is contained in:
Guy Harris 2003-10-28 00:31:17 +00:00
parent a1f7d525b7
commit 1c5ed66f45
11 changed files with 1669 additions and 21 deletions

View File

@ -1680,6 +1680,7 @@ Laurent Meyer <laurent.meyer6 [AT] wanadoo.fr> {
Lars Roland <Lars.Roland [AT] gmx.net> {
MGCP request/response matching and MGCP statistics tap
Common routines for use by statistics taps
H.225 message and reason tag counter taps
}
Miha Jemec <m.jemec [AT] iskratel.si> {

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.644 2003/10/27 23:31:53 guy Exp $
# $Id: Makefile.am,v 1.645 2003/10/28 00:31:15 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -901,6 +901,7 @@ ethereal_LDADD = \
TETHEREAL_TAP_SRC = \
tap-bootpstat.c \
tap-dcerpcstat.c \
tap-h225counter.c \
tap-httpstat.c \
tap-iostat.c \
tap-iousers.c \

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.351 2003/10/27 23:31:54 guy Exp $
# $Id: Makefile.nmake,v 1.352 2003/10/28 00:31:15 guy Exp $
include config.nmake
include <win32.mak>
@ -405,6 +405,7 @@ DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj)
TETHEREAL_TAP_SRC = \
tap-bootpstat.c \
tap-dcerpcstat.c \
tap-h225counter.c \
tap-httpstat.c \
tap-iostat.c \
tap-iousers.c \

View File

@ -405,6 +405,22 @@ of frames.
These tables can also be generated at runtime by selecting the appropriate
conversation type from the menu "Tools/Statistics/Conversation List/".
B<-z> h225,counter[I<,filter>]
Count ITU-T H.225 messages and their reasons. In the first column you get a
list of H.225 messages and H.225 message reasons, which occur in the current
capture file. The number of occurences of each message or reason is displayed
in the second column.
Example: use B<-z h225,counter>.
This option can be used multiple times on the command line.
If the optional filterstring is provided, the stats will only be calculated
on those calls that match that filter.
Example: use B<-z "h225,counter,ip.addr==1.2.3.4"> to only collect stats for
H.225 packets exchanged by the host at IP address 1.2.3.4 .
=back
=head1 INTERFACE
@ -1024,6 +1040,19 @@ You can apply an optional filter string in a dialog box, before starting
the calculation. The statistics will only be calculated
on those calls matching that filter.
=item Tools:Statistics:Watch protocol:ITU-T H.225
Count ITU-T H.225 messages and their reasons. In the first column you get a
list of H.225 messages and H.225 message reasons, which occur in the current
capture file. The number of occurences of each message or reason will be displayed
in the second column.
This window opened will update in semi-real time to reflect changes when
doing live captures or when reading new capture files into B<Ethereal>.
You can apply an optional filter string in a dialog box, before starting
the counter. The statistics will only be calculated
on those calls matching that filter.
=back
=head2 WINDOWS

View File

@ -584,6 +584,22 @@ on those calls that match that filter.
Example: use B<-z "mgcp,rtd,ip.addr==1.2.3.4"> to only collect stats for
MGCP packets exchanged by the host at IP address 1.2.3.4 .
B<-z> h225,counter[I<,filter>]
Count ITU-T H.225 messages and their reasons. In the first column you get a
list of H.225 messages and H.225 message reasons, which occur in the current
capture file. The number of occurences of each message or reason is displayed
in the second column.
Example: use B<-z h225,counter>.
This option can be used multiple times on the command line.
If the optional filterstring is provided, the stats will only be calculated
on those calls that match that filter.
Example: use B<-z "h225,counter,ip.addr==1.2.3.4"> to only collect stats for
H.225 packets exchanged by the host at IP address 1.2.3.4 .
=back
=head1 CAPTURE FILTER SYNTAX

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for the GTK interface routines for Ethereal
#
# $Id: Makefile.am,v 1.71 2003/10/15 19:40:39 guy Exp $
# $Id: Makefile.am,v 1.72 2003/10/28 00:31:17 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -39,6 +39,7 @@ ETHEREAL_TAP_SRC = \
endpoint_talkers_tr.c \
endpoint_talkers_udpip.c \
fc_stat.c \
h225_counter.c \
http_stat.c \
io_stat.c \
mgcp_stat.c \

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.55 2003/10/15 19:40:40 guy Exp $
# $Id: Makefile.nmake,v 1.56 2003/10/28 00:31:17 guy Exp $
include ..\config.nmake
@ -31,6 +31,7 @@ ETHEREAL_TAP_SRC = \
endpoint_talkers_tr.c \
endpoint_talkers_udpip.c \
fc_stat.c \
h225_counter.c \
http_stat.c \
io_stat.c \
mgcp_stat.c \

879
gtk/h225_counter.c Normal file
View File

@ -0,0 +1,879 @@
/* h225_counter.c
* h225 message counter for ethereal
* Copyright 2003 Lars Roland
*
* $Id: h225_counter.c,v 1.1 2003/10/28 00:31:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <gtk/gtk.h>
#include <string.h>
#include "../epan/packet_info.h"
#include "../epan/epan.h"
#include "menu.h"
#include "../tap.h"
#include "../epan/value_string.h"
#include "../register.h"
#include "../packet-h225.h"
#include "gtk_stat_util.h"
#include "compat_macros.h"
#include "../simple_dialog.h"
#include "dlg_utils.h"
#include "../file.h"
#include "../globals.h"
extern GtkWidget *main_display_filter_widget;
static GtkWidget *dlg=NULL;
static GtkWidget *filter_entry;
/* following values represent the size of their valuestring arrays */
#define RAS_MSG_TYPES 33
#define CS_MSG_TYPES 13
#define GRJ_REASONS 8
#define RRJ_REASONS 18
#define URQ_REASONS 6
#define URJ_REASONS 6
#define ARJ_REASONS 22
#define BRJ_REASONS 8
#define DRQ_REASONS 3
#define DRJ_REASONS 4
#define LRJ_REASONS 16
#define IRQNAK_REASONS 4
#define REL_CMP_REASONS 26
#define FACILITY_REASONS 11
static const value_string RasMessage_vals[] = {
{ 0, "gatekeeperRequest" },
{ 1, "gatekeeperConfirm" },
{ 2, "gatekeeperReject" },
{ 3, "registrationRequest" },
{ 4, "registrationConfirm" },
{ 5, "registrationReject" },
{ 6, "unregistrationRequest" },
{ 7, "unregistrationConfirm" },
{ 8, "unregistrationReject" },
{ 9, "admissionRequest" },
{10, "admissionConfirm" },
{11, "admissionReject" },
{12, "bandwidthRequest" },
{13, "bandwidthConfirm" },
{14, "bandwidthReject" },
{15, "disengageRequest" },
{16, "disengageConfirm" },
{17, "disengageReject" },
{18, "locationRequest" },
{19, "locationConfirm" },
{20, "locationReject" },
{21, "infoRequest" },
{22, "infoRequestResponse" },
{23, "nonStandardMessage" },
{24, "unknownMessageResponse" },
{25, "requestInProgress" },
{26, "resourcesAvailableIndicate" },
{27, "resourcesAvailableConfirm" },
{28, "infoRequestAck" },
{29, "infoRequestNak" },
{30, "serviceControlIndication" },
{31, "serviceControlResponse" },
{32, "admissionConfirmSequence" },
{ 0, NULL}
};
static const value_string h323_message_body_vals[] = {
{ 0, "setup" },
{ 1, "callProceeding" },
{ 2, "connect" },
{ 3, "alerting" },
{ 4, "information" },
{ 5, "releaseComplete" },
{ 6, "facility" },
{ 7, "progress" },
{ 8, "empty" },
{ 9, "status" },
{ 10, "statusInquiry" },
{ 11, "setupAcknowledge" },
{ 12, "notify" },
{ 0, NULL}
};
static const value_string FacilityReason_vals[] = {
{ 0, "routeCallToGatekeeper" },
{ 1, "callForwarded" },
{ 2, "routeCallToMC" },
{ 3, "undefinedReason" },
{ 4, "conferenceListChoice" },
{ 5, "startH245" },
{ 6, "noH245" },
{ 7, "newTokens" },
{ 8, "featureSetUpdate" },
{ 9, "forwardedElements" },
{ 10, "transportedInformation" },
{ 0, NULL}
};
static const value_string GatekeeperRejectReason_vals[] = {
{ 0, "resourceUnavailable" },
{ 1, "terminalExcluded" },
{ 2, "invalidRevision" },
{ 3, "undefinedReason" },
{ 4, "securityDenial" },
{ 5, "genericDataReason" },
{ 6, "neededFeatureNotSupported" },
{ 7, "securityError" },
{ 0, NULL}
};
static const value_string UnregRequestReason_vals[] = {
{ 0, "reregistrationRequired" },
{ 1, "ttlExpired" },
{ 2, "securityDenial" },
{ 3, "undefinedReason" },
{ 4, "maintenance" },
{ 5, "securityError" },
{ 0, NULL}
};
static const value_string UnregRejectReason_vals[] = {
{ 0, "notCurrentlyRegistered" },
{ 1, "callInProgress" },
{ 2, "undefinedReason" },
{ 3, "permissionDenied" },
{ 4, "securityDenial" },
{ 5, "securityError" },
{ 0, NULL}
};
static const value_string BandRejectReason_vals[] = {
{ 0, "notBound" },
{ 1, "invalidConferenceID" },
{ 2, "invalidPermission" },
{ 3, "insufficientResources" },
{ 4, "invalidRevision" },
{ 5, "undefinedReason" },
{ 6, "securityDenial" },
{ 7, "securityError" },
{ 0, NULL}
};
static const value_string DisengageReason_vals[] = {
{ 0, "forcedDrop" },
{ 1, "normalDrop" },
{ 2, "undefinedReason" },
{ 0, NULL}
};
static const value_string DisengageRejectReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "requestToDropOther" },
{ 2, "securityDenial" },
{ 3, "securityError" },
{ 0, NULL}
};
static const value_string InfoRequestNakReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "securityDenial" },
{ 2, "undefinedReason" },
{ 3, "securityError" },
{ 0, NULL}
};
static const value_string ReleaseCompleteReason_vals[] = {
{ 0, "noBandwidth" },
{ 1, "gatekeeperResources" },
{ 2, "unreachableDestination" },
{ 3, "destinationRejection" },
{ 4, "invalidRevision" },
{ 5, "noPermission" },
{ 6, "unreachableGatekeeper" },
{ 7, "gatewayResources" },
{ 8, "badFormatAddress" },
{ 9, "adaptiveBusy" },
{ 10, "inConf" },
{ 11, "undefinedReason" },
{ 12, "facilityCallDeflection" },
{ 13, "securityDenied" },
{ 14, "calledPartyNotRegistered" },
{ 15, "callerNotRegistered" },
{ 16, "newConnectionNeeded" },
{ 17, "nonStandardReason" },
{ 18, "replaceWithConferenceInvite" },
{ 19, "genericDataReason" },
{ 20, "neededFeatureNotSupported" },
{ 21, "tunnelledSignallingRejected" },
{ 22, "invalidCID" },
{ 23, "invalidCID" },
{ 24, "securityError" },
{ 25, "hopCountExceeded" },
{ 0, NULL}
};
static const value_string AdmissionRejectReason_vals[] = {
{ 0, "calledPartyNotRegistered" },
{ 1, "invalidPermission" },
{ 2, "requestDenied" },
{ 3, "undefinedReason" },
{ 4, "callerNotRegistered" },
{ 5, "routeCallToGatekeeper" },
{ 6, "invalidEndpointIdentifier" },
{ 7, "resourceUnavailable" },
{ 8, "securityDenial" },
{ 9, "qosControlNotSupported" },
{ 10, "incompleteAddress" },
{ 11, "aliasesInconsistent" },
{ 12, "routeCallToSCN" },
{ 13, "exceedsCallCapacity" },
{ 14, "collectDestination" },
{ 15, "collectPIN" },
{ 16, "genericDataReason" },
{ 17, "neededFeatureNotSupported" },
{ 18, "securityErrors" },
{ 19, "securityDHmismatch" },
{ 20, "noRouteToDestination" },
{ 21, "unallocatedNumber" },
{ 0, NULL}
};
static const value_string LocationRejectReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "invalidPermission" },
{ 2, "requestDenied" },
{ 3, "undefinedReason" },
{ 4, "securityDenial" },
{ 5, "aliasesInconsistent" },
{ 6, "routeCalltoSCN" },
{ 7, "resourceUnavailable" },
{ 8, "genericDataReason" },
{ 9, "neededFeatureNotSupported" },
{10, "hopCountExceeded" },
{11, "incompleteAddress" },
{12, "securityError" },
{13, "securityDHmismatch" },
{14, "noRouteToDestination" },
{15, "unallocatedNumber" },
{ 0, NULL}
};
static const value_string RegistrationRejectReason_vals[] = {
{ 0, "discoveryRequired" },
{ 1, "invalidRevision" },
{ 2, "invalidCallSignalAddress" },
{ 3, "invalidRASAddress" },
{ 4, "duplicateAlias" },
{ 5, "invalidTerminalType" },
{ 6, "undefinedReason" },
{ 7, "transportNotSupported" },
{ 8, "transportQOSNotSupported" },
{ 9, "resourceUnavailable" },
{ 10, "invalidAlias" },
{ 11, "securityDenial" },
{ 12, "fullRegistrationRequired" },
{ 13, "additiveRegistrationNotSupported" },
{ 14, "invalidTerminalAliases" },
{ 15, "genericDataReason" },
{ 16, "neededFeatureNotSupported" },
{ 17, "securityError" },
{ 0, NULL}
};
/* used to keep track of the statistics for an entire program interface */
typedef struct _h225counter_t {
GtkWidget *win;
GtkWidget *vbox;
char *filter;
GtkWidget *scrolled_window;
GtkCList *table;
guint32 ras_msg[RAS_MSG_TYPES + 1];
guint32 cs_msg[CS_MSG_TYPES + 1];
guint32 grj_reason[GRJ_REASONS + 1];
guint32 rrj_reason[RRJ_REASONS + 1];
guint32 urq_reason[URQ_REASONS + 1];
guint32 urj_reason[URJ_REASONS + 1];
guint32 arj_reason[ARJ_REASONS + 1];
guint32 brj_reason[BRJ_REASONS + 1];
guint32 drq_reason[DRQ_REASONS + 1];
guint32 drj_reason[DRJ_REASONS + 1];
guint32 lrj_reason[LRJ_REASONS + 1];
guint32 irqnak_reason[IRQNAK_REASONS + 1];
guint32 rel_cmp_reason[REL_CMP_REASONS + 1];
guint32 facility_reason[FACILITY_REASONS + 1];
} h225counter_t;
static void
h225counter_reset(void *phs)
{
h225counter_t *hs=(h225counter_t *)phs;
int i;
for(i=0;i<=RAS_MSG_TYPES;i++) {
hs->ras_msg[i] = 0;
}
for(i=0;i<=CS_MSG_TYPES;i++) {
hs->cs_msg[i] = 0;
}
for(i=0;i<=GRJ_REASONS;i++) {
hs->grj_reason[i] = 0;
}
for(i=0;i<=RRJ_REASONS;i++) {
hs->rrj_reason[i] = 0;
}
for(i=0;i<=URQ_REASONS;i++) {
hs->urq_reason[i] = 0;
}
for(i=0;i<=URJ_REASONS;i++) {
hs->urj_reason[i] = 0;
}
for(i=0;i<=ARJ_REASONS;i++) {
hs->arj_reason[i] = 0;
}
for(i=0;i<=BRJ_REASONS;i++) {
hs->brj_reason[i] = 0;
}
for(i=0;i<=DRQ_REASONS;i++) {
hs->drq_reason[i] = 0;
}
for(i=0;i<=DRJ_REASONS;i++) {
hs->drj_reason[i] = 0;
}
for(i=0;i<=LRJ_REASONS;i++) {
hs->lrj_reason[i] = 0;
}
for(i=0;i<=IRQNAK_REASONS;i++) {
hs->irqnak_reason[i] = 0;
}
for(i=0;i<=REL_CMP_REASONS;i++) {
hs->rel_cmp_reason[i] = 0;
}
for(i=0;i<=FACILITY_REASONS;i++) {
hs->facility_reason[i] = 0;
}
}
static int
h225counter_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
{
h225counter_t *hs=(h225counter_t *)phs;
h225_packet_info *pi=phi;
switch (pi->msg_type) {
case H225_RAS:
if(pi->msg_tag==-1) { /* uninitialized */
return 0;
}
else if (pi->msg_tag >= RAS_MSG_TYPES) { /* unknown */
hs->ras_msg[RAS_MSG_TYPES]++;
}
else {
hs->ras_msg[pi->msg_tag]++;
}
/* Look for reason tag */
if(pi->reason==-1) { /* uninitialized */
break;
}
switch(pi->msg_tag) {
case 2: /* GRJ */
if(pi->reason < GRJ_REASONS)
hs->grj_reason[pi->reason]++;
else
hs->grj_reason[GRJ_REASONS]++;
break;
case 5: /* RRJ */
if(pi->reason < RRJ_REASONS)
hs->rrj_reason[pi->reason]++;
else
hs->rrj_reason[RRJ_REASONS]++;
break;
case 6: /* URQ */
if(pi->reason < URQ_REASONS)
hs->urq_reason[pi->reason]++;
else
hs->urq_reason[URQ_REASONS]++;
break;
case 8: /* URJ */
if(pi->reason < URJ_REASONS)
hs->urj_reason[pi->reason]++;
else
hs->urj_reason[URJ_REASONS]++;
break;
case 11: /* ARJ */
if(pi->reason < ARJ_REASONS)
hs->arj_reason[pi->reason]++;
else
hs->arj_reason[ARJ_REASONS]++;
break;
case 14: /* BRJ */
if(pi->reason < BRJ_REASONS)
hs->brj_reason[pi->reason]++;
else
hs->brj_reason[BRJ_REASONS]++;
break;
case 15: /* DRQ */
if(pi->reason < DRQ_REASONS)
hs->drq_reason[pi->reason]++;
else
hs->drq_reason[DRQ_REASONS]++;
break;
case 17: /* DRJ */
if(pi->reason < DRJ_REASONS)
hs->drj_reason[pi->reason]++;
else
hs->drj_reason[DRJ_REASONS]++;
break;
case 20: /* LRJ */
if(pi->reason < LRJ_REASONS)
hs->lrj_reason[pi->reason]++;
else
hs->lrj_reason[LRJ_REASONS]++;
break;
case 29: /* IRQ Nak */
if(pi->reason < IRQNAK_REASONS)
hs->irqnak_reason[pi->reason]++;
else
hs->irqnak_reason[IRQNAK_REASONS]++;
break;
default:
/* do nothing */
break;
}
break;
case H225_CS:
if(pi->msg_tag==-1) { /* uninitialized */
return 0;
}
else if (pi->msg_tag >= CS_MSG_TYPES) { /* unknown */
hs->cs_msg[CS_MSG_TYPES]++;
}
else {
hs->cs_msg[pi->msg_tag]++;
}
/* Look for reason tag */
if(pi->reason==-1) { /* uninitialized */
break;
}
switch(pi->msg_tag) {
case 5: /* ReleaseComplete */
if(pi->reason < REL_CMP_REASONS)
hs->rel_cmp_reason[pi->reason]++;
else
hs->rel_cmp_reason[REL_CMP_REASONS]++;
break;
case 6: /* Facility */
if(pi->reason < FACILITY_REASONS)
hs->facility_reason[pi->reason]++;
else
hs->facility_reason[FACILITY_REASONS]++;
break;
default:
/* do nothing */
break;
}
break;
default:
return 0;
break;
}
return 1;
}
static void
h225counter_draw(void *phs)
{
h225counter_t *hs=(h225counter_t *)phs;
int i,j;
char *str[2];
for(i=0;i<2;i++) {
str[i]=g_malloc(sizeof(char[256]));
}
/* Now print Message and Reason Counter Table */
/* clear list before printing */
gtk_clist_clear(hs->table);
for(i=0;i<=RAS_MSG_TYPES;i++) {
if(hs->ras_msg[i]!=0) {
sprintf(str[0], "%s", val_to_str(i,RasMessage_vals,"unknown ras-messages "));
sprintf(str[1], "%d", hs->ras_msg[i]);
gtk_clist_append(hs->table, str);
/* reason counter */
switch(i) {
case 2: /* GRJ */
for(j=0;j<=GRJ_REASONS;j++) {
if(hs->grj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,GatekeeperRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->grj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 5: /* RRJ */
for(j=0;j<=RRJ_REASONS;j++) {
if(hs->rrj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,RegistrationRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->rrj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 6: /* URQ */
for(j=0;j<=URQ_REASONS;j++) {
if(hs->urq_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,UnregRequestReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->urq_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 8: /* URJ */
for(j=0;j<=URJ_REASONS;j++) {
if(hs->urj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,UnregRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->urj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 11: /* ARJ */
for(j=0;j<=ARJ_REASONS;j++) {
if(hs->arj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,AdmissionRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->arj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 14: /* BRJ */
for(j=0;j<=BRJ_REASONS;j++) {
if(hs->brj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,BandRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->brj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 15: /* DRQ */
for(j=0;j<=DRQ_REASONS;j++) {
if(hs->drq_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,DisengageReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->drq_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 17: /* DRJ */
for(j=0;j<=DRJ_REASONS;j++) {
if(hs->drj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,DisengageRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->drj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 20: /* LRJ */
for(j=0;j<=LRJ_REASONS;j++) {
if(hs->lrj_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,LocationRejectReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->lrj_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 29: /* IRQNak */
for(j=0;j<=IRQNAK_REASONS;j++) {
if(hs->irqnak_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,InfoRequestNakReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->irqnak_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
default:
break;
}
/* end of reason counter*/
}
}
for(i=0;i<=CS_MSG_TYPES;i++) {
if(hs->cs_msg[i]!=0) {
sprintf(str[0], "%s", val_to_str(i,h323_message_body_vals,"unknown cs-messages "));
sprintf(str[1], "%d", hs->cs_msg[i]);
gtk_clist_append(hs->table, str);
/* reason counter */
switch(i) {
case 5: /* ReleaseComplete */
for(j=0;j<=REL_CMP_REASONS;j++) {
if(hs->rel_cmp_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,ReleaseCompleteReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->rel_cmp_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
case 6: /* Facility */
for(j=0;j<=FACILITY_REASONS;j++) {
if(hs->facility_reason[j]!=0) {
sprintf(str[0], " %s", val_to_str(j,FacilityReason_vals,"unknown reason "));
sprintf(str[1], "%d", hs->facility_reason[j]);
gtk_clist_append(hs->table, str);
}
}
break;
default:
break;
}
}
}
gtk_widget_show(GTK_WIDGET(hs->table));
}
void protect_thread_critical_region(void);
void unprotect_thread_critical_region(void);
static void
win_destroy_cb(GtkWindow *win _U_, gpointer data)
{
h225counter_t *hs=(h225counter_t *)data;
protect_thread_critical_region();
remove_tap_listener(hs);
unprotect_thread_critical_region();
if(hs->filter){
g_free(hs->filter);
hs->filter=NULL;
}
g_free(hs);
}
static gchar *titles[]={"Message Type or Reason",
"Count" };
void
gtk_h225counter_init(char *optarg)
{
h225counter_t *hs;
char *filter=NULL;
GString *error_string;
if(strncmp(optarg,"h225,counter,",13) == 0){
filter=optarg+13;
} else {
filter=g_malloc(1);
*filter='\0';
}
hs=g_malloc(sizeof(h225counter_t));
hs->filter=g_malloc(strlen(filter)+1);
strcpy(hs->filter, filter);
h225counter_reset(hs);
hs->win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
SIGNAL_CONNECT(hs->win, "destroy", win_destroy_cb, hs);
hs->vbox=gtk_vbox_new(FALSE, 0);
init_main_stat_window(hs->win, hs->vbox, "ITU-T H.225 Message and Message Reason Counter", filter);
/* init a scrolled window*/
hs->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
WIDGET_SET_SIZE(hs->scrolled_window, 400, 200);
hs->table = create_stat_table(hs->scrolled_window, hs->vbox, 2, titles);
error_string=register_tap_listener("h225", hs, filter, h225counter_reset, h225counter_packet, h225counter_draw);
if(error_string){
simple_dialog(ESD_TYPE_WARN, NULL, error_string->str);
g_string_free(error_string, TRUE);
g_free(hs->filter);
g_free(hs);
return;
}
gtk_widget_show_all(hs->win);
redissect_packets(&cfile);
}
static void
dlg_destroy_cb(void)
{
dlg=NULL;
}
static void
dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
{
gtk_widget_destroy(GTK_WIDGET(parent_w));
}
static void
h225counter_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
{
char *filter;
char str[256];
filter=(char *)gtk_entry_get_text(GTK_ENTRY(filter_entry));
if(filter[0]==0){
gtk_h225counter_init("h225,counter");
} else {
sprintf(str,"h225,counter,%s", filter);
gtk_h225counter_init(str);
}
}
static void
gtk_h225counter_cb(GtkWidget *w _U_, gpointer d _U_)
{
char *filter;
char *title;
GtkWidget *dlg_box;
GtkWidget *filter_box, *filter_label;
GtkWidget *bbox, *start_button, *cancel_button;
/* if the window is already open, bring it to front */
if(dlg){
gdk_window_raise(dlg->window);
return;
}
title = g_strdup_printf("Ethereal: H.225 Messages and Message Reasons: %s", cf_get_display_name(&cfile));
dlg=dlg_window_new(title);
g_free(title);
SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
dlg_box=gtk_vbox_new(FALSE, 10);
gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
gtk_widget_show(dlg_box);
/* Filter box */
filter_box=gtk_hbox_new(FALSE, 3);
/* Filter label */
filter_label=gtk_label_new("Filter:");
gtk_box_pack_start(GTK_BOX(filter_box), filter_label, FALSE, FALSE, 0);
gtk_widget_show(filter_label);
/* Filter entry */
filter_entry=gtk_entry_new();
gtk_widget_set_usize(filter_entry, 300, -2);
gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
if(filter){
gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
}
gtk_widget_show(filter_entry);
gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
gtk_widget_show(filter_box);
/* button box */
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_DEFAULT_STYLE);
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
gtk_widget_show(bbox);
/* the start button */
start_button=gtk_button_new_with_label("Create Stat");
SIGNAL_CONNECT_OBJECT(start_button, "clicked",
h225counter_start_button_clicked, NULL);
gtk_box_pack_start(GTK_BOX(bbox), start_button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS(start_button, GTK_CAN_DEFAULT);
gtk_widget_grab_default(start_button);
gtk_widget_show(start_button);
#if GTK_MAJOR_VERSION < 2
cancel_button=gtk_button_new_with_label("Cancel");
#else
cancel_button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);
#endif
SIGNAL_CONNECT(cancel_button, "clicked", dlg_cancel_cb, dlg);
GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
gtk_box_pack_start(GTK_BOX(bbox), cancel_button, TRUE, TRUE, 0);
gtk_widget_show(cancel_button);
/* Catch the "activate" signal on the filter text entry, so that
if the user types Return there, we act as if the "Create Stat"
button had been selected, as happens if Return is typed if
some widget that *doesn't* handle the Return key has the input
focus. */
dlg_set_activate(filter_entry, start_button);
/* Catch the "key_press_event" signal in the window, so that we can
catch the ESC key being pressed and act as if the "Cancel" button
had been selected. */
dlg_set_cancel(dlg, cancel_button);
/* Give the initial focus to the "Filter" entry box. */
gtk_widget_grab_focus(filter_entry);
gtk_widget_show_all(dlg);
}
void
register_tap_listener_gtk_h225counter(void)
{
register_ethereal_tap("h225,counter", gtk_h225counter_init);
}
void
register_tap_menu_gtk_h225counter(void)
{
register_tap_menu_item("Statistics/Watch protocol/ITU-T H.225...",
gtk_h225counter_cb, NULL, NULL);
}

View File

@ -4,7 +4,7 @@
*
* Maintained by Andreas Sikkema (andreas.sikkema@philips.com)
*
* $Id: packet-h225.c,v 1.21 2003/10/27 22:28:47 guy Exp $
* $Id: packet-h225.c,v 1.22 2003/10/28 00:31:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -37,8 +37,10 @@
#include <string.h>
#include "prefs.h"
#include "tap.h"
#include "packet-tpkt.h"
#include "packet-per.h"
#include "packet-h225.h"
#include "packet-h245.h"
#include "t35.h"
@ -46,10 +48,15 @@
#define UDP_PORT_RAS2 1719
#define TCP_PORT_CS 1720
static void reset_h225_packet_info(h225_packet_info *pi);
static h225_packet_info h225_pi;
static dissector_handle_t h225ras_handle;
static dissector_handle_t H323UserInformation_handle;
static dissector_handle_t data_handle;
static int h225_tap = -1;
static int proto_h225 = -1;
static int hf_h225_cname = -1;
static int hf_h225_route = -1;
@ -1264,7 +1271,7 @@ static per_choice_t FacilityReason_choice[] = {
static int
dissect_h225_FacilityReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_FacilityReason, ett_h225_FacilityReason, FacilityReason_choice, "FacilityReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_FacilityReason, ett_h225_FacilityReason, FacilityReason_choice, "FacilityReason", &(h225_pi.reason));
return offset;
}
@ -1553,7 +1560,7 @@ static per_choice_t GatekeeperRejectReason_choice[] = {
static int
dissect_h225_GatekeeperRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_GatekeeperRejectReason, ett_h225_GatekeeperRejectReason, GatekeeperRejectReason_choice, "GatekeeperRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_GatekeeperRejectReason, ett_h225_GatekeeperRejectReason, GatekeeperRejectReason_choice, "GatekeeperRejectReason", &(h225_pi.reason));
return offset;
}
@ -1586,7 +1593,7 @@ static per_choice_t UnregRequestReason_choice[] = {
static int
dissect_h225_UnregRequestReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_UnregRequestReason, ett_h225_UnregRequestReason, UnregRequestReason_choice, "UnregRequestReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_UnregRequestReason, ett_h225_UnregRequestReason, UnregRequestReason_choice, "UnregRequestReason", &(h225_pi.reason));
return offset;
}
@ -1619,7 +1626,7 @@ static per_choice_t UnregRejectReason_choice[] = {
static int
dissect_h225_UnregRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_UnregRejectReason, ett_h225_UnregRejectReason, UnregRejectReason_choice, "UnregRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_UnregRejectReason, ett_h225_UnregRejectReason, UnregRejectReason_choice, "UnregRejectReason", &(h225_pi.reason));
return offset;
}
@ -1728,7 +1735,7 @@ static per_choice_t BandRejectReason_choice[] = {
static int
dissect_h225_BandRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_BandRejectReason, ett_h225_BandRejectReason, BandRejectReason_choice, "BandRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_BandRejectReason, ett_h225_BandRejectReason, BandRejectReason_choice, "BandRejectReason", &(h225_pi.reason));
return offset;
}
@ -1752,7 +1759,7 @@ static per_choice_t DisengageReason_choice[] = {
static int
dissect_h225_DisengageReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_DisengageReason, ett_h225_DisengageReason, DisengageReason_choice, "DisengageReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_DisengageReason, ett_h225_DisengageReason, DisengageReason_choice, "DisengageReason", &(h225_pi.reason));
return offset;
}
@ -1779,7 +1786,7 @@ static per_choice_t DisengageRejectReason_choice[] = {
static int
dissect_h225_DisengageRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_DisengageRejectReason, ett_h225_DisengageRejectReason, DisengageRejectReason_choice, "DisengageRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_DisengageRejectReason, ett_h225_DisengageRejectReason, DisengageRejectReason_choice, "DisengageRejectReason", &(h225_pi.reason));
return offset;
}
@ -1807,7 +1814,7 @@ static per_choice_t InfoRequestNakReason_choice[] = {
static int
dissect_h225_InfoRequestNakReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_InfoRequestNakReason, ett_h225_InfoRequestNakReason, InfoRequestNakReason_choice, "InfoRequestNakReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_InfoRequestNakReason, ett_h225_InfoRequestNakReason, InfoRequestNakReason_choice, "InfoRequestNakReason", &(h225_pi.reason));
return offset;
}
@ -2377,7 +2384,7 @@ static per_choice_t ReleaseCompleteReason_choice[] = {
static int
dissect_h225_ReleaseCompleteReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_ReleaseCompleteReason, ett_h225_ReleaseCompleteReason, ReleaseCompleteReason_choice, "ReleaseCompleteReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_ReleaseCompleteReason, ett_h225_ReleaseCompleteReason, ReleaseCompleteReason_choice, "ReleaseCompleteReason", &(h225_pi.reason));
return offset;
}
@ -2416,7 +2423,7 @@ dissect_h225_RequestSeqNum(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_
{
offset=dissect_per_constrained_integer(tvb, offset, pinfo,
tree, hf_h225_RequestSeqNum, 1, 65535,
NULL, NULL, FALSE);
&(h225_pi.requestSeqNum), NULL, FALSE);
return offset;
}
@ -2886,7 +2893,14 @@ dissect_h225_InfoRequestResponseStatus(tvbuff_t *tvb, int offset, packet_info *p
static int
dissect_h225_guid(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h225_guid, 16, 16, NULL, NULL);
guint32 value_length;
guint32 value_offset;
offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h225_guid, 16, 16, &(value_offset), &(value_length));
/* save call guid */
tvb_memcpy(tvb, h225_pi.guid, value_offset, value_length);
return offset;
}
@ -5123,7 +5137,7 @@ static per_choice_t AdmissionRejectReason_choice[] = {
static int
dissect_h225_AdmissionRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_AdmissionRejectReason, ett_h225_AdmissionRejectReason, AdmissionRejectReason_choice, "AdmissionRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_AdmissionRejectReason, ett_h225_AdmissionRejectReason, AdmissionRejectReason_choice, "AdmissionRejectReason", &(h225_pi.reason));
return offset;
}
@ -5281,7 +5295,7 @@ static per_choice_t LocationRejectReason_choice[] = {
static int
dissect_h225_LocationRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_LocationRejectReason, ett_h225_LocationRejectReason, LocationRejectReason_choice, "LocationRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_LocationRejectReason, ett_h225_LocationRejectReason, LocationRejectReason_choice, "LocationRejectReason", &(h225_pi.reason));
return offset;
}
@ -6062,7 +6076,7 @@ static per_choice_t RegistrationRejectReason_choice[] = {
static int
dissect_h225_RegistrationRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_RegistrationRejectReason, ett_h225_RegistrationRejectReason, RegistrationRejectReason_choice, "RegistrationRejectReason", NULL);
offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h225_RegistrationRejectReason, ett_h225_RegistrationRejectReason, RegistrationRejectReason_choice, "RegistrationRejectReason", &(h225_pi.reason));
return offset;
}
@ -7126,6 +7140,8 @@ dissect_h225_h323_message_body(tvbuff_t *tvb, int offset, packet_info *pinfo, pr
val_to_str(value, h323_message_body_vals, "<unknown>"));
}
h225_pi.msg_tag = value;
if (contains_faststart == TRUE )
{
if (check_col(pinfo->cinfo, COL_INFO))
@ -8398,6 +8414,10 @@ dissect_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint32 offset=0;
guint32 value;
/* Init struct for collecting h225_packet_info */
reset_h225_packet_info(&(h225_pi));
h225_pi.msg_type = H225_RAS;
if (check_col(pinfo->cinfo, COL_PROTOCOL)){
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.225.0");
}
@ -8411,6 +8431,9 @@ dissect_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_add_fstr(pinfo->cinfo, COL_INFO, "RAS: %s ",
val_to_str(value, RasMessage_vals, "<unknown>"));
}
h225_pi.msg_tag = value;
tap_queue_packet(h225_tap, pinfo, &h225_pi);
}
@ -8432,6 +8455,10 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
proto_tree *tr;
guint32 offset=0;
/* Init struct for collecting h225_packet_info */
reset_h225_packet_info(&(h225_pi));
h225_pi.msg_type = H225_CS;
if (check_col(pinfo->cinfo, COL_PROTOCOL)){
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.225.0");
}
@ -8443,6 +8470,8 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
tr=proto_item_add_subtree(it, ett_h225);
offset=dissect_per_sequence(tvb, offset, pinfo, tr, hf_h225_H323_UserInformation, ett_h225_H323_UserInformation, H323_UserInformation_sequence);
tap_queue_packet(h225_tap, pinfo, &h225_pi);
}
@ -10137,6 +10166,8 @@ proto_register_h225(void)
nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
h225_tap = register_tap("h225");
}
void
@ -10153,3 +10184,16 @@ proto_reg_handoff_h225(void)
dissector_add("udp.port", UDP_PORT_RAS1, h225ras_handle);
dissector_add("udp.port", UDP_PORT_RAS2, h225ras_handle);
}
static void reset_h225_packet_info(h225_packet_info *pi)
{
if(pi == NULL) {
return;
}
pi->msg_type = H225_OTHERS;
pi->msg_tag = -1;
pi->reason = -1;
pi->requestSeqNum = 0;
memset(pi->guid,0,16);
}

View File

@ -2,7 +2,7 @@
* Routines for H.225 packet dissection
* 2003 Tomas Kukosa
*
* $Id: packet-h225.h,v 1.3 2003/09/26 22:20:07 guy Exp $
* $Id: packet-h225.h,v 1.4 2003/10/28 00:31:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -24,11 +24,24 @@
*/
#ifndef __H225_H__
#define __H225_H__
#define __H225_H__
extern int dissect_h225_NonStandardParameter(tvbuff_t*, int, packet_info*, proto_tree*, int);
extern int dissect_h225_AliasAddress(tvbuff_t*, int, packet_info*, proto_tree*);
typedef enum _h225_msg_type {
H225_RAS,
H225_CS,
H225_OTHERS
} h225_msg_type;
typedef struct _h225_packet_info {
h225_msg_type msg_type; /* ras or cs message */
gint msg_tag; /* message tag*/
gint reason; /* reason tag, if available */
guint requestSeqNum; /* request sequence number of ras-message, if available */
guint8 guid[16]; /* globally unique call id */
} h225_packet_info;
#endif /* __H225_H__ */

662
tap-h225counter.c Normal file
View File

@ -0,0 +1,662 @@
/* tap_h225counter.c
* h225 message counter for ethereal
* Copyright 2003 Lars Roland
*
* $Id: tap-h225counter.c,v 1.1 2003/10/28 00:31:16 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* 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>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <string.h>
#include "epan/packet_info.h"
#include "tap.h"
#include "epan/value_string.h"
#include "register.h"
#include "packet-h225.h"
/* following values represent the size of their valuestring arrays */
#define RAS_MSG_TYPES 33
#define CS_MSG_TYPES 13
#define GRJ_REASONS 8
#define RRJ_REASONS 18
#define URQ_REASONS 6
#define URJ_REASONS 6
#define ARJ_REASONS 22
#define BRJ_REASONS 8
#define DRQ_REASONS 3
#define DRJ_REASONS 4
#define LRJ_REASONS 16
#define IRQNAK_REASONS 4
#define REL_CMP_REASONS 26
#define FACILITY_REASONS 11
static const value_string RasMessage_vals[] = {
{ 0, "gatekeeperRequest" },
{ 1, "gatekeeperConfirm" },
{ 2, "gatekeeperReject" },
{ 3, "registrationRequest" },
{ 4, "registrationConfirm" },
{ 5, "registrationReject" },
{ 6, "unregistrationRequest" },
{ 7, "unregistrationConfirm" },
{ 8, "unregistrationReject" },
{ 9, "admissionRequest" },
{10, "admissionConfirm" },
{11, "admissionReject" },
{12, "bandwidthRequest" },
{13, "bandwidthConfirm" },
{14, "bandwidthReject" },
{15, "disengageRequest" },
{16, "disengageConfirm" },
{17, "disengageReject" },
{18, "locationRequest" },
{19, "locationConfirm" },
{20, "locationReject" },
{21, "infoRequest" },
{22, "infoRequestResponse" },
{23, "nonStandardMessage" },
{24, "unknownMessageResponse" },
{25, "requestInProgress" },
{26, "resourcesAvailableIndicate" },
{27, "resourcesAvailableConfirm" },
{28, "infoRequestAck" },
{29, "infoRequestNak" },
{30, "serviceControlIndication" },
{31, "serviceControlResponse" },
{32, "admissionConfirmSequence" },
{ 0, NULL}
};
static const value_string h323_message_body_vals[] = {
{ 0, "setup" },
{ 1, "callProceeding" },
{ 2, "connect" },
{ 3, "alerting" },
{ 4, "information" },
{ 5, "releaseComplete" },
{ 6, "facility" },
{ 7, "progress" },
{ 8, "empty" },
{ 9, "status" },
{ 10, "statusInquiry" },
{ 11, "setupAcknowledge" },
{ 12, "notify" },
{ 0, NULL}
};
static const value_string FacilityReason_vals[] = {
{ 0, "routeCallToGatekeeper" },
{ 1, "callForwarded" },
{ 2, "routeCallToMC" },
{ 3, "undefinedReason" },
{ 4, "conferenceListChoice" },
{ 5, "startH245" },
{ 6, "noH245" },
{ 7, "newTokens" },
{ 8, "featureSetUpdate" },
{ 9, "forwardedElements" },
{ 10, "transportedInformation" },
{ 0, NULL}
};
static const value_string GatekeeperRejectReason_vals[] = {
{ 0, "resourceUnavailable" },
{ 1, "terminalExcluded" },
{ 2, "invalidRevision" },
{ 3, "undefinedReason" },
{ 4, "securityDenial" },
{ 5, "genericDataReason" },
{ 6, "neededFeatureNotSupported" },
{ 7, "securityError" },
{ 0, NULL}
};
static const value_string UnregRequestReason_vals[] = {
{ 0, "reregistrationRequired" },
{ 1, "ttlExpired" },
{ 2, "securityDenial" },
{ 3, "undefinedReason" },
{ 4, "maintenance" },
{ 5, "securityError" },
{ 0, NULL}
};
static const value_string UnregRejectReason_vals[] = {
{ 0, "notCurrentlyRegistered" },
{ 1, "callInProgress" },
{ 2, "undefinedReason" },
{ 3, "permissionDenied" },
{ 4, "securityDenial" },
{ 5, "securityError" },
{ 0, NULL}
};
static const value_string BandRejectReason_vals[] = {
{ 0, "notBound" },
{ 1, "invalidConferenceID" },
{ 2, "invalidPermission" },
{ 3, "insufficientResources" },
{ 4, "invalidRevision" },
{ 5, "undefinedReason" },
{ 6, "securityDenial" },
{ 7, "securityError" },
{ 0, NULL}
};
static const value_string DisengageReason_vals[] = {
{ 0, "forcedDrop" },
{ 1, "normalDrop" },
{ 2, "undefinedReason" },
{ 0, NULL}
};
static const value_string DisengageRejectReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "requestToDropOther" },
{ 2, "securityDenial" },
{ 3, "securityError" },
{ 0, NULL}
};
static const value_string InfoRequestNakReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "securityDenial" },
{ 2, "undefinedReason" },
{ 3, "securityError" },
{ 0, NULL}
};
static const value_string ReleaseCompleteReason_vals[] = {
{ 0, "noBandwidth" },
{ 1, "gatekeeperResources" },
{ 2, "unreachableDestination" },
{ 3, "destinationRejection" },
{ 4, "invalidRevision" },
{ 5, "noPermission" },
{ 6, "unreachableGatekeeper" },
{ 7, "gatewayResources" },
{ 8, "badFormatAddress" },
{ 9, "adaptiveBusy" },
{ 10, "inConf" },
{ 11, "undefinedReason" },
{ 12, "facilityCallDeflection" },
{ 13, "securityDenied" },
{ 14, "calledPartyNotRegistered" },
{ 15, "callerNotRegistered" },
{ 16, "newConnectionNeeded" },
{ 17, "nonStandardReason" },
{ 18, "replaceWithConferenceInvite" },
{ 19, "genericDataReason" },
{ 20, "neededFeatureNotSupported" },
{ 21, "tunnelledSignallingRejected" },
{ 22, "invalidCID" },
{ 23, "invalidCID" },
{ 24, "securityError" },
{ 25, "hopCountExceeded" },
{ 0, NULL}
};
static const value_string AdmissionRejectReason_vals[] = {
{ 0, "calledPartyNotRegistered" },
{ 1, "invalidPermission" },
{ 2, "requestDenied" },
{ 3, "undefinedReason" },
{ 4, "callerNotRegistered" },
{ 5, "routeCallToGatekeeper" },
{ 6, "invalidEndpointIdentifier" },
{ 7, "resourceUnavailable" },
{ 8, "securityDenial" },
{ 9, "qosControlNotSupported" },
{ 10, "incompleteAddress" },
{ 11, "aliasesInconsistent" },
{ 12, "routeCallToSCN" },
{ 13, "exceedsCallCapacity" },
{ 14, "collectDestination" },
{ 15, "collectPIN" },
{ 16, "genericDataReason" },
{ 17, "neededFeatureNotSupported" },
{ 18, "securityErrors" },
{ 19, "securityDHmismatch" },
{ 20, "noRouteToDestination" },
{ 21, "unallocatedNumber" },
{ 0, NULL}
};
static const value_string LocationRejectReason_vals[] = {
{ 0, "notRegistered" },
{ 1, "invalidPermission" },
{ 2, "requestDenied" },
{ 3, "undefinedReason" },
{ 4, "securityDenial" },
{ 5, "aliasesInconsistent" },
{ 6, "routeCalltoSCN" },
{ 7, "resourceUnavailable" },
{ 8, "genericDataReason" },
{ 9, "neededFeatureNotSupported" },
{10, "hopCountExceeded" },
{11, "incompleteAddress" },
{12, "securityError" },
{13, "securityDHmismatch" },
{14, "noRouteToDestination" },
{15, "unallocatedNumber" },
{ 0, NULL}
};
static const value_string RegistrationRejectReason_vals[] = {
{ 0, "discoveryRequired" },
{ 1, "invalidRevision" },
{ 2, "invalidCallSignalAddress" },
{ 3, "invalidRASAddress" },
{ 4, "duplicateAlias" },
{ 5, "invalidTerminalType" },
{ 6, "undefinedReason" },
{ 7, "transportNotSupported" },
{ 8, "transportQOSNotSupported" },
{ 9, "resourceUnavailable" },
{ 10, "invalidAlias" },
{ 11, "securityDenial" },
{ 12, "fullRegistrationRequired" },
{ 13, "additiveRegistrationNotSupported" },
{ 14, "invalidTerminalAliases" },
{ 15, "genericDataReason" },
{ 16, "neededFeatureNotSupported" },
{ 17, "securityError" },
{ 0, NULL}
};
/* used to keep track of the statistics for an entire program interface */
typedef struct _h225counter_t {
char *filter;
guint32 ras_msg[RAS_MSG_TYPES + 1];
guint32 cs_msg[CS_MSG_TYPES + 1];
guint32 grj_reason[GRJ_REASONS + 1];
guint32 rrj_reason[RRJ_REASONS + 1];
guint32 urq_reason[URQ_REASONS + 1];
guint32 urj_reason[URJ_REASONS + 1];
guint32 arj_reason[ARJ_REASONS + 1];
guint32 brj_reason[BRJ_REASONS + 1];
guint32 drq_reason[DRQ_REASONS + 1];
guint32 drj_reason[DRJ_REASONS + 1];
guint32 lrj_reason[LRJ_REASONS + 1];
guint32 irqnak_reason[IRQNAK_REASONS + 1];
guint32 rel_cmp_reason[REL_CMP_REASONS + 1];
guint32 facility_reason[FACILITY_REASONS + 1];
} h225counter_t;
static void
h225counter_reset(void *phs)
{
h225counter_t *hs=(h225counter_t *)phs;
int i;
for(i=0;i<=RAS_MSG_TYPES;i++) {
hs->ras_msg[i] = 0;
}
for(i=0;i<=CS_MSG_TYPES;i++) {
hs->cs_msg[i] = 0;
}
for(i=0;i<=GRJ_REASONS;i++) {
hs->grj_reason[i] = 0;
}
for(i=0;i<=RRJ_REASONS;i++) {
hs->rrj_reason[i] = 0;
}
for(i=0;i<=URQ_REASONS;i++) {
hs->urq_reason[i] = 0;
}
for(i=0;i<=URJ_REASONS;i++) {
hs->urj_reason[i] = 0;
}
for(i=0;i<=ARJ_REASONS;i++) {
hs->arj_reason[i] = 0;
}
for(i=0;i<=BRJ_REASONS;i++) {
hs->brj_reason[i] = 0;
}
for(i=0;i<=DRQ_REASONS;i++) {
hs->drq_reason[i] = 0;
}
for(i=0;i<=DRJ_REASONS;i++) {
hs->drj_reason[i] = 0;
}
for(i=0;i<=LRJ_REASONS;i++) {
hs->lrj_reason[i] = 0;
}
for(i=0;i<=IRQNAK_REASONS;i++) {
hs->irqnak_reason[i] = 0;
}
for(i=0;i<=REL_CMP_REASONS;i++) {
hs->rel_cmp_reason[i] = 0;
}
for(i=0;i<=FACILITY_REASONS;i++) {
hs->facility_reason[i] = 0;
}
}
static int
h225counter_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
{
h225counter_t *hs=(h225counter_t *)phs;
h225_packet_info *pi=phi;
switch (pi->msg_type) {
case H225_RAS:
if(pi->msg_tag==-1) { /* uninitialized */
return 0;
}
else if (pi->msg_tag >= RAS_MSG_TYPES) { /* unknown */
hs->ras_msg[RAS_MSG_TYPES]++;
}
else {
hs->ras_msg[pi->msg_tag]++;
}
/* Look for reason tag */
if(pi->reason==-1) { /* uninitialized */
break;
}
switch(pi->msg_tag) {
case 2: /* GRJ */
if(pi->reason < GRJ_REASONS)
hs->grj_reason[pi->reason]++;
else
hs->grj_reason[GRJ_REASONS]++;
break;
case 5: /* RRJ */
if(pi->reason < RRJ_REASONS)
hs->rrj_reason[pi->reason]++;
else
hs->rrj_reason[RRJ_REASONS]++;
break;
case 6: /* URQ */
if(pi->reason < URQ_REASONS)
hs->urq_reason[pi->reason]++;
else
hs->urq_reason[URQ_REASONS]++;
break;
case 8: /* URJ */
if(pi->reason < URJ_REASONS)
hs->urj_reason[pi->reason]++;
else
hs->urj_reason[URJ_REASONS]++;
break;
case 11: /* ARJ */
if(pi->reason < ARJ_REASONS)
hs->arj_reason[pi->reason]++;
else
hs->arj_reason[ARJ_REASONS]++;
break;
case 14: /* BRJ */
if(pi->reason < BRJ_REASONS)
hs->brj_reason[pi->reason]++;
else
hs->brj_reason[BRJ_REASONS]++;
break;
case 15: /* DRQ */
if(pi->reason < DRQ_REASONS)
hs->drq_reason[pi->reason]++;
else
hs->drq_reason[DRQ_REASONS]++;
break;
case 17: /* DRJ */
if(pi->reason < DRJ_REASONS)
hs->drj_reason[pi->reason]++;
else
hs->drj_reason[DRJ_REASONS]++;
break;
case 20: /* LRJ */
if(pi->reason < LRJ_REASONS)
hs->lrj_reason[pi->reason]++;
else
hs->lrj_reason[LRJ_REASONS]++;
break;
case 29: /* IRQ Nak */
if(pi->reason < IRQNAK_REASONS)
hs->irqnak_reason[pi->reason]++;
else
hs->irqnak_reason[IRQNAK_REASONS]++;
break;
default:
/* do nothing */
break;
}
break;
case H225_CS:
if(pi->msg_tag==-1) { /* uninitialized */
return 0;
}
else if (pi->msg_tag >= CS_MSG_TYPES) { /* unknown */
hs->cs_msg[CS_MSG_TYPES]++;
}
else {
hs->cs_msg[pi->msg_tag]++;
}
/* Look for reason tag */
if(pi->reason==-1) { /* uninitialized */
break;
}
switch(pi->msg_tag) {
case 5: /* ReleaseComplete */
if(pi->reason < REL_CMP_REASONS)
hs->rel_cmp_reason[pi->reason]++;
else
hs->rel_cmp_reason[REL_CMP_REASONS]++;
break;
case 6: /* Facility */
if(pi->reason < FACILITY_REASONS)
hs->facility_reason[pi->reason]++;
else
hs->facility_reason[FACILITY_REASONS]++;
break;
default:
/* do nothing */
break;
}
break;
default:
return 0;
break;
}
return 1;
}
static void
h225counter_draw(void *phs)
{
h225counter_t *hs=(h225counter_t *)phs;
int i,j;
printf("================== H225 Message and Reason Counter ==================\n");
printf("RAS-Messages:\n");
for(i=0;i<=RAS_MSG_TYPES;i++) {
if(hs->ras_msg[i]!=0) {
printf(" %s : %u\n", val_to_str(i,RasMessage_vals,"unknown ras-messages "), hs->ras_msg[i]);
/* reason counter */
switch(i) {
case 2: /* GRJ */
for(j=0;j<=GRJ_REASONS;j++) {
if(hs->grj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,GatekeeperRejectReason_vals,"unknown reason "), hs->grj_reason[j]);
}
}
break;
case 5: /* RRJ */
for(j=0;j<=RRJ_REASONS;j++) {
if(hs->rrj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,RegistrationRejectReason_vals,"unknown reason "), hs->rrj_reason[j]);
}
}
break;
case 6: /* URQ */
for(j=0;j<=URQ_REASONS;j++) {
if(hs->urq_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,UnregRequestReason_vals,"unknown reason "), hs->urq_reason[j]);
}
}
break;
case 8: /* URJ */
for(j=0;j<=URJ_REASONS;j++) {
if(hs->urj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,UnregRejectReason_vals,"unknown reason "), hs->urj_reason[j]);
}
}
break;
case 11: /* ARJ */
for(j=0;j<=ARJ_REASONS;j++) {
if(hs->arj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,AdmissionRejectReason_vals,"unknown reason "), hs->arj_reason[j]);
}
}
break;
case 14: /* BRJ */
for(j=0;j<=BRJ_REASONS;j++) {
if(hs->brj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,BandRejectReason_vals,"unknown reason "), hs->brj_reason[j]);
}
}
break;
case 15: /* DRQ */
for(j=0;j<=DRQ_REASONS;j++) {
if(hs->drq_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,DisengageReason_vals,"unknown reason "), hs->drq_reason[j]);
}
}
break;
case 17: /* DRJ */
for(j=0;j<=DRJ_REASONS;j++) {
if(hs->drj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,DisengageRejectReason_vals,"unknown reason "), hs->drj_reason[j]);
}
}
break;
case 20: /* LRJ */
for(j=0;j<=LRJ_REASONS;j++) {
if(hs->lrj_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,LocationRejectReason_vals,"unknown reason "), hs->lrj_reason[j]);
}
}
case 29: /* IRQNak */
for(j=0;j<=IRQNAK_REASONS;j++) {
if(hs->irqnak_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,InfoRequestNakReason_vals,"unknown reason "), hs->irqnak_reason[j]);
}
}
break;
default:
break;
}
/* end of reason counter*/
}
}
printf("Call Signalling:\n");
for(i=0;i<=CS_MSG_TYPES;i++) {
if(hs->cs_msg[i]!=0) {
printf(" %s : %u\n", val_to_str(i,h323_message_body_vals,"unknown cs-messages "), hs->cs_msg[i]);
/* reason counter */
switch(i) {
case 5: /* ReleaseComplete */
for(j=0;j<=REL_CMP_REASONS;j++) {
if(hs->rel_cmp_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,ReleaseCompleteReason_vals,"unknown reason "), hs->rel_cmp_reason[j]);
}
}
break;
case 6: /* Facility */
for(j=0;j<=FACILITY_REASONS;j++) {
if(hs->facility_reason[j]!=0) {
printf(" %s : %u\n", val_to_str(j,FacilityReason_vals,"unknown reason "), hs->facility_reason[j]);
}
}
break;
default:
break;
}
}
}
printf("=====================================================================\n");
}
static void
h225counter_init(char *optarg)
{
h225counter_t *hs;
char *filter=NULL;
GString *error_string;
if(!strncmp(optarg,"h225,counter,",13)){
filter=optarg+13;
} else {
filter=g_malloc(1);
*filter='\0';
}
hs = g_malloc(sizeof(h225counter_t));
hs->filter=g_malloc(strlen(filter)+1);
strcpy(hs->filter, filter);
h225counter_reset(hs);
error_string=register_tap_listener("h225", hs, filter, NULL, h225counter_packet, h225counter_draw);
if(error_string){
/* error, we failed to attach to the tap. clean up */
g_free(hs->filter);
g_free(hs);
fprintf(stderr, "tethereal: Couldn't register h225,counter tap: %s\n",
error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
}
void
register_tap_listener_h225counter(void)
{
register_ethereal_tap("h225,counter", h225counter_init);
}