aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--asn1/h225/h225.cnf116
-rw-r--r--asn1/h225/packet-h225-template.c33
-rw-r--r--asn1/h225/packet-h225-template.h22
-rw-r--r--asn1/h245/h245.cnf60
-rw-r--r--asn1/h245/packet-h245-template.c71
-rw-r--r--asn1/h245/packet-h245-template.h6
-rw-r--r--epan/dissectors/packet-h225.c148
-rw-r--r--epan/dissectors/packet-h225.h24
-rw-r--r--epan/dissectors/packet-h245.c133
-rw-r--r--epan/dissectors/packet-h245.h6
-rw-r--r--epan/dissectors/packet-isup.c15
-rw-r--r--epan/dissectors/packet-isup.h3
-rw-r--r--epan/dissectors/packet-q931.c421
-rw-r--r--epan/dissectors/packet-q931.h14
-rw-r--r--epan/dissectors/packet-rtp.c32
-rw-r--r--epan/dissectors/packet-sdp.c17
-rw-r--r--epan/dissectors/packet-sip.c23
-rw-r--r--epan/dissectors/packet-sip.h6
-rw-r--r--epan/libethereal.def2
-rw-r--r--gtk/graph_analysis.c1009
-rw-r--r--gtk/graph_analysis.h121
-rw-r--r--gtk/rtp_stream.c15
-rw-r--r--gtk/rtp_stream.h5
-rw-r--r--gtk/voip_calls.c1312
-rw-r--r--gtk/voip_calls.h191
-rw-r--r--gtk/voip_calls_dlg.c719
-rw-r--r--gtk/voip_calls_dlg.h55
-rw-r--r--rtp_pt.h1
29 files changed, 4264 insertions, 318 deletions
diff --git a/AUTHORS b/AUTHORS
index fa0152587f..f220c6e7de 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2223,6 +2223,7 @@ Kelly Byrd <kbyrd-ethereal [AT] memcpy.com> {
Luis Ontanon <luis.ontanon.ibm[AT]h3g.it> {
RADIUS and ISUP enhancements
+ MATE plugin
}
Luca Deri <deri [AT] ntop.org> {
@@ -2236,6 +2237,7 @@ Viorel Suman <vsuman [AT] avmob.ro> {
Alejandro Vaquero <alejandro.vaquero [AT] verso.com> {
RTP graphic analysis
+ VoIP call analysis
}
Francesco Fondelli <fondelli.francesco [AT] tiscali.it> {
diff --git a/asn1/h225/h225.cnf b/asn1/h225/h225.cnf
index 0f4d281df6..781fbdf0ff 100644
--- a/asn1/h225/h225.cnf
+++ b/asn1/h225/h225.cnf
@@ -147,9 +147,9 @@ CallIdentifier/guid guid
val_to_str(message_body_val, T_h323_message_body_vals, "<unknown>"));
}
- if (h225_pi.msg_type == H225_CS) {
+ if (h225_pi->msg_type == H225_CS) {
/* Don't override msg_tag value from IRR */
- h225_pi.msg_tag = message_body_val;
+ h225_pi->msg_tag = message_body_val;
}
if (contains_faststart == TRUE )
@@ -167,14 +167,19 @@ CallIdentifier/guid guid
#.FN_BODY FastStart/_item
guint32 newoffset;
guint32 length;
+ char codec_str[50];
offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_h225_fastStart_item_length, &length);
newoffset=offset + (length<<3); /* please note that offset is in bits in
PER dissectors, but the item length
is in octets */
- offset=dissect_h245_OpenLogicalChannel(tvb,offset, pinfo, tree, hf_index);
+ offset=dissect_h245_OpenLogicalChannelCodec(tvb,offset, pinfo, tree, hf_index, codec_str);
+
+ /* Add to packet info */
+ g_snprintf(h225_pi->frame_label, 50, "%s %s", h225_pi->frame_label, codec_str);
+
contains_faststart = TRUE;
- h225_pi.is_faststart = TRUE;
+ h225_pi->is_faststart = TRUE;
return newoffset;
@@ -192,7 +197,7 @@ CallIdentifier/guid guid
val_to_str(rasmessage_value, RasMessage_vals, "<unknown>"));
}
- h225_pi.msg_tag = rasmessage_value;
+ h225_pi->msg_tag = rasmessage_value;
#.END
#----------------------------------------------------------------------------------------
# TODO asn2eth can't handle restriced string ?
@@ -241,28 +246,85 @@ guint32 value_len;
#.END
#----------------------------------------------------------------------------------------
+#.FN_FTR NULL
+ if (h225_pi->cs_type == H225_OTHER) h225_pi->cs_type = H225_EMPTY;
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR Status-UUIE
+ /* Add to packet info */
+ h225_pi->cs_type = H225_STATUS;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR Information-UUIE
+ /* Add to packet info */
+ h225_pi->cs_type = H225_INFORMATION;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR Progress-UUIE
+ /* Add to packet info */
+ h225_pi->cs_type = H225_PROGRESS;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_FTR Facility-UUIE
+ /* Add to packet info */
+ h225_pi->cs_type = H225_FACILITY;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
+#.END
+#----------------------------------------------------------------------------------------
+#.FN_BODY H323-UU-PDU/h245Tunneling
+ offset=dissect_per_boolean(tvb, offset, pinfo, tree, hf_h225_h245Tunneling, &(h225_pi->is_h245Tunneling), NULL);
+#.END
+#----------------------------------------------------------------------------------------
#.FN_HDR Setup-UUIE
contains_faststart = FALSE;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR Setup-UUIE
- h225_pi.cs_type = H225_SETUP;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_SETUP;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR CallProceeding-UUIE
- h225_pi.cs_type = H225_CALL_PROCEDING;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_CALL_PROCEDING;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR Alerting-UUIE
- h225_pi.cs_type = H225_ALERTING;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_ALERTING;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR ReleaseComplete-UUIE
- h225_pi.cs_type = H225_RELEASE_COMPLET;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_RELEASE_COMPLET;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR Connect-UUIE
- h225_pi.cs_type = H225_CONNECT;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_CONNECT;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_HDR H245TransportAddress
@@ -273,9 +335,9 @@ guint32 value_len;
#----------------------------------------------------------------------------------------
#.FN_FTR H245TransportAddress
/* we need this info for TAPing */
- h225_pi.is_h245 = TRUE;
- h225_pi.h245_address = ipv4_address;
- h225_pi.h245_port = ipv4_port;
+ h225_pi->is_h245 = TRUE;
+ h225_pi->h245_address = ipv4_address;
+ h225_pi->h245_port = ipv4_port;
if((!pinfo->fd->flags.visited) && ipv4_address!=0 && ipv4_port!=0 && h245_handle){
address src_addr;
@@ -300,7 +362,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_FacilityReason, FacilityReason_choice, "FacilityReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
@@ -310,7 +372,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_GatekeeperRejectReason, GatekeeperRejectReason_choice, "GatekeeperRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
@@ -320,7 +382,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_UnregRequestReason, UnregRequestReason_choice, "UnregRequestReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
@@ -330,7 +392,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_UnregRejectReason, UnregRejectReason_choice, "UnregRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY BandRejectReason
@@ -338,7 +400,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_BandRejectReason, BandRejectReason_choice, "BandRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY DisengageReason
@@ -347,7 +409,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_DisengageReason, DisengageReason_choice, "DisengageReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#----------------------------------------------------------------------------------------
#.FN_BODY DisengageRejectReason
guint32 value;
@@ -355,7 +417,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_DisengageRejectReason, DisengageRejectReason_choice, "DisengageRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY AdmissionRejectReason
@@ -364,7 +426,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_AdmissionRejectReason, AdmissionRejectReason_choice, "AdmissionRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY LocationRejectReason
@@ -373,7 +435,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_LocationRejectReason, LocationRejectReason_choice, "LocationRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY RegistrationRejectReason
@@ -382,7 +444,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_RegistrationRejectReason, RegistrationRejectReason_choice, "RegistrationRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY InfoRequestNakReason
@@ -391,7 +453,7 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_InfoRequestNakReason, InfoRequestNakReason_choice, "InfoRequestNakReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY ReleaseCompleteReason
@@ -400,19 +462,19 @@ guint32 value_len;
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_ReleaseCompleteReason, ReleaseCompleteReason_choice, "ReleaseCompleteReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY CallIdentifier/guid
guint32 guid_offset,guid_len;
offset = dissect_per_octet_string(tvb,offset,pinfo,tree,hf_index,16,16,&guid_offset,&guid_len);
- tvb_memcpy(tvb,h225_pi.guid,guid_offset,guid_len);
+ tvb_memcpy(tvb,h225_pi->guid,guid_offset,guid_len);
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY RequestSeqNum
offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
- 1U, 65535U, &(h225_pi.requestSeqNum), NULL, FALSE);
+ 1U, 65535U, &(h225_pi->requestSeqNum), NULL, FALSE);
#----------------------------------------------------------------------------------------
#.FN_BODY H323-UU-PDU/h4501SupplementaryService/_item
diff --git a/asn1/h225/packet-h225-template.c b/asn1/h225/packet-h225-template.c
index c774f95b5c..0d2ec536e3 100644
--- a/asn1/h225/packet-h225-template.c
+++ b/asn1/h225/packet-h225-template.c
@@ -67,7 +67,9 @@ static void reset_h225_packet_info(h225_packet_info *pi);
static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi);
static int dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static h225_packet_info h225_pi;
+static h225_packet_info pi_arr[5]; /* We assuming a maximum of 5 H225 messaages per packet */
+static int pi_current=0;
+h225_packet_info *h225_pi=NULL;
static dissector_handle_t h225ras_handle;
static dissector_handle_t H323UserInformation_handle;
@@ -132,9 +134,15 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
proto_tree *tr;
int offset = 0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h225_pi=&pi_arr[pi_current];
+
/* Init struct for collecting h225_packet_info */
- reset_h225_packet_info(&(h225_pi));
- h225_pi.msg_type = H225_CS;
+ 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");
@@ -148,7 +156,7 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
offset = dissect_h225_H323_UserInformation(tvb, offset,pinfo, tr, hf_h225_H323_UserInformation);
- tap_queue_packet(h225_tap, pinfo, &h225_pi);
+ tap_queue_packet(h225_tap, pinfo, h225_pi);
return offset;
}
@@ -158,9 +166,15 @@ dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_tree *tr;
guint32 offset=0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h225_pi=&pi_arr[pi_current];
+
/* Init struct for collecting h225_packet_info */
- reset_h225_packet_info(&(h225_pi));
- h225_pi.msg_type = H225_RAS;
+ 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");
@@ -171,12 +185,13 @@ dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
offset = dissect_h225_RasMessage(tvb, 0, pinfo,tr, hf_h225_RasMessage );
- ras_call_matching(tvb, pinfo, tr, &(h225_pi));
+ ras_call_matching(tvb, pinfo, tr, h225_pi);
- tap_queue_packet(h225_tap, pinfo, &h225_pi);
+ tap_queue_packet(h225_tap, pinfo, h225_pi);
return offset;
}
+
/*--- proto_register_h225 -------------------------------------------*/
void proto_register_h225(void) {
@@ -279,8 +294,10 @@ static void reset_h225_packet_info(h225_packet_info *pi)
pi->request_available = FALSE;
pi->is_faststart = FALSE;
pi->is_h245 = FALSE;
+ pi->is_h245Tunneling = FALSE;
pi->h245_address = 0;
pi->h245_port = 0;
+ pi->frame_label[0] = '\0';
}
/*
diff --git a/asn1/h225/packet-h225-template.h b/asn1/h225/packet-h225-template.h
index 604f550be7..69492a3538 100644
--- a/asn1/h225/packet-h225-template.h
+++ b/asn1/h225/packet-h225-template.h
@@ -33,12 +33,20 @@ typedef enum _h225_msg_type {
} h225_msg_type;
typedef enum _h225_cs_type {
- H225_SETUP,
- H225_CALL_PROCEDING,
- H225_ALERTING,
- H225_CONNECT,
- H225_RELEASE_COMPLET,
- H225_OTHER
+ H225_SETUP,
+ H225_CALL_PROCEDING,
+ H225_CONNECT,
+ H225_ALERTING,
+ H225_INFORMATION,
+ H225_RELEASE_COMPLET,
+ H225_FACILITY,
+ H225_PROGRESS,
+ H225_EMPTY,
+ H225_STATUS,
+ H225_STATUS_INQUIRY,
+ H225_SETUP_ACK,
+ H225_NOTIFY,
+ H225_OTHER
} h225_cs_type;
typedef struct _h225_packet_info {
@@ -54,8 +62,10 @@ typedef struct _h225_packet_info {
/* added for h225 conversations analysis */
gboolean is_faststart; /* true, if faststart field is included */
gboolean is_h245;
+ gboolean is_h245Tunneling;
guint32 h245_address;
guint16 h245_port;
+ gchar frame_label[50]; /* the Fram label used by graph_analysis, what is a abreviation of cinfo */
} h225_packet_info;
/*
diff --git a/asn1/h245/h245.cnf b/asn1/h245/h245.cnf
index 1dec2fcc0c..4d0a409a10 100644
--- a/asn1/h245/h245.cnf
+++ b/asn1/h245/h245.cnf
@@ -33,6 +33,20 @@ OpenLogicalChannel
}
col_set_fence(pinfo->cinfo,COL_INFO);
+
+ /* Add to packet info */
+
+ /* if it is TCS*/
+ if ((codec_type != NULL) && ( value == 2))
+ g_snprintf(h245_pi->frame_label, 50, "%s (%s) ",val_to_str(value, h245_RequestMessage_short_vals, "UKN"), h245_pi->frame_label);
+ else
+ g_snprintf(h245_pi->frame_label, 50, "%s ", val_to_str(value, h245_RequestMessage_short_vals, "UKN"));
+
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_RequestMessage_vals, "<unknown>"));
+
+ /* if it is OLC or RM*/
+ if ((codec_type != NULL) && (( value == 3) || ( value == 8)))
+ g_snprintf(h245_pi->frame_label, 50, "%s (%s) ", h245_pi->frame_label, codec_type);
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY ResponseMessage
@@ -56,6 +70,10 @@ OpenLogicalChannel
}
col_set_fence(pinfo->cinfo,COL_INFO);
+
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_ResponseMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_ResponseMessage_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY IndicationMessage
@@ -79,6 +97,9 @@ OpenLogicalChannel
}
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_IndicationMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_IndicationMessage_vals, "<unknown>"));
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY CommandMessage
@@ -102,6 +123,10 @@ OpenLogicalChannel
}
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_CommandMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_CommandMessage_vals, "<unknown>"));
+
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY AudioCapability
@@ -111,7 +136,9 @@ OpenLogicalChannel
ett_h245_AudioCapability, AudioCapability_choice, "AudioCapability",
&value);
- codec_type = val_to_str(value, h245_AudioCapability_vals, "<unknown>");
+ codec_type = val_to_str(value, h245_AudioCapability_short_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, val_to_str(value, h245_AudioCapability_short_vals, "ukn"));
+
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY VideoCapability
@@ -122,6 +149,8 @@ OpenLogicalChannel
&value);
codec_type = val_to_str(value, h245_VideoCapability_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, codec_type);
+
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY Application
@@ -132,76 +161,77 @@ OpenLogicalChannel
&value);
codec_type = val_to_str(value, h245_Application_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, codec_type);
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR MasterSlaveDeterminationAck
- h245_pi.msg_type = H245_MastSlvDetAck;
+ h245_pi->msg_type = H245_MastSlvDetAck;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR MasterSlaveDeterminationReject
- h245_pi.msg_type = H245_MastSlvDetRjc;
+ h245_pi->msg_type = H245_MastSlvDetRjc;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR OpenLogicalChannelReject
- h245_pi.msg_type = H245_OpenLogChnRjc;
+ h245_pi->msg_type = H245_OpenLogChnRjc;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR CloseLogicalChannel
- h245_pi.msg_type = H245_CloseLogChn;
+ h245_pi->msg_type = H245_CloseLogChn;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR CloseLogicalChannelAck
- h245_pi.msg_type = H245_CloseLogChnAck;
+ h245_pi->msg_type = H245_CloseLogChnAck;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR OpenLogicalChannelConfirm
- h245_pi.msg_type = H245_OpenLogChnCnf;
+ h245_pi->msg_type = H245_OpenLogChnCnf;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR TerminalCapabilitySetAck
- h245_pi.msg_type = H245_TermCapSetAck;
+ h245_pi->msg_type = H245_TermCapSetAck;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR MasterSlaveDetermination
- h245_pi.msg_type = H245_MastSlvDet;
+ h245_pi->msg_type = H245_MastSlvDet;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR TerminalCapabilitySetReject
- h245_pi.msg_type = H245_TermCapSetRjc;
+ h245_pi->msg_type = H245_TermCapSetRjc;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR MasterSlaveDeterminationRelease
- h245_pi.msg_type = H245_MastSlvDetRls;
+ h245_pi->msg_type = H245_MastSlvDetRls;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR TerminalCapabilitySet
- h245_pi.msg_type = H245_TermCapSet;
+ h245_pi->msg_type = H245_TermCapSet;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR TerminalCapabilitySetRelease
- h245_pi.msg_type = H245_TermCapSetRls;
+ h245_pi->msg_type = H245_TermCapSetRls;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR OpenLogicalChannel
- h245_pi.msg_type = H245_OpenLogChn;
+ if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
#.END
#----------------------------------------------------------------------------------------
#.FN_FTR OpenLogicalChannelAck
- h245_pi.msg_type = H245_OpenLogChnAck;
+ h245_pi->msg_type = H245_OpenLogChnAck;
#.END
#----------------------------------------------------------------------------------------
#.FN_BODY CapabilityIdentifier/standard
diff --git a/asn1/h245/packet-h245-template.c b/asn1/h245/packet-h245-template.c
index 6766115419..f9cafb8481 100644
--- a/asn1/h245/packet-h245-template.c
+++ b/asn1/h245/packet-h245-template.c
@@ -70,7 +70,10 @@ static int hf_h245_pdu_type = -1;
static int hf_h245Manufacturer = -1;
static int h245_tap = -1;
static int ett_h245 = -1;
-static h245_packet_info h245_pi;
+static int h245dg_tap = -1;
+static h245_packet_info pi_arr[5]; /* We assuming a maximum of 5 H245 messaages per packet */
+static int pi_current=0;
+h245_packet_info *h245_pi=NULL;
static gboolean h245_reassembly = TRUE;
static gboolean h245_shorttypes = FALSE;
@@ -164,6 +167,34 @@ static const value_string h245_CommandMessage_short_vals[] = {
{ 12, "GC" },
{ 0, NULL }
};
+static const value_string h245_AudioCapability_short_vals[] = {
+ { 0, "nonStd" },
+ { 1, "g711A" },
+ { 2, "g711A56k" },
+ { 3, "g711U" },
+ { 4, "g711U56k" },
+ { 5, "g722-64k" },
+ { 6, "g722-56k" },
+ { 7, "g722-48k" },
+ { 8, "g7231" },
+ { 9, "g728" },
+ { 10, "g729" },
+ { 11, "g729A" },
+ { 12, "is11172" },
+ { 13, "is13818" },
+ { 14, "g729B" },
+ { 15, "g729AB" },
+ { 16, "g7231C" },
+ { 17, "gsmFR" },
+ { 18, "gsmHR" },
+ { 19, "gsmEFR" },
+ { 20, "generic" },
+ { 21, "g729Ext" },
+ { 22, "vbd" },
+ { 23, "audioTelEvent" },
+ { 24, "audioTone" },
+ { 0, NULL }
+};
/* To put the codec type only in COL_INFO when
an OLC is read */
@@ -199,12 +230,18 @@ int proto_h245 = -1;
void
dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
- reset_h245_packet_info(&(h245_pi));
- h245_pi.msg_type = H245_OTHER;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h245_pi=&pi_arr[pi_current];
+
+ reset_h245_packet_info(h245_pi);
+ h245_pi->msg_type = H245_OTHER;
dissect_tpkt_encap(tvb, pinfo, parent_tree, h245_reassembly, MultimediaSystemControlMessage_handle);
- tap_queue_packet(h245_tap, pinfo, &h245_pi);
+ tap_queue_packet(h245_tap, pinfo, h245_pi);
}
void
@@ -214,6 +251,14 @@ dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
proto_tree *tr;
guint32 offset=0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h245_pi=&pi_arr[pi_current];
+
+ reset_h245_packet_info(h245_pi);
+ h245_pi->msg_type = H245_OTHER;
if (check_col(pinfo->cinfo, COL_PROTOCOL)){
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.245");
@@ -222,8 +267,23 @@ dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), "H.245");
tr=proto_item_add_subtree(it, ett_h245);
dissect_h245_MultimediaSystemControlMessage(tvb, offset, pinfo ,tr, hf_h245_pdu_type);
+ tap_queue_packet(h245dg_tap, pinfo, h245_pi);
}
+int
+dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *codec_str) {
+ offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
+ ett_h245_OpenLogicalChannel, OpenLogicalChannel_sequence);
+
+
+ if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
+
+ if (codec_str){
+ g_strlcpy(codec_str, codec_type, 50);
+ }
+
+ return offset;
+}
/*--- proto_register_h245 -------------------------------------------*/
void proto_register_h245(void) {
@@ -270,6 +330,7 @@ void proto_register_h245(void) {
nsp_object_dissector_table = register_dissector_table("h245.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
nsp_h221_dissector_table = register_dissector_table("h245.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
h245_tap = register_tap("h245");
+ h245dg_tap = register_tap("h245dg");
register_ber_oid_name("0.0.8.239.1.1","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ControlCapability(1)");
register_ber_oid_name("0.0.8.239.1.2","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ExtendedVideoCapability(2)");
@@ -309,5 +370,7 @@ static void reset_h245_packet_info(h245_packet_info *pi)
}
pi->msg_type = H245_OTHER;
+ pi->frame_label[0] = '\0';
+ sprintf(pi->comment, "H245 ");
}
diff --git a/asn1/h245/packet-h245-template.h b/asn1/h245/packet-h245-template.h
index 3dff3f9132..598378ff91 100644
--- a/asn1/h245/packet-h245-template.h
+++ b/asn1/h245/packet-h245-template.h
@@ -2,7 +2,7 @@
* Routines for h245 packet dissection
* Copyright 2005, Anders Broman <anders.broman@ericsson.com>
*
- * $Id: packet-h245-template.h 12203 2004-10-05 09:18:55Z guy $
+ * $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -45,10 +45,14 @@ typedef enum _h245_msg_type {
typedef struct _h245_packet_info {
h245_msg_type msg_type; /* type of message */
+ gchar frame_label[50]; /* the Frame label used by graph_analysis, what is a abreviation of cinfo */
+ gchar comment[50]; /* the Frame Comment used by graph_analysis, what is a message desc */
} h245_packet_info;
#include "packet-h245-exp.h"*/
+int dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *codec_str);
+
#endif /* PACKET_H245_H */
diff --git a/epan/dissectors/packet-h225.c b/epan/dissectors/packet-h225.c
index 40acff090b..bd09350bcc 100644
--- a/epan/dissectors/packet-h225.c
+++ b/epan/dissectors/packet-h225.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Ethereal dissector compiler */
-/* .\packet-h225.c */
+/* ./packet-h225.c */
/* ../../tools/asn2eth.py -X -e -p h225 -c h225.cnf -s packet-h225-template h225.asn */
/* Input file: packet-h225-template.c */
@@ -74,7 +74,9 @@ static void reset_h225_packet_info(h225_packet_info *pi);
static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi);
static int dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static h225_packet_info h225_pi;
+static h225_packet_info pi_arr[5]; /* We assuming a maximum of 5 H225 messaages per packet */
+static int pi_current=0;
+h225_packet_info *h225_pi=NULL;
static dissector_handle_t h225ras_handle;
static dissector_handle_t H323UserInformation_handle;
@@ -129,7 +131,7 @@ static int hf_h225_notify = -1; /* Notify_UUIE */
static int hf_h225_nonStandardData = -1; /* NonStandardParameter */
static int hf_h225_h4501SupplementaryService = -1; /* T_h4501SupplementaryService */
static int hf_h225_h4501SupplementaryService_item = -1; /* T_h4501SupplementaryService_item */
-static int hf_h225_h245Tunneling = -1; /* BOOLEAN */
+static int hf_h225_h245Tunneling = -1; /* T_h245Tunneling */
static int hf_h225_h245Control = -1; /* H245Control */
static int hf_h225_nonStandardControl = -1; /* SEQUENCE_OF_NonStandardParameter */
static int hf_h225_nonStandardControl_item = -1; /* NonStandardParameter */
@@ -1345,6 +1347,7 @@ dissect_h225_NULL(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree
proto_item_append_text(ti_tmp, ": NULL");
}
+ if (h225_pi->cs_type == H225_OTHER) h225_pi->cs_type = H225_EMPTY;
return offset;
}
static int dissect_empty_flg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -2209,9 +2212,9 @@ dissect_h225_H245TransportAddress(tvbuff_t *tvb, int offset, packet_info *pinfo
NULL);
/* we need this info for TAPing */
- h225_pi.is_h245 = TRUE;
- h225_pi.h245_address = ipv4_address;
- h225_pi.h245_port = ipv4_port;
+ h225_pi->is_h245 = TRUE;
+ h225_pi->h245_address = ipv4_address;
+ h225_pi->h245_port = ipv4_port;
if((!pinfo->fd->flags.visited) && ipv4_address!=0 && ipv4_port!=0 && h245_handle){
address src_addr;
@@ -3506,9 +3509,6 @@ dissect_h225_BOOLEAN(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tr
return offset;
}
-static int dissect_h245Tunneling(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
- return dissect_h225_BOOLEAN(tvb, offset, pinfo, tree, hf_h225_h245Tunneling);
-}
static int dissect_multipleCalls(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
return dissect_h225_BOOLEAN(tvb, offset, pinfo, tree, hf_h225_multipleCalls);
}
@@ -4002,7 +4002,7 @@ dissect_h225_T_guid(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tre
guint32 guid_offset,guid_len;
offset = dissect_per_octet_string(tvb,offset,pinfo,tree,hf_index,16,16,&guid_offset,&guid_len);
- tvb_memcpy(tvb,h225_pi.guid,guid_offset,guid_len);
+ tvb_memcpy(tvb,h225_pi->guid,guid_offset,guid_len);
return offset;
}
@@ -4242,14 +4242,19 @@ static int
dissect_h225_FastStart_item(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
guint32 newoffset;
guint32 length;
+ char codec_str[50];
offset=dissect_per_length_determinant(tvb, offset, pinfo, tree, hf_h225_fastStart_item_length, &length);
newoffset=offset + (length<<3); /* please note that offset is in bits in
PER dissectors, but the item length
is in octets */
- offset=dissect_h245_OpenLogicalChannel(tvb,offset, pinfo, tree, hf_index);
+ offset=dissect_h245_OpenLogicalChannelCodec(tvb,offset, pinfo, tree, hf_index, codec_str);
+
+ /* Add to packet info */
+ g_snprintf(h225_pi->frame_label, 50, "%s %s", h225_pi->frame_label, codec_str);
+
contains_faststart = TRUE;
- h225_pi.is_faststart = TRUE;
+ h225_pi->is_faststart = TRUE;
return newoffset;
@@ -5337,7 +5342,12 @@ dissect_h225_Setup_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Setup_UUIE, Setup_UUIE_sequence);
- h225_pi.cs_type = H225_SETUP;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_SETUP;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_setup(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5384,7 +5394,12 @@ dissect_h225_CallProceeding_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_CallProceeding_UUIE, CallProceeding_UUIE_sequence);
- h225_pi.cs_type = H225_CALL_PROCEDING;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_CALL_PROCEDING;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_callProceeding(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5431,7 +5446,12 @@ dissect_h225_Connect_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, pro
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Connect_UUIE, Connect_UUIE_sequence);
- h225_pi.cs_type = H225_CONNECT;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_CONNECT;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_connect(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5464,7 +5484,12 @@ dissect_h225_Alerting_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, pr
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Alerting_UUIE, Alerting_UUIE_sequence);
- h225_pi.cs_type = H225_ALERTING;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_ALERTING;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_alerting(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5487,6 +5512,9 @@ dissect_h225_Information_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Information_UUIE, Information_UUIE_sequence);
+ /* Add to packet info */
+ h225_pi->cs_type = H225_INFORMATION;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_information(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5618,7 +5646,7 @@ dissect_h225_ReleaseCompleteReason(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_ReleaseCompleteReason, ReleaseCompleteReason_choice, "ReleaseCompleteReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -5646,7 +5674,9 @@ dissect_h225_ReleaseComplete_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_ReleaseComplete_UUIE, ReleaseComplete_UUIE_sequence);
- h225_pi.cs_type = H225_RELEASE_COMPLET;
+ /* Add to packet info */
+ h225_pi->cs_type = H225_RELEASE_COMPLET;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_releaseComplete(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5691,7 +5721,7 @@ dissect_h225_FacilityReason(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, p
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_FacilityReason, FacilityReason_choice, "FacilityReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
@@ -5760,6 +5790,9 @@ dissect_h225_Facility_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, pr
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Facility_UUIE, Facility_UUIE_sequence);
+ /* Add to packet info */
+ h225_pi->cs_type = H225_FACILITY;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_facility(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5786,6 +5819,12 @@ dissect_h225_Progress_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, pr
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Progress_UUIE, Progress_UUIE_sequence);
+ /* Add to packet info */
+ h225_pi->cs_type = H225_PROGRESS;
+ if (contains_faststart == TRUE )
+ g_snprintf(h225_pi->frame_label, 50, "%s OLC (%s)", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"), h225_pi->frame_label);
+ else
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_progress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5805,6 +5844,9 @@ dissect_h225_Status_UUIE(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot
offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
ett_h225_Status_UUIE, Status_UUIE_sequence);
+ /* Add to packet info */
+ h225_pi->cs_type = H225_STATUS;
+ g_snprintf(h225_pi->frame_label, 50, "%s", val_to_str(h225_pi->cs_type, T_h323_message_body_vals, "<unknown>"));
return offset;
}
static int dissect_status(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5917,9 +5959,9 @@ dissect_h225_T_h323_message_body(tvbuff_t *tvb, int offset, packet_info *pinfo _
val_to_str(message_body_val, T_h323_message_body_vals, "<unknown>"));
}
- if (h225_pi.msg_type == H225_CS) {
+ if (h225_pi->msg_type == H225_CS) {
/* Don't override msg_tag value from IRR */
- h225_pi.msg_tag = message_body_val;
+ h225_pi->msg_tag = message_body_val;
}
if (contains_faststart == TRUE )
@@ -5974,6 +6016,17 @@ static int dissect_h4501SupplementaryService(tvbuff_t *tvb, int offset, packet_i
static int
+dissect_h225_T_h245Tunneling(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
+ offset=dissect_per_boolean(tvb, offset, pinfo, tree, hf_h225_h245Tunneling, &(h225_pi->is_h245Tunneling), NULL);
+
+ return offset;
+}
+static int dissect_h245Tunneling(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
+ return dissect_h225_T_h245Tunneling(tvb, offset, pinfo, tree, hf_h225_h245Tunneling);
+}
+
+
+static int
dissect_h225_H245Control_item(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
tvbuff_t *h245_tvb;
@@ -6428,7 +6481,7 @@ static int dissect_securityError(tvbuff_t *tvb, int offset, packet_info *pinfo,
static int
dissect_h225_RequestSeqNum(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index) {
offset = dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_index,
- 1U, 65535U, &(h225_pi.requestSeqNum), NULL, FALSE);
+ 1U, 65535U, &(h225_pi->requestSeqNum), NULL, FALSE);
return offset;
@@ -7055,7 +7108,7 @@ dissect_h225_GatekeeperRejectReason(tvbuff_t *tvb, int offset, packet_info *pinf
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_GatekeeperRejectReason, GatekeeperRejectReason_choice, "GatekeeperRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
@@ -7328,7 +7381,7 @@ dissect_h225_RegistrationRejectReason(tvbuff_t *tvb, int offset, packet_info *pi
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_RegistrationRejectReason, RegistrationRejectReason_choice, "RegistrationRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -7390,7 +7443,7 @@ dissect_h225_UnregRequestReason(tvbuff_t *tvb, int offset, packet_info *pinfo _U
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_UnregRequestReason, UnregRequestReason_choice, "UnregRequestReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
@@ -7478,7 +7531,7 @@ dissect_h225_UnregRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo _U_
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_UnregRejectReason, UnregRejectReason_choice, "UnregRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -7784,7 +7837,7 @@ dissect_h225_AdmissionRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_AdmissionRejectReason, AdmissionRejectReason_choice, "AdmissionRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -7917,7 +7970,7 @@ dissect_h225_BandRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_BandRejectReason, BandRejectReason_choice, "BandRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -7971,7 +8024,7 @@ dissect_h225_DisengageReason(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_DisengageReason, DisengageReason_choice, "DisengageReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -8061,7 +8114,7 @@ dissect_h225_DisengageRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_DisengageRejectReason, DisengageRejectReason_choice, "DisengageRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -8212,7 +8265,7 @@ dissect_h225_LocationRejectReason(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_LocationRejectReason, LocationRejectReason_choice, "LocationRejectReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -8605,7 +8658,7 @@ dissect_h225_InfoRequestNakReason(tvbuff_t *tvb, int offset, packet_info *pinfo
offset = dissect_per_choice(tvb, offset, pinfo, tree, hf_index,
ett_h225_InfoRequestNakReason, InfoRequestNakReason_choice, "InfoRequestNakReason",
&value);
- h225_pi.reason = value;
+ h225_pi->reason = value;
return offset;
}
@@ -8832,7 +8885,7 @@ dissect_h225_RasMessage(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto
val_to_str(rasmessage_value, RasMessage_vals, "<unknown>"));
}
- h225_pi.msg_tag = rasmessage_value;
+ h225_pi->msg_tag = rasmessage_value;
return offset;
}
@@ -8849,9 +8902,15 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
proto_tree *tr;
int offset = 0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h225_pi=&pi_arr[pi_current];
+
/* Init struct for collecting h225_packet_info */
- reset_h225_packet_info(&(h225_pi));
- h225_pi.msg_type = H225_CS;
+ 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");
@@ -8865,7 +8924,7 @@ dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
offset = dissect_h225_H323_UserInformation(tvb, offset,pinfo, tr, hf_h225_H323_UserInformation);
- tap_queue_packet(h225_tap, pinfo, &h225_pi);
+ tap_queue_packet(h225_tap, pinfo, h225_pi);
return offset;
}
@@ -8875,9 +8934,15 @@ dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_tree *tr;
guint32 offset=0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h225_pi=&pi_arr[pi_current];
+
/* Init struct for collecting h225_packet_info */
- reset_h225_packet_info(&(h225_pi));
- h225_pi.msg_type = H225_RAS;
+ 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");
@@ -8888,12 +8953,13 @@ dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
offset = dissect_h225_RasMessage(tvb, 0, pinfo,tr, hf_h225_RasMessage );
- ras_call_matching(tvb, pinfo, tr, &(h225_pi));
+ ras_call_matching(tvb, pinfo, tr, h225_pi);
- tap_queue_packet(h225_tap, pinfo, &h225_pi);
+ tap_queue_packet(h225_tap, pinfo, h225_pi);
return offset;
}
+
/*--- proto_register_h225 -------------------------------------------*/
void proto_register_h225(void) {
@@ -12231,8 +12297,10 @@ static void reset_h225_packet_info(h225_packet_info *pi)
pi->request_available = FALSE;
pi->is_faststart = FALSE;
pi->is_h245 = FALSE;
+ pi->is_h245Tunneling = FALSE;
pi->h245_address = 0;
pi->h245_port = 0;
+ pi->frame_label[0] = '\0';
}
/*
diff --git a/epan/dissectors/packet-h225.h b/epan/dissectors/packet-h225.h
index 172618e380..68855914bc 100644
--- a/epan/dissectors/packet-h225.h
+++ b/epan/dissectors/packet-h225.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Ethereal dissector compiler */
-/* .\packet-h225.h */
+/* ./packet-h225.h */
/* ../../tools/asn2eth.py -X -e -p h225 -c h225.cnf -s packet-h225-template h225.asn */
/* Input file: packet-h225-template.h */
@@ -40,12 +40,20 @@ typedef enum _h225_msg_type {
} h225_msg_type;
typedef enum _h225_cs_type {
- H225_SETUP,
- H225_CALL_PROCEDING,
- H225_ALERTING,
- H225_CONNECT,
- H225_RELEASE_COMPLET,
- H225_OTHER
+ H225_SETUP,
+ H225_CALL_PROCEDING,
+ H225_CONNECT,
+ H225_ALERTING,
+ H225_INFORMATION,
+ H225_RELEASE_COMPLET,
+ H225_FACILITY,
+ H225_PROGRESS,
+ H225_EMPTY,
+ H225_STATUS,
+ H225_STATUS_INQUIRY,
+ H225_SETUP_ACK,
+ H225_NOTIFY,
+ H225_OTHER
} h225_cs_type;
typedef struct _h225_packet_info {
@@ -61,8 +69,10 @@ typedef struct _h225_packet_info {
/* added for h225 conversations analysis */
gboolean is_faststart; /* true, if faststart field is included */
gboolean is_h245;
+ gboolean is_h245Tunneling;
guint32 h245_address;
guint16 h245_port;
+ gchar frame_label[50]; /* the Fram label used by graph_analysis, what is a abreviation of cinfo */
} h225_packet_info;
/*
diff --git a/epan/dissectors/packet-h245.c b/epan/dissectors/packet-h245.c
index a6bbcf3c58..e91ffa26d3 100644
--- a/epan/dissectors/packet-h245.c
+++ b/epan/dissectors/packet-h245.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Ethereal dissector compiler */
-/* .\packet-h245.c */
+/* ./packet-h245.c */
/* ../../tools/asn2eth.py -X -e -p h245 -c h245.cnf -s packet-h245-template h245.asn */
/* Input file: packet-h245-template.c */
@@ -77,7 +77,10 @@ static int hf_h245_pdu_type = -1;
static int hf_h245Manufacturer = -1;
static int h245_tap = -1;
static int ett_h245 = -1;
-static h245_packet_info h245_pi;
+static int h245dg_tap = -1;
+static h245_packet_info pi_arr[5]; /* We assuming a maximum of 5 H245 messaages per packet */
+static int pi_current=0;
+h245_packet_info *h245_pi=NULL;
static gboolean h245_reassembly = TRUE;
static gboolean h245_shorttypes = FALSE;
@@ -171,6 +174,34 @@ static const value_string h245_CommandMessage_short_vals[] = {
{ 12, "GC" },
{ 0, NULL }
};
+static const value_string h245_AudioCapability_short_vals[] = {
+ { 0, "nonStd" },
+ { 1, "g711A" },
+ { 2, "g711A56k" },
+ { 3, "g711U" },
+ { 4, "g711U56k" },
+ { 5, "g722-64k" },
+ { 6, "g722-56k" },
+ { 7, "g722-48k" },
+ { 8, "g7231" },
+ { 9, "g728" },
+ { 10, "g729" },
+ { 11, "g729A" },
+ { 12, "is11172" },
+ { 13, "is13818" },
+ { 14, "g729B" },
+ { 15, "g729AB" },
+ { 16, "g7231C" },
+ { 17, "gsmFR" },
+ { 18, "gsmHR" },
+ { 19, "gsmEFR" },
+ { 20, "generic" },
+ { 21, "g729Ext" },
+ { 22, "vbd" },
+ { 23, "audioTelEvent" },
+ { 24, "audioTone" },
+ { 0, NULL }
+};
/* To put the codec type only in COL_INFO when
an OLC is read */
@@ -2418,7 +2449,7 @@ dissect_h245_MasterSlaveDetermination(tvbuff_t *tvb, int offset, packet_info *pi
ett_h245_MasterSlaveDetermination, MasterSlaveDetermination_sequence);
- h245_pi.msg_type = H245_MastSlvDet;
+ h245_pi->msg_type = H245_MastSlvDet;
return offset;
}
static int dissect_masterSlaveDetermination(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -5460,6 +5491,7 @@ dissect_h245_Application(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot
&value);
codec_type = val_to_str(value, h245_Application_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, codec_type);
return offset;
}
@@ -7226,6 +7258,8 @@ dissect_h245_VideoCapability(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
&value);
codec_type = val_to_str(value, h245_VideoCapability_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, codec_type);
+
return offset;
}
@@ -7595,7 +7629,9 @@ dissect_h245_AudioCapability(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
ett_h245_AudioCapability, AudioCapability_choice, "AudioCapability",
&value);
- codec_type = val_to_str(value, h245_AudioCapability_vals, "<unknown>");
+ codec_type = val_to_str(value, h245_AudioCapability_short_vals, "<unknown>");
+ if (h245_pi != NULL) g_snprintf(h245_pi->frame_label, 50, "%s %s", h245_pi->frame_label, val_to_str(value, h245_AudioCapability_short_vals, "ukn"));
+
return offset;
}
@@ -8187,7 +8223,7 @@ dissect_h245_TerminalCapabilitySet(tvbuff_t *tvb, int offset, packet_info *pinfo
ett_h245_TerminalCapabilitySet, TerminalCapabilitySet_sequence);
- h245_pi.msg_type = H245_TermCapSet;
+ h245_pi->msg_type = H245_TermCapSet;
return offset;
}
static int dissect_terminalCapabilitySet(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -10089,7 +10125,7 @@ dissect_h245_OpenLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinfo _U
ett_h245_OpenLogicalChannel, OpenLogicalChannel_sequence);
- h245_pi.msg_type = H245_OpenLogChn;
+ if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
return offset;
}
static int dissect_openLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -10161,7 +10197,7 @@ dissect_h245_CloseLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinfo _
ett_h245_CloseLogicalChannel, CloseLogicalChannel_sequence);
- h245_pi.msg_type = H245_CloseLogChn;
+ h245_pi->msg_type = H245_CloseLogChn;
return offset;
}
static int dissect_closeLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12166,6 +12202,20 @@ dissect_h245_RequestMessage(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, p
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+
+ /* if it is TCS*/
+ if ((codec_type != NULL) && ( value == 2))
+ g_snprintf(h245_pi->frame_label, 50, "%s (%s) ",val_to_str(value, h245_RequestMessage_short_vals, "UKN"), h245_pi->frame_label);
+ else
+ g_snprintf(h245_pi->frame_label, 50, "%s ", val_to_str(value, h245_RequestMessage_short_vals, "UKN"));
+
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_RequestMessage_vals, "<unknown>"));
+
+ /* if it is OLC or RM*/
+ if ((codec_type != NULL) && (( value == 3) || ( value == 8)))
+ g_snprintf(h245_pi->frame_label, 50, "%s (%s) ", h245_pi->frame_label, codec_type);
+
return offset;
}
static int dissect_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12208,7 +12258,7 @@ dissect_h245_MasterSlaveDeterminationAck(tvbuff_t *tvb, int offset, packet_info
ett_h245_MasterSlaveDeterminationAck, MasterSlaveDeterminationAck_sequence);
- h245_pi.msg_type = H245_MastSlvDetAck;
+ h245_pi->msg_type = H245_MastSlvDetAck;
return offset;
}
static int dissect_masterSlaveDeterminationAck(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12249,7 +12299,7 @@ dissect_h245_MasterSlaveDeterminationReject(tvbuff_t *tvb, int offset, packet_in
ett_h245_MasterSlaveDeterminationReject, MasterSlaveDeterminationReject_sequence);
- h245_pi.msg_type = H245_MastSlvDetRjc;
+ h245_pi->msg_type = H245_MastSlvDetRjc;
return offset;
}
static int dissect_masterSlaveDeterminationReject(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12267,7 +12317,7 @@ dissect_h245_TerminalCapabilitySetAck(tvbuff_t *tvb, int offset, packet_info *pi
ett_h245_TerminalCapabilitySetAck, TerminalCapabilitySetAck_sequence);
- h245_pi.msg_type = H245_TermCapSetAck;
+ h245_pi->msg_type = H245_TermCapSetAck;
return offset;
}
static int dissect_terminalCapabilitySetAck(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12340,7 +12390,7 @@ dissect_h245_TerminalCapabilitySetReject(tvbuff_t *tvb, int offset, packet_info
ett_h245_TerminalCapabilitySetReject, TerminalCapabilitySetReject_sequence);
- h245_pi.msg_type = H245_TermCapSetRjc;
+ h245_pi->msg_type = H245_TermCapSetRjc;
return offset;
}
static int dissect_terminalCapabilitySetReject(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12510,7 +12560,7 @@ dissect_h245_OpenLogicalChannelAck(tvbuff_t *tvb, int offset, packet_info *pinfo
ett_h245_OpenLogicalChannelAck, OpenLogicalChannelAck_sequence);
- h245_pi.msg_type = H245_OpenLogChnAck;
+ h245_pi->msg_type = H245_OpenLogChnAck;
return offset;
}
static int dissect_openLogicalChannelAck(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12578,7 +12628,7 @@ dissect_h245_OpenLogicalChannelReject(tvbuff_t *tvb, int offset, packet_info *pi
ett_h245_OpenLogicalChannelReject, OpenLogicalChannelReject_sequence);
- h245_pi.msg_type = H245_OpenLogChnRjc;
+ h245_pi->msg_type = H245_OpenLogChnRjc;
return offset;
}
static int dissect_openLogicalChannelReject(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -12596,7 +12646,7 @@ dissect_h245_CloseLogicalChannelAck(tvbuff_t *tvb, int offset, packet_info *pinf
ett_h245_CloseLogicalChannelAck, CloseLogicalChannelAck_sequence);
- h245_pi.msg_type = H245_CloseLogChnAck;
+ h245_pi->msg_type = H245_CloseLogChnAck;
return offset;
}
static int dissect_closeLogicalChannelAck(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -13867,6 +13917,10 @@ dissect_h245_ResponseMessage(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_ResponseMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_ResponseMessage_vals, "<unknown>"));
+
return offset;
}
static int dissect_response(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -15032,6 +15086,10 @@ dissect_h245_CommandMessage(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, p
}
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_CommandMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_CommandMessage_vals, "<unknown>"));
+
return offset;
}
@@ -15076,7 +15134,7 @@ dissect_h245_MasterSlaveDeterminationRelease(tvbuff_t *tvb, int offset, packet_i
ett_h245_MasterSlaveDeterminationRelease, MasterSlaveDeterminationRelease_sequence);
- h245_pi.msg_type = H245_MastSlvDetRls;
+ h245_pi->msg_type = H245_MastSlvDetRls;
return offset;
}
static int dissect_masterSlaveDeterminationRelease(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -15093,7 +15151,7 @@ dissect_h245_TerminalCapabilitySetRelease(tvbuff_t *tvb, int offset, packet_info
ett_h245_TerminalCapabilitySetRelease, TerminalCapabilitySetRelease_sequence);
- h245_pi.msg_type = H245_TermCapSetRls;
+ h245_pi->msg_type = H245_TermCapSetRls;
return offset;
}
static int dissect_terminalCapabilitySetRelease(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -15111,7 +15169,7 @@ dissect_h245_OpenLogicalChannelConfirm(tvbuff_t *tvb, int offset, packet_info *p
ett_h245_OpenLogicalChannelConfirm, OpenLogicalChannelConfirm_sequence);
- h245_pi.msg_type = H245_OpenLogChnCnf;
+ h245_pi->msg_type = H245_OpenLogChnCnf;
return offset;
}
static int dissect_openLogicalChannelConfirm(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
@@ -16193,6 +16251,9 @@ dissect_h245_IndicationMessage(tvbuff_t *tvb, int offset, packet_info *pinfo _U_
}
col_set_fence(pinfo->cinfo,COL_INFO);
+ /* Add to packet info */
+ g_snprintf(h245_pi->frame_label, 50, "%s %s ", h245_pi->frame_label, val_to_str(value, h245_IndicationMessage_short_vals, "UKN"));
+ g_snprintf(h245_pi->comment, 50, "%s %s ", h245_pi->comment, val_to_str(value, h245_IndicationMessage_vals, "<unknown>"));
return offset;
}
@@ -16255,12 +16316,18 @@ dissect_h245_Moderfc2733(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot
void
dissect_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
- reset_h245_packet_info(&(h245_pi));
- h245_pi.msg_type = H245_OTHER;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h245_pi=&pi_arr[pi_current];
+
+ reset_h245_packet_info(h245_pi);
+ h245_pi->msg_type = H245_OTHER;
dissect_tpkt_encap(tvb, pinfo, parent_tree, h245_reassembly, MultimediaSystemControlMessage_handle);
- tap_queue_packet(h245_tap, pinfo, &h245_pi);
+ tap_queue_packet(h245_tap, pinfo, h245_pi);
}
void
@@ -16270,6 +16337,14 @@ dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
proto_tree *tr;
guint32 offset=0;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ h245_pi=&pi_arr[pi_current];
+
+ reset_h245_packet_info(h245_pi);
+ h245_pi->msg_type = H245_OTHER;
if (check_col(pinfo->cinfo, COL_PROTOCOL)){
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.245");
@@ -16278,8 +16353,23 @@ dissect_h245_h245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
it=proto_tree_add_protocol_format(parent_tree, proto_h245, tvb, 0, tvb_length(tvb), "H.245");
tr=proto_item_add_subtree(it, ett_h245);
dissect_h245_MultimediaSystemControlMessage(tvb, offset, pinfo ,tr, hf_h245_pdu_type);
+ tap_queue_packet(h245dg_tap, pinfo, h245_pi);
}
+int
+dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *codec_str) {
+ offset = dissect_per_sequence(tvb, offset, pinfo, tree, hf_index,
+ ett_h245_OpenLogicalChannel, OpenLogicalChannel_sequence);
+
+
+ if (h245_pi != NULL) h245_pi->msg_type = H245_OpenLogChn;
+
+ if (codec_str){
+ g_strlcpy(codec_str, codec_type, 50);
+ }
+
+ return offset;
+}
/*--- proto_register_h245 -------------------------------------------*/
void proto_register_h245(void) {
@@ -22148,6 +22238,7 @@ void proto_register_h245(void) {
nsp_object_dissector_table = register_dissector_table("h245.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
nsp_h221_dissector_table = register_dissector_table("h245.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
h245_tap = register_tap("h245");
+ h245dg_tap = register_tap("h245dg");
register_ber_oid_name("0.0.8.239.1.1","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ControlCapability(1)");
register_ber_oid_name("0.0.8.239.1.2","itu-t(0) recommendation(0) h(8) h239(239) generic-capabilities(1) h239ExtendedVideoCapability(2)");
@@ -22187,5 +22278,7 @@ static void reset_h245_packet_info(h245_packet_info *pi)
}
pi->msg_type = H245_OTHER;
+ pi->frame_label[0] = '\0';
+ sprintf(pi->comment, "H245 ");
}
diff --git a/epan/dissectors/packet-h245.h b/epan/dissectors/packet-h245.h
index 71822bfedd..2c0d3633a2 100644
--- a/epan/dissectors/packet-h245.h
+++ b/epan/dissectors/packet-h245.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Ethereal dissector compiler */
-/* .\packet-h245.h */
+/* ./packet-h245.h */
/* ../../tools/asn2eth.py -X -e -p h245 -c h245.cnf -s packet-h245-template h245.asn */
/* Input file: packet-h245-template.h */
@@ -52,6 +52,8 @@ typedef enum _h245_msg_type {
typedef struct _h245_packet_info {
h245_msg_type msg_type; /* type of message */
+ gchar frame_label[50]; /* the Frame label used by graph_analysis, what is a abreviation of cinfo */
+ gchar comment[50]; /* the Frame Comment used by graph_analysis, what is a message desc */
} h245_packet_info;
@@ -65,6 +67,8 @@ int dissect_h245_OpenLogicalChannel(tvbuff_t *tvb, int offset, packet_info *pinf
/*--- End of included file: packet-h245-exp.h ---*/
+int dissect_h245_OpenLogicalChannelCodec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index, char *codec_str);
+
#endif /* PACKET_H245_H */
diff --git a/epan/dissectors/packet-isup.c b/epan/dissectors/packet-isup.c
index e89de7fe8b..63880f559b 100644
--- a/epan/dissectors/packet-isup.c
+++ b/epan/dissectors/packet-isup.c
@@ -1315,6 +1315,10 @@ static gint ett_bat_ase_iwfa = -1;
static dissector_handle_t sdp_handle = NULL;
static dissector_handle_t q931_ie_handle = NULL;
+/* Info for the tap that must be passed between procedures */
+gchar *tap_called_number = NULL;
+gchar *tap_calling_number = NULL;
+
/* ------------------------------------------------------------------
Mapping number to ASCII-character
------------------------------------------------------------------ */
@@ -1461,6 +1465,7 @@ dissect_isup_called_party_number_parameter(tvbuff_t *parameter_tvb, proto_tree *
proto_tree_add_string(address_digits_tree, hf_isup_called, parameter_tvb,
offset - length, length, called_number);
}
+ tap_called_number = g_strdup(called_number);
}
/* ------------------------------------------------------------------
Dissector Parameter Subsequent number
@@ -2868,8 +2873,8 @@ dissect_isup_calling_party_number_parameter(tvbuff_t *parameter_tvb, proto_tree
} else {
proto_tree_add_string(address_digits_tree, hf_isup_calling, parameter_tvb,
offset - length, length, calling_number);
-
}
+ tap_calling_number = g_strdup(calling_number);
}
/* ------------------------------------------------------------------
Dissector Parameter Original called number
@@ -5143,8 +5148,8 @@ dissect_isup_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *isup
offset += MESSAGE_TYPE_LENGTH;
tap_rec.message_type = message_type;
-
- tap_queue_packet(isup_tap, pinfo, &tap_rec);
+ tap_rec.calling_number = NULL;
+ tap_rec.called_number = NULL;
parameter_tvb = tvb_new_subset(message_tvb, offset, -1, -1);
@@ -5359,7 +5364,11 @@ dissect_isup_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *isup
}
else if (message_type !=MESSAGE_TYPE_CHARGE_INFO)
proto_tree_add_text(isup_tree, message_tvb, 0, 0, "No optional parameters are possible with this message type");
+ /* if there are calling/called number, we'll get them for the tap */
+ tap_rec.calling_number=tap_calling_number;
+ tap_rec.called_number=tap_called_number;
+ tap_queue_packet(isup_tap, pinfo, &tap_rec);
}
/* ------------------------------------------------------------------ */
diff --git a/epan/dissectors/packet-isup.h b/epan/dissectors/packet-isup.h
index 450b325fcb..edae5fb6c0 100644
--- a/epan/dissectors/packet-isup.h
+++ b/epan/dissectors/packet-isup.h
@@ -28,6 +28,9 @@
typedef struct _isup_tap_rec_t {
guint8 message_type;
+ /* added for VoIP calls analysis, see gtk/voip_calls.c*/
+ gchar *called_number;
+ gchar *calling_number;
} isup_tap_rec_t;
diff --git a/epan/dissectors/packet-q931.c b/epan/dissectors/packet-q931.c
index 2bcffd08b9..6bb9ba79ed 100644
--- a/epan/dissectors/packet-q931.c
+++ b/epan/dissectors/packet-q931.c
@@ -33,6 +33,7 @@
#include <glib.h>
#include <string.h>
#include <epan/packet.h>
+#include <epan/tap.h>
#include <epan/strutil.h>
#include "nlpid.h"
#include "packet-q931.h"
@@ -54,6 +55,12 @@
* http://www.andrews-arnold.co.uk/isdn/q931cause.html
* http://www.tulatelecom.ru/staff/german/DSSHelp/MessList/InfEl/InfElList.html
*/
+static void reset_q931_packet_info(q931_packet_info *pi);
+static gboolean have_valid_q931_pi=FALSE;
+static q931_packet_info pi_arr[5]; /* We assuming a maximum of 5 q931 messaages per packet */
+static int pi_current=0;
+static q931_packet_info *q931_pi=NULL;
+static int q931_tap = -1;
static int proto_q931 = -1;
static int hf_q931_discriminator = -1;
@@ -1211,6 +1218,12 @@ dissect_q931_cause_ie(tvbuff_t *tvb, int offset, int len,
return;
octet = tvb_get_guint8(tvb, offset);
cause_value = octet & 0x7F;
+
+ /* add cause value to packet info for use in tap */
+ if(have_valid_q931_pi) {
+ q931_pi->cause_value = cause_value;
+ }
+
proto_tree_add_uint(tree, hf_cause_value, tvb, offset, 1, cause_value);
proto_tree_add_boolean(tree, hf_q931_extension_ind, tvb, offset, 1, octet);
offset += 1;
@@ -2112,6 +2125,11 @@ dissect_q931_number_ie(tvbuff_t *tvb, int offset, int len,
}
}
+ /* Collect q931_packet_info */
+ if ( e164_info.e164_number_type == CALLING_PARTY_NUMBER && have_valid_q931_pi)
+ q931_pi->calling_number = tvb_get_string(tvb, offset, len);
+ if ( e164_info.e164_number_type == CALLED_PARTY_NUMBER && have_valid_q931_pi)
+ q931_pi->called_number = tvb_get_string(tvb, offset, len);
}
/*
@@ -2352,6 +2370,15 @@ dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
fragment_data *fd_head;
tvbuff_t *next_tvb = NULL;
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ q931_pi=&pi_arr[pi_current];
+ /* Init struct for collecting q931_packet_info */
+ reset_q931_packet_info(q931_pi);
+ have_valid_q931_pi=TRUE;
+
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Q.931");
@@ -2382,7 +2409,11 @@ dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
call_ref[0] &= 0x7F;
proto_tree_add_bytes(q931_tree, hf_q931_call_ref,
tvb, offset, call_ref_len, call_ref);
+ } else
+ { /* info for the tap */
+ call_ref[0] &= 0x7F;
}
+ g_memmove(&(q931_pi->crv), call_ref, call_ref_len);
offset += call_ref_len;
}
message_type = tvb_get_guint8(tvb, offset);
@@ -2689,196 +2720,202 @@ dissect_q931_IEs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root_tree,
proto_tree_add_text(q931_tree, tvb, offset + 4, tvb_reported_length_remaining(tvb, offset + 4), "Message segment");
info_element_len += tvb_reported_length_remaining(tvb, offset + 4);
}
- } else if (q931_tree != NULL) {
- switch ((codeset << 8) | info_element) {
-
- case CS0 | Q931_IE_BEARER_CAPABILITY:
- case CS0 | Q931_IE_LOW_LAYER_COMPAT:
- dissect_q931_bearer_capability_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_CAUSE:
- dissect_q931_cause_ie(tvb,
- offset + 2, info_element_len,
- ie_tree,
- hf_q931_cause_value);
- break;
-
- case CS0 | Q931_IE_CALL_STATE:
- dissect_q931_call_state_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_CHANNEL_IDENTIFICATION:
- dissect_q931_channel_identification_ie(
- tvb, offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_PROGRESS_INDICATOR:
- dissect_q931_progress_indicator_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_NETWORK_SPECIFIC_FACIL:
- case CS0 | Q931_IE_TRANSIT_NETWORK_SEL:
- dissect_q931_ns_facilities_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_NOTIFICATION_INDICATOR:
- dissect_q931_notification_indicator_ie(
- tvb, offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_DISPLAY:
- dissect_q931_ia5_ie(tvb, offset + 2,
- info_element_len, ie_tree,
- "Display information");
- break;
-
- case CS0 | Q931_IE_DATE_TIME:
- dissect_q931_date_time_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_KEYPAD_FACILITY:
- dissect_q931_ia5_ie(tvb, offset + 2,
- info_element_len, ie_tree,
- "Keypad facility");
- break;
-
- case CS0 | Q931_IE_SIGNAL:
- dissect_q931_signal_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_INFORMATION_RATE:
- dissect_q931_information_rate_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_E2E_TRANSIT_DELAY:
- dissect_q931_e2e_transit_delay_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_TD_SELECTION_AND_INT:
- dissect_q931_td_selection_and_int_ie(
- tvb, offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_PL_BINARY_PARAMETERS:
- dissect_q931_pl_binary_parameters_ie(
- tvb, offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_PL_WINDOW_SIZE:
- dissect_q931_pl_window_size_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_PACKET_SIZE:
- dissect_q931_packet_size_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_CUG:
- dissect_q931_cug_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_REVERSE_CHARGE_IND:
- dissect_q931_reverse_charge_ind_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_CALLING_PARTY_NUMBER:
- e164_info.e164_number_type = CALLING_PARTY_NUMBER;
- dissect_q931_number_ie(tvb,
- offset + 2, info_element_len,
- ie_tree,
- hf_q931_calling_party_number, e164_info);
- break;
-
- case CS0 | Q931_IE_CONNECTED_NUMBER_DEFAULT:
- dissect_q931_number_ie(tvb,
- offset + 2, info_element_len,
- ie_tree,
- hf_q931_connected_number, e164_info);
- break;
-
- case CS0 | Q931_IE_CALLED_PARTY_NUMBER:
- e164_info.e164_number_type = CALLED_PARTY_NUMBER;
- dissect_q931_number_ie(tvb,
- offset + 2, info_element_len,
- ie_tree,
- hf_q931_called_party_number, e164_info);
- break;
-
- case CS0 | Q931_IE_REDIRECTING_NUMBER:
- dissect_q931_number_ie(tvb,
- offset + 2, info_element_len,
- ie_tree,
- hf_q931_redirecting_number, e164_info);
- break;
-
- case CS0 | Q931_IE_CALLING_PARTY_SUBADDR:
- case CS0 | Q931_IE_CALLED_PARTY_SUBADDR:
- dissect_q931_party_subaddr_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_RESTART_INDICATOR:
- dissect_q931_restart_indicator_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_HIGH_LAYER_COMPAT:
- dissect_q931_high_layer_compat_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- case CS0 | Q931_IE_USER_USER:
- dissect_q931_user_user_ie(tvb,
- offset + 2, info_element_len,
- ie_tree);
- break;
-
- default:
- proto_tree_add_text(ie_tree, tvb,
- offset + 2, info_element_len,
- "Data: %s",
- bytes_to_str(
- tvb_get_ptr(tvb, offset + 2,
- info_element_len),
- info_element_len));
- break;
+ } else {
+ /* we move calling, called number and release cause to not check tree=NULL for the tap used in Voip Calls... */
+ switch ((codeset << 8) | info_element){
+ case CS0 | Q931_IE_CALLING_PARTY_NUMBER:
+ e164_info.e164_number_type = CALLING_PARTY_NUMBER;
+ dissect_q931_number_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree,
+ hf_q931_calling_party_number, e164_info);
+ break;
+ case CS0 | Q931_IE_CALLED_PARTY_NUMBER:
+ e164_info.e164_number_type = CALLED_PARTY_NUMBER;
+ dissect_q931_number_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree,
+ hf_q931_called_party_number, e164_info);
+ break;
+ case CS0 | Q931_IE_CAUSE:
+ dissect_q931_cause_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree,
+ hf_q931_cause_value);
+ break;
+ }
+ if (q931_tree != NULL) {
+ switch ((codeset << 8) | info_element) {
+
+ case CS0 | Q931_IE_BEARER_CAPABILITY:
+ case CS0 | Q931_IE_LOW_LAYER_COMPAT:
+ dissect_q931_bearer_capability_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_CALL_STATE:
+ dissect_q931_call_state_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_CHANNEL_IDENTIFICATION:
+ dissect_q931_channel_identification_ie(
+ tvb, offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_PROGRESS_INDICATOR:
+ dissect_q931_progress_indicator_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_NETWORK_SPECIFIC_FACIL:
+ case CS0 | Q931_IE_TRANSIT_NETWORK_SEL:
+ dissect_q931_ns_facilities_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_NOTIFICATION_INDICATOR:
+ dissect_q931_notification_indicator_ie(
+ tvb, offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_DISPLAY:
+ dissect_q931_ia5_ie(tvb, offset + 2,
+ info_element_len, ie_tree,
+ "Display information");
+ break;
+
+ case CS0 | Q931_IE_DATE_TIME:
+ dissect_q931_date_time_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_KEYPAD_FACILITY:
+ dissect_q931_ia5_ie(tvb, offset + 2,
+ info_element_len, ie_tree,
+ "Keypad facility");
+ break;
+
+ case CS0 | Q931_IE_SIGNAL:
+ dissect_q931_signal_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_INFORMATION_RATE:
+ dissect_q931_information_rate_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_E2E_TRANSIT_DELAY:
+ dissect_q931_e2e_transit_delay_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_TD_SELECTION_AND_INT:
+ dissect_q931_td_selection_and_int_ie(
+ tvb, offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_PL_BINARY_PARAMETERS:
+ dissect_q931_pl_binary_parameters_ie(
+ tvb, offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_PL_WINDOW_SIZE:
+ dissect_q931_pl_window_size_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_PACKET_SIZE:
+ dissect_q931_packet_size_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_CUG:
+ dissect_q931_cug_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_REVERSE_CHARGE_IND:
+ dissect_q931_reverse_charge_ind_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_CONNECTED_NUMBER_DEFAULT:
+ dissect_q931_number_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree,
+ hf_q931_connected_number, e164_info);
+ break;
+
+ case CS0 | Q931_IE_REDIRECTING_NUMBER:
+ dissect_q931_number_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree,
+ hf_q931_redirecting_number, e164_info);
+ break;
+
+ case CS0 | Q931_IE_CALLING_PARTY_SUBADDR:
+ case CS0 | Q931_IE_CALLED_PARTY_SUBADDR:
+ dissect_q931_party_subaddr_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_RESTART_INDICATOR:
+ dissect_q931_restart_indicator_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_HIGH_LAYER_COMPAT:
+ dissect_q931_high_layer_compat_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ case CS0 | Q931_IE_USER_USER:
+ dissect_q931_user_user_ie(tvb,
+ offset + 2, info_element_len,
+ ie_tree);
+ break;
+
+ default:
+ proto_tree_add_text(ie_tree, tvb,
+ offset + 2, info_element_len,
+ "Data: %s",
+ bytes_to_str(
+ tvb_get_ptr(tvb, offset + 2,
+ info_element_len),
+ info_element_len));
+ break;
+ }
}
}
offset += 1 + 1 + info_element_len;
}
codeset = locked_codeset;
}
+ if(have_valid_q931_pi) {
+ tap_queue_packet(q931_tap, pinfo, q931_pi);
+ }
+ have_valid_q931_pi=FALSE;
}
/*
@@ -3143,6 +3180,8 @@ proto_register_q931(void)
"Reassemble segmented Q.931 messages",
"Reassemble segmented Q.931 messages (Q.931 - Annex H)",
&q931_reassembly);
+ /* Register for tapping */
+ q931_tap = register_tap("q931");
}
void
@@ -3166,3 +3205,17 @@ proto_reg_handoff_q931(void)
*/
heur_dissector_add("tcp", dissect_q931_tpkt, proto_q931);
}
+
+static void reset_q931_packet_info(q931_packet_info *pi)
+{
+ if(pi == NULL) {
+ return;
+ }
+
+ g_free(pi->calling_number);
+ g_free(pi->called_number);
+ pi->calling_number = NULL;
+ pi->called_number = NULL;
+ pi->cause_value = 0xFF;
+ pi->crv = -1;
+}
diff --git a/epan/dissectors/packet-q931.h b/epan/dissectors/packet-q931.h
index 8ce65ca368..0f0a12ced2 100644
--- a/epan/dissectors/packet-q931.h
+++ b/epan/dissectors/packet-q931.h
@@ -44,7 +44,19 @@ extern void dissect_q931_user_user_ie(tvbuff_t *tvb, int offset, int len,
extern const value_string q931_cause_location_vals[];
-extern const value_string q931_cause_code_vals[];
+typedef struct _q931_packet_info {
+ gchar *calling_number;
+ gchar *called_number;
+ guint8 cause_value;
+ gint32 crv;
+} q931_packet_info;
+
+/*
+ * the following allows TAP code access to the messages
+ * without having to duplicate it. With MSVC and a
+ * libethereal.dll, we need a special declaration.
+ */
+ETH_VAR_IMPORT const value_string q931_cause_code_vals[];
extern const value_string q931_protocol_discriminator_vals[];
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index 80ef73577a..3d12e5ca35 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -190,6 +190,38 @@ const value_string rtp_payload_type_vals[] =
{ 0, NULL },
};
+const value_string rtp_payload_type_short_vals[] =
+{
+ { PT_PCMU, "g711U" },
+ { PT_1016, "fs-1016" },
+ { PT_G721, "g721" },
+ { PT_GSM, "GSM" },
+ { PT_G723, "g723" },
+ { PT_DVI4_8000, "DVI4 8k" },
+ { PT_DVI4_16000, "DVI4 16k" },
+ { PT_LPC, "Exp. from Xerox PARC" },
+ { PT_PCMA, "g711A" },
+ { PT_G722, "g722" },
+ { PT_L16_STEREO, "16-bit audio, stereo" },
+ { PT_L16_MONO, "16-bit audio, monaural" },
+ { PT_QCELP, "Qualcomm" },
+ { PT_CN, "CN" },
+ { PT_MPA, "MPEG-I/II Audio"},
+ { PT_G728, "g728" },
+ { PT_DVI4_11025, "DVI4 11k" },
+ { PT_DVI4_22050, "DVI4 22k" },
+ { PT_G729, "g729" },
+ { PT_CN_OLD, "CN(old)" },
+ { PT_CELB, "CellB" },
+ { PT_JPEG, "JPEG" },
+ { PT_NV, "NV" },
+ { PT_H261, "h261" },
+ { PT_MPV, "MPEG-I/II Video"},
+ { PT_MP2T, "MPEG-II streams"},
+ { PT_H263, "h263" },
+ { 0, NULL },
+};
+
/* Set up an RTP conversation */
void rtp_add_address(packet_info *pinfo,
address *addr, int port,
diff --git a/epan/dissectors/packet-sdp.c b/epan/dissectors/packet-sdp.c
index b88719584a..9afa2e6af5 100644
--- a/epan/dissectors/packet-sdp.c
+++ b/epan/dissectors/packet-sdp.c
@@ -57,6 +57,9 @@
#include <epan/conversation.h>
#include <epan/strutil.h>
+#include "tap.h"
+#include "packet-sdp.h"
+
#include "packet-rtp.h"
#include "rtp_pt.h"
#include "packet-rtcp.h"
@@ -68,6 +71,10 @@ static dissector_handle_t rtcp_handle=NULL;
static dissector_handle_t t38_handle=NULL;
+static void reset_sdp_packet_info(sdp_packet_info *pi);
+static int sdp_tap = -1;
+static sdp_packet_info *sdp_pi;
+
static int proto_sdp = -1;
/* Top level fields */
@@ -213,6 +220,10 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint32 ipaddr[4];
gint n;
+ /* Initialise packet info for passing to tap */
+ sdp_pi = g_malloc(sizeof(sdp_packet_info));
+ sdp_pi->summary_str[0] = '\0';
+
/* Initialise RTP channel info */
transport_info.connection_address=NULL;
transport_info.connection_type=NULL;
@@ -436,6 +447,8 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_text(sdp_tree, tvb, offset, datalen,
"Data (%d bytes)", datalen);
}
+ /* Report this packet to the tap */
+ tap_queue_packet(sdp_tap, pinfo, sdp_pi);
}
static void
@@ -884,6 +897,7 @@ dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
media_format = tvb_get_string(tvb, offset, tokenlen);
proto_tree_add_string(sdp_media_tree, hf_media_format, tvb, offset,
tokenlen, val_to_str(atol(media_format), rtp_payload_type_vals, "%u"));
+ g_snprintf(sdp_pi->summary_str, 50, "%s %s", sdp_pi->summary_str, val_to_str(atol(media_format), rtp_payload_type_short_vals, "%u"));
g_free(media_format);
} else {
proto_tree_add_item(sdp_media_tree, hf_media_format, tvb,
@@ -1167,6 +1181,9 @@ proto_register_sdp(void)
* on Windows without stuffing it into the Big Transfer Vector).
*/
register_dissector("sdp", dissect_sdp, proto_sdp);
+
+ /* Register for tapping */
+ sdp_tap = register_tap("sdp");
}
void
diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c
index d373e42189..1bb62b8ca8 100644
--- a/epan/dissectors/packet-sip.c
+++ b/epan/dissectors/packet-sip.c
@@ -605,12 +605,17 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
char *media_type_str_lower_case = NULL;
char *content_type_parameter_str = NULL;
guint resend_for_packet = 0;
+ char *string;
/* Initialise stat info for passing to tap */
stat_info = g_malloc(sizeof(sip_info_value_t));
stat_info->response_code = 0;
stat_info->request_method = NULL;
+ stat_info->reason_phrase = NULL;
stat_info->resend = 0;
+ stat_info->tap_call_id = NULL;
+ stat_info->tap_from_addr = NULL;
+ stat_info->tap_to_addr = NULL;
/*
* Note that "tvb_find_line_end()" will return a value that
@@ -660,6 +665,11 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_add_fstr(pinfo->cinfo, COL_INFO, "Status: %s",
tvb_format_text(tvb, SIP2_HDR_LEN + 1, linelen - SIP2_HDR_LEN - 1));
}
+ string = tvb_get_string(tvb, SIP2_HDR_LEN + 5, linelen - (SIP2_HDR_LEN + 5));
+ stat_info->reason_phrase = g_malloc(linelen - (SIP2_HDR_LEN + 5) + 1);
+ strncpy(stat_info->reason_phrase, string, linelen - (SIP2_HDR_LEN + 5) + 1);
+ /* String no longer needed */
+ g_free(string);
break;
case OTHER_LINE:
@@ -843,6 +853,9 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
parameter_len = parameter_end_offset - parameter_offset;
proto_tree_add_item(sip_element_tree, hf_sip_to_addr, tvb, parameter_offset,
parameter_len, FALSE);
+ /*info for the tap for voip_calls.c*/
+ stat_info->tap_to_addr=tvb_get_string(tvb, parameter_offset, parameter_len);
+
parameter_offset = parameter_end_offset + 1;
/*
* URI parameters ?
@@ -875,6 +888,8 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
parameter_len = parameter_end_offset - parameter_offset;
proto_tree_add_item(sip_element_tree, hf_sip_to_addr, tvb, parameter_offset,
parameter_len, FALSE);
+ /*info for the tap for voip_calls.c*/
+ stat_info->tap_to_addr=tvb_get_string(tvb, parameter_offset, parameter_len);
offset = parameter_end_offset;
}
/* Find parameter tag if present.
@@ -948,6 +963,8 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
parameter_len = parameter_end_offset - parameter_offset;
dfilter_store_sip_from_addr(tvb, sip_element_tree,
parameter_offset, parameter_len);
+ /*info for the tap for voip_calls.c*/
+ stat_info->tap_from_addr=tvb_get_string(tvb, parameter_offset, parameter_len);
parameter_offset = parameter_end_offset + 1;
/*
* URI parameters ?
@@ -980,6 +997,8 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
parameter_len = parameter_end_offset - parameter_offset;
proto_tree_add_item(sip_element_tree, hf_sip_from_addr, tvb, parameter_offset,
parameter_len, FALSE);
+ /*info for the tap for voip_calls.c*/
+ stat_info->tap_from_addr=tvb_get_string(tvb, parameter_offset, parameter_len);
offset = parameter_end_offset;
}
/* Find parameter tag if present.
@@ -1008,6 +1027,7 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* Store the sequence number */
cseq_number = atoi(value);
cseq_number_set = 1;
+ stat_info->tap_cseq_number=cseq_number;
/* Extract method name from value */
for (value_offset = 0; value_offset < (gint)strlen(value); value_offset++)
@@ -1034,7 +1054,8 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
strlen(value)+1 < MAX_CALL_ID_SIZE ?
strlen(value)+1 :
MAX_CALL_ID_SIZE);
-
+ stat_info->tap_call_id = g_strdup(call_id);
+
/* Add 'Call-id' string item to tree */
if(hdr_tree) {
proto_tree_add_string_format(hdr_tree,
diff --git a/epan/dissectors/packet-sip.h b/epan/dissectors/packet-sip.h
index e8702758e5..dae72fb8b6 100644
--- a/epan/dissectors/packet-sip.h
+++ b/epan/dissectors/packet-sip.h
@@ -31,6 +31,12 @@ typedef struct _sip_info_value_t
gchar *request_method;
guint response_code;
guchar resend;
+ /* added for VoIP calls analysis, see gtk/voip_calls.c*/
+ gchar *tap_call_id;
+ gchar *tap_from_addr;
+ gchar *tap_to_addr;
+ guint32 tap_cseq_number;
+ gchar *reason_phrase;
} sip_info_value_t;
extern void dfilter_store_sip_from_addr(tvbuff_t *tvb,proto_tree *tree,guint parameter_offset,
diff --git a/epan/libethereal.def b/epan/libethereal.def
index 25fd5495f3..dfe6789839 100644
--- a/epan/libethereal.def
+++ b/epan/libethereal.def
@@ -430,6 +430,7 @@ proto_tree_children_foreach
proto_tree_get_parent
p_add_proto_data
p_get_proto_data
+q931_cause_code_vals DATA
range_convert_range
range_convert_str
range_copy
@@ -470,6 +471,7 @@ rpc_roundup
rtcp_add_address
rtp_add_address
rtp_payload_type_vals DATA
+rtp_payload_type_short_vals DATA
set_actual_length
set_timestamp_setting
show_fragment_seq_tree
diff --git a/gtk/graph_analysis.c b/gtk/graph_analysis.c
new file mode 100644
index 0000000000..34e7d60fce
--- /dev/null
+++ b/gtk/graph_analysis.c
@@ -0,0 +1,1009 @@
+/* graph_analysis.c
+ * Graphic Analysis addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Verso Technologies Inc.
+ * By Alejandro Vaquero <alejandrovaquero@yahoo.com>
+ *
+ * based on rtp_analysis.c and io_stat
+ *
+ *
+ * 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 "graph_analysis.h"
+
+#include <epan/epan_dissect.h>
+#include <epan/filesystem.h>
+
+#include "util.h"
+#include <epan/tap.h>
+#include "register.h"
+#include <epan/dissectors/packet-rtp.h>
+
+/* in /gtk ... */
+#include <gtk/gtk.h>
+#include "gtkglobals.h"
+
+#include "dlg_utils.h"
+#include "ui_util.h"
+#include "alert_box.h"
+#include "simple_dialog.h"
+#include "tap_menu.h"
+#include "main.h"
+#include "progress_dlg.h"
+#include "compat_macros.h"
+#include "../color.h"
+
+#include "image/clist_ascend.xpm"
+#include "image/clist_descend.xpm"
+
+#include <math.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_IO_H
+#include <io.h> /* open/close on win32 */
+#endif
+
+/* Win32 needs the O_BINARY flag for open() */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/****************************************************************************/
+
+
+#define OK_TEXT "[ Ok ]"
+#define PT_UNDEFINED -1
+
+
+#if GTK_MAJOR_VERSION < 2
+GtkRcStyle *rc_style;
+GdkColormap *colormap;
+#endif
+
+typedef const guint8 * ip_addr_p;
+
+
+/****************************************************************************/
+/* Reset the user_data structure */
+static void graph_analysis_reset(graph_analysis_data_t* user_data)
+{
+ int i;
+
+ user_data->num_nodes = 0;
+ user_data->num_items = 0;
+ for (i=0; i<MAX_NUM_NODES; i++){
+ user_data->nodes[i] = 0;
+ }
+
+ user_data->dlg.first_node=0;
+ user_data->dlg.first_item=0;
+ user_data->dlg.left_x_border=0;
+ user_data->dlg.selected_item=0xFFFFFFFF; /*not item selected */
+}
+
+/****************************************************************************/
+/* Reset the user_data structure */
+static void graph_analysis_init_dlg(graph_analysis_data_t* user_data)
+{
+ /* init dialog_graph */
+ user_data->dlg.needs_redraw=TRUE;
+ user_data->dlg.draw_area=NULL;
+ user_data->dlg.pixmap=NULL;
+ user_data->dlg.h_scrollbar=NULL;
+ user_data->dlg.h_scrollbar_adjustment=NULL;
+ user_data->dlg.v_scrollbar=NULL;
+ user_data->dlg.v_scrollbar_adjustment=NULL;
+ user_data->dlg.pixmap_width=600;
+ user_data->dlg.pixmap_height=400;
+ user_data->dlg.first_node=0;
+ user_data->dlg.first_item=0;
+ user_data->dlg.left_x_border=0;
+ user_data->dlg.selected_item=0xFFFFFFFF; /*not item selected */
+ user_data->dlg.window=NULL;
+}
+
+/****************************************************************************/
+/* CALLBACKS */
+
+
+/****************************************************************************/
+/* close the dialog window and remove the tap listener */
+static void on_destroy(GtkWidget *win _U_, graph_analysis_data_t *user_data _U_)
+{
+
+ g_free(user_data);
+}
+
+
+/****************************************************************************/
+static void dialog_graph_set_title(graph_analysis_data_t* user_data)
+{
+ char *title;
+ if (!user_data->dlg.window){
+ return;
+ }
+ title = g_strdup_printf("Ale");
+
+ gtk_window_set_title(GTK_WINDOW(user_data->dlg.window), title);
+ g_free(title);
+}
+
+#define RIGHT_ARROW 1
+#define LEFT_ARROW 0
+#define WIDTH_ARROW 8
+#define HEIGHT_ARROW 6
+
+/****************************************************************************/
+static void draw_arrow(GdkDrawable *pixmap, GdkGC *gc, gint x, gint y, boolean direction)
+{
+ GdkPoint arrow_point[3];
+
+ arrow_point[0].x = x;
+ arrow_point[0].y = y-HEIGHT_ARROW/2;
+ if (direction == RIGHT_ARROW)
+ arrow_point[1].x = x+WIDTH_ARROW;
+ else
+ arrow_point[1].x = x-WIDTH_ARROW;
+ arrow_point[1].y = y;
+ arrow_point[2].x = x;
+ arrow_point[2].y = y+HEIGHT_ARROW/2;;
+
+ gdk_draw_polygon(pixmap, gc, TRUE,
+ arrow_point, 3);
+}
+
+#define MAX_LABEL 50
+#define MAX_COMMENT 60
+#define ITEM_HEIGHT 20
+#define NODE_WIDTH 100
+#define TOP_Y_BORDER 40
+#define BOTTOM_Y_BORDER 0
+#define COMMENT_WIDTH 250
+
+/****************************************************************************/
+static void dialog_graph_draw(graph_analysis_data_t* user_data)
+{
+ guint32 i, last_item, first_item, last_node, first_node, display_items, display_nodes;
+ guint32 start_arrow, end_arrow, label_x, src_port_x, dst_port_x, arrow_width;
+ guint32 current_item;
+ guint32 left_x_border;
+ guint32 right_x_border;
+ guint32 top_y_border;
+ guint32 bottom_y_border;
+ graph_analysis_item_t *gai;
+ gboolean display_label;
+
+#if GTK_MAJOR_VERSION < 2
+ GdkFont *font;
+ FONT_TYPE *big_font;
+ FONT_TYPE *small_font;
+#else
+ PangoLayout *layout;
+ PangoLayout *big_layout;
+ PangoLayout *small_layout;
+#endif
+ guint32 label_width, label_height;
+ guint32 draw_width, draw_height;
+ char label_string[MAX_COMMENT];
+ GList* list;
+
+ /* new variables */
+
+#if GTK_MAJOR_VERSION <2
+ font = user_data->dlg.draw_area->style->font;
+ big_font = gdk_font_load("-adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1");
+ small_font = gdk_font_load("-adobe-helvetica-bold-r-normal--10-120-75-75-p-70-iso8859-1");
+#endif
+ if(!user_data->dlg.needs_redraw){
+ return;
+ }
+ user_data->dlg.needs_redraw=FALSE;
+
+ /*
+ * Clear out old plot
+ */
+ gdk_draw_rectangle(user_data->dlg.pixmap,
+ user_data->dlg.draw_area->style->white_gc,
+ TRUE,
+ 0, 0,
+ user_data->dlg.draw_area->allocation.width,
+ user_data->dlg.draw_area->allocation.height);
+
+ /* Calculate the y border */
+ top_y_border=TOP_Y_BORDER; /* to display the node IP address */
+ bottom_y_border=BOTTOM_Y_BORDER;
+
+ draw_height=user_data->dlg.pixmap_height-top_y_border-bottom_y_border;
+
+ first_item = user_data->dlg.first_item;
+ display_items = draw_height/ITEM_HEIGHT;
+ last_item = first_item+display_items-1;
+
+ /* get the items to display and fill the matrix array */
+ list = g_list_first(user_data->graph_info->list);
+ current_item = 0;
+ i = 0;
+ while (list)
+ {
+ gai = list->data;
+ if (gai->display){
+ if (current_item>=display_items) break; /* the item is outside the display */
+ if (i>=first_item){
+ user_data->dlg.items[current_item].frame_num = gai->frame_num;
+ user_data->dlg.items[current_item].time = gai->time;
+ user_data->dlg.items[current_item].port_src = gai->port_src;
+ user_data->dlg.items[current_item].port_dst = gai->port_dst;
+ /* Add "..." if the length is 50 characters */
+ if (strlen(gai->frame_label) > 48) {
+ gai->frame_label[48] = '.';
+ gai->frame_label[47] = '.';
+ gai->frame_label[46] = '.';
+ }
+ user_data->dlg.items[current_item].frame_label = gai->frame_label;
+ user_data->dlg.items[current_item].comment = gai->comment;
+ user_data->dlg.items[current_item].conv_num = gai->conv_num;
+ user_data->dlg.items[current_item].src_node = gai->src_node;
+ user_data->dlg.items[current_item].dst_node = gai->dst_node;
+ user_data->dlg.items[current_item].line_style = gai->line_style;
+ current_item++;
+ }
+ i++;
+ }
+
+ list = g_list_next(list);
+ }
+ /* in case the windows is resized so we have to move the top item */
+ if ((first_item + display_items) > user_data->num_items){
+ if (display_items>user_data->num_items)
+ first_item=0;
+ else
+ first_item = user_data->num_items - display_items;
+ }
+
+ /* in case there are less items than possible displayed */
+ display_items = current_item;
+ last_item = first_item+display_items-1;
+
+ /* if not items to display */
+ if (display_items == 0) return;
+
+
+ /* Calculate the x borders */
+ /* We use time from the last display item to calcultate the x left border */
+ g_snprintf(label_string, MAX_LABEL, "%.3f", user_data->dlg.items[display_items-1].time);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(font, label_string);
+ label_height=gdk_string_height(font, label_string);
+#else
+ layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area, label_string);
+ big_layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area, label_string);
+ small_layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area, label_string);
+
+ pango_layout_set_font_description(big_layout, pango_font_description_from_string("Helvetica-Bold 8"));
+ pango_layout_set_font_description(small_layout, pango_font_description_from_string("Helvetica-Bold 7"));
+
+ pango_layout_get_pixel_size(layout, &label_width, &label_height);
+#endif
+ left_x_border=label_width+10;
+ user_data->dlg.left_x_border = left_x_border;
+
+ right_x_border=COMMENT_WIDTH;
+
+ /* Calculate the number of nodes to display */
+ draw_width=user_data->dlg.pixmap_width-right_x_border-left_x_border;
+ display_nodes = draw_width/NODE_WIDTH;
+ first_node = user_data->dlg.first_node;
+
+ /* in case the windows is resized so we have to move the left node */
+ if ((first_node + display_nodes) > user_data->num_nodes){
+ if (display_nodes>user_data->num_nodes)
+ first_node=0;
+ else
+ first_node=user_data->num_nodes - display_nodes;
+ }
+
+ /* in case there are less nodes than possible displayed */
+ if (display_nodes>user_data->num_nodes) display_nodes=user_data->num_nodes;
+
+ last_node = first_node + display_nodes-1;
+
+ /* Paint the background items */
+ for (current_item=0; current_item<display_items; current_item++){
+ /* Paint background */
+ gdk_draw_rectangle(user_data->dlg.pixmap,
+ user_data->dlg.bg_gc[user_data->dlg.items[current_item].conv_num%MAX_NUM_COL_CONV],
+ TRUE,
+ left_x_border,
+ top_y_border+current_item*ITEM_HEIGHT,
+ draw_width,
+ ITEM_HEIGHT);
+ }
+
+
+ /* Draw the node names on top and the division lines */
+ for (i=0; i<display_nodes; i++){
+ /* draw the node IPs */
+ g_snprintf(label_string, MAX_LABEL, "%s",
+ ip_to_str((guint8 *)&(user_data->nodes[i+first_node])));
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(font, label_string);
+ label_height=gdk_string_height(font, label_string);
+ gdk_draw_string(user_data->dlg.pixmap,
+ font,
+ user_data->dlg.draw_area->style->black_gc,
+ left_x_border+NODE_WIDTH/2-label_width/2+NODE_WIDTH*i,
+ top_y_border/2-label_height/2,
+ label_string);
+#else
+ pango_layout_set_text(layout, label_string, -1);
+ pango_layout_get_pixel_size(layout, &label_width, &label_height);
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.draw_area->style->black_gc,
+ left_x_border+NODE_WIDTH/2-label_width/2+NODE_WIDTH*i,
+ top_y_border/2-label_height/2,
+ layout);
+#endif
+
+ /* draw the node division lines */
+ gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.div_line_gc,
+ left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
+ top_y_border,
+ left_x_border+NODE_WIDTH/2+NODE_WIDTH*i,
+ user_data->dlg.pixmap_height-bottom_y_border);
+
+ }
+
+ /*
+ * Draw the items
+ */
+
+
+ for (current_item=0; current_item<display_items; current_item++){
+ /* draw the time */
+ g_snprintf(label_string, MAX_LABEL, "%.3f", user_data->dlg.items[current_item].time);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(font, label_string);
+ label_height=gdk_string_height(font, label_string);
+ gdk_draw_string(user_data->dlg.pixmap,
+ font,
+ user_data->dlg.draw_area->style->black_gc,
+ left_x_border-label_width-4,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4,
+ label_string);
+#else
+ pango_layout_set_text(layout, label_string, -1);
+ pango_layout_get_pixel_size(layout, &label_width, &label_height);
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.draw_area->style->black_gc,
+ left_x_border-label_width-4,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+ layout);
+#endif
+
+ /*draw the comments */
+ g_snprintf(label_string, MAX_COMMENT, "%s", user_data->dlg.items[current_item].comment);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(small_font, label_string);
+ label_height=gdk_string_height(small_font, label_string);
+ gdk_draw_string(user_data->dlg.pixmap,
+ small_font,
+ user_data->dlg.draw_area->style->black_gc,
+ user_data->dlg.pixmap_width-right_x_border+3,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4,
+ label_string);
+#else
+ pango_layout_set_text(small_layout, label_string, -1);
+ pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.draw_area->style->black_gc,
+ user_data->dlg.pixmap_width-right_x_border+3,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+ small_layout);
+#endif
+
+ /* draw the arrow an frame label*/
+ display_label = FALSE;
+ if (user_data->dlg.items[current_item].src_node>=first_node){
+ if (user_data->dlg.items[current_item].src_node<=last_node){
+ start_arrow = left_x_border+(user_data->dlg.items[current_item].src_node-first_node)*NODE_WIDTH+NODE_WIDTH/2;
+ display_label = TRUE;
+ } else {
+ start_arrow = user_data->dlg.pixmap_width - right_x_border;
+ }
+ } else {
+ start_arrow = left_x_border;
+ }
+
+ if (user_data->dlg.items[current_item].dst_node>=first_node){
+ if (user_data->dlg.items[current_item].dst_node<=last_node){
+ end_arrow = left_x_border+(user_data->dlg.items[current_item].dst_node-first_node)*NODE_WIDTH+NODE_WIDTH/2;
+ display_label = TRUE;
+ } else {
+ end_arrow = user_data->dlg.pixmap_width - right_x_border;
+ }
+ } else {
+ end_arrow = left_x_border;
+ }
+
+ if (start_arrow != end_arrow){
+ /* draw the arrow line */
+ gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.draw_area->style->black_gc,
+ start_arrow,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7,
+ end_arrow,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7);
+
+ /* draw the additional line when line style is 2 pixels width */
+ if (user_data->dlg.items[current_item].line_style == 2){
+ gdk_draw_line(user_data->dlg.pixmap, user_data->dlg.draw_area->style->black_gc,
+ start_arrow,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-6,
+ end_arrow,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-6);
+ }
+
+ /* draw the arrow */
+ if (start_arrow<end_arrow)
+ draw_arrow(user_data->dlg.pixmap, user_data->dlg.draw_area->style->black_gc, end_arrow-WIDTH_ARROW,top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7, RIGHT_ARROW);
+ else
+ draw_arrow(user_data->dlg.pixmap, user_data->dlg.draw_area->style->black_gc, end_arrow+WIDTH_ARROW,top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-7, LEFT_ARROW);
+ }
+
+ /* draw the frame comment */
+ if (display_label){
+ g_snprintf(label_string, MAX_LABEL, "%s", user_data->dlg.items[current_item].frame_label);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(big_font, label_string);
+ label_height=gdk_string_height(big_font, label_string);
+#else
+ pango_layout_set_text(big_layout, label_string, -1);
+ pango_layout_get_pixel_size(big_layout, &label_width, &label_height);
+#endif
+
+ if (start_arrow<end_arrow){
+ arrow_width = end_arrow-start_arrow;
+ label_x = arrow_width/2+start_arrow;
+ }
+ else {
+ arrow_width = start_arrow-end_arrow;
+ label_x = arrow_width/2+end_arrow;
+ }
+
+ if (label_width>arrow_width) arrow_width = label_width;
+
+ if (left_x_border > (label_x-label_width/2)) label_x = left_x_border + label_width/2;
+
+ if ((user_data->dlg.pixmap_width - right_x_border) < (label_x+label_width/2)) label_x = user_data->dlg.pixmap_width - right_x_border - label_width/2;
+
+#if GTK_MAJOR_VERSION < 2
+ gdk_draw_string(user_data->dlg.pixmap,
+ big_font,
+ user_data->dlg.draw_area->style->black_gc,
+ label_x - label_width/2,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4-3,
+ label_string);
+#else
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.draw_area->style->black_gc,
+ label_x - label_width/2,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2-3,
+ big_layout);
+#endif
+
+ /* draw the source port number */
+ if ((start_arrow != left_x_border) && (start_arrow != (user_data->dlg.pixmap_width - right_x_border))){
+ g_snprintf(label_string, MAX_LABEL, "(%i)", user_data->dlg.items[current_item].port_src);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(small_font, label_string);
+ label_height=gdk_string_height(small_font, label_string);
+#else
+ pango_layout_set_text(small_layout, label_string, -1);
+ pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
+#endif
+ if (start_arrow<end_arrow){
+ src_port_x = start_arrow - label_width - 2;
+ }
+ else {
+ src_port_x = start_arrow + 2;
+ }
+#if GTK_MAJOR_VERSION < 2
+ gdk_draw_string(user_data->dlg.pixmap,
+ small_font,
+ user_data->dlg.div_line_gc,
+ src_port_x,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2+label_height/4-2,
+ label_string);
+#else
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.div_line_gc,
+ src_port_x,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
+ small_layout);
+#endif
+ }
+
+ /* draw the destination port number */
+ if ((end_arrow != left_x_border) && (end_arrow != (user_data->dlg.pixmap_width - right_x_border))){
+ g_snprintf(label_string, MAX_LABEL, "(%i)", user_data->dlg.items[current_item].port_dst);
+#if GTK_MAJOR_VERSION < 2
+ label_width=gdk_string_width(small_font, label_string);
+ label_height=gdk_string_height(small_font, label_string);
+#else
+ pango_layout_set_text(small_layout, label_string, -1);
+ pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
+#endif
+ if (start_arrow<end_arrow){
+ dst_port_x = end_arrow + 2;
+ }
+ else {
+ dst_port_x = end_arrow - label_width - 2;
+ }
+#if GTK_MAJOR_VERSION < 2
+ gdk_draw_string(user_data->dlg.pixmap,
+ small_font,
+ user_data->dlg.div_line_gc,
+ dst_port_x,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2+label_height/4-2,
+ label_string);
+#else
+ gdk_draw_layout(user_data->dlg.pixmap,
+ user_data->dlg.div_line_gc,
+ dst_port_x,
+ top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT-2-label_height/2-2,
+ small_layout);
+#endif
+ }
+
+ }
+ }
+
+#if GTK_MAJOR_VERSION >= 2
+ g_object_unref(G_OBJECT(layout));
+#endif
+
+ /* draw the border on the selected item */
+ if ( (user_data->dlg.selected_item != 0xFFFFFFFF) && ( (user_data->dlg.selected_item>=first_item) && (user_data->dlg.selected_item<=last_item) )){
+ gdk_draw_rectangle(user_data->dlg.pixmap, user_data->dlg.draw_area->style->black_gc,
+ FALSE,
+ left_x_border-1,
+ (user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER,
+ user_data->dlg.pixmap_width-COMMENT_WIDTH-left_x_border+1,
+ ITEM_HEIGHT);
+ }
+
+
+
+ gdk_draw_pixmap(user_data->dlg.draw_area->window,
+ user_data->dlg.draw_area->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area)],
+ user_data->dlg.pixmap,
+ 0, 0,
+ 0, 0,
+ user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);
+
+
+ /* update the h_scrollbar */
+ user_data->dlg.h_scrollbar_adjustment->upper=(gfloat) user_data->num_nodes-1;
+ user_data->dlg.h_scrollbar_adjustment->step_increment=1;
+ user_data->dlg.h_scrollbar_adjustment->page_increment=(gfloat) (last_node-first_node);
+ user_data->dlg.h_scrollbar_adjustment->page_size=(gfloat) (last_node-first_node);
+ user_data->dlg.h_scrollbar_adjustment->value=(gfloat) first_node;
+
+ gtk_adjustment_changed(user_data->dlg.h_scrollbar_adjustment);
+ gtk_adjustment_value_changed(user_data->dlg.h_scrollbar_adjustment);
+
+ /* update the v_scrollbar */
+ user_data->dlg.v_scrollbar_adjustment->upper=(gfloat) user_data->num_items-1;
+ user_data->dlg.v_scrollbar_adjustment->step_increment=1;
+ user_data->dlg.v_scrollbar_adjustment->page_increment=(gfloat) (last_item-first_item);
+ user_data->dlg.v_scrollbar_adjustment->page_size=(gfloat) (last_item-first_item);
+ user_data->dlg.v_scrollbar_adjustment->value=(gfloat) first_item;
+
+ gtk_adjustment_changed(user_data->dlg.v_scrollbar_adjustment);
+ gtk_adjustment_value_changed(user_data->dlg.v_scrollbar_adjustment);
+
+}
+
+/****************************************************************************/
+static void dialog_graph_redraw(graph_analysis_data_t* user_data)
+{
+ user_data->dlg.needs_redraw=TRUE;
+ dialog_graph_draw(user_data);
+}
+
+/****************************************************************************/
+static gint quit(GtkWidget *widget, GdkEventExpose *event _U_)
+{
+ graph_analysis_data_t *user_data;
+
+ user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+ user_data->dlg.window = NULL;
+
+ user_data = NULL;
+ return TRUE;
+}
+
+/****************************************************************************/
+static gint button_press_event(GtkWidget *widget, GdkEventButton *event _U_)
+{
+ graph_analysis_data_t *user_data;
+ guint32 item;
+
+ user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+ if (event->type != GDK_BUTTON_PRESS) return TRUE;
+
+ if (event->y<TOP_Y_BORDER) return TRUE;
+
+ /* get the item clicked */
+ item = ((guint32)event->y - TOP_Y_BORDER) / ITEM_HEIGHT;
+ user_data->dlg.selected_item = item + user_data->dlg.first_item;
+
+ user_data->dlg.needs_redraw=TRUE;
+ dialog_graph_draw(user_data);
+
+ goto_frame(&cfile, user_data->dlg.items[item].frame_num);
+
+ return TRUE;
+}
+
+/****************************************************************************/
+static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
+{
+ graph_analysis_data_t *user_data;
+
+ user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+ if(!user_data){
+ exit(10);
+ }
+
+
+ gdk_draw_pixmap(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ user_data->dlg.pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+
+ return FALSE;
+}
+
+static const GdkColor COLOR_GRAY = {0, 0x7fff, 0x7fff, 0x7fff};
+
+/****************************************************************************/
+static gint configure_event(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+ graph_analysis_data_t *user_data;
+ int i;
+ GdkColor color_div_line = COLOR_GRAY;
+
+ static GdkColor col[MAX_NUM_COL_CONV] = {
+ {0, 0x00FF, 0xFFFF, 0x00FF},
+ {0, 0xFFFF, 0xFFFF, 0x00FF},
+ {0, 0xFFFF, 0x00FF, 0x00FF},
+ {0, 0xFFFF, 0x00FF, 0xFFFF},
+ {0, 0x00FF, 0x00FF, 0xFFFF},
+ {0, 0x00FF, 0xFFFF, 0xFFFF},
+ {0, 0xFFFF, 0x80FF, 0x00FF},
+ {0, 0x80FF, 0x00FF, 0xFFFF},
+ {0, 0x00FF, 0x80FF, 0xFFFF},
+ {0, 0xFFFF, 0x00FF, 0x80FF}
+ };
+
+ user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+ if(!user_data){
+ exit(10);
+ }
+
+ if(user_data->dlg.pixmap){
+ gdk_pixmap_unref(user_data->dlg.pixmap);
+ user_data->dlg.pixmap=NULL;
+ }
+
+ user_data->dlg.pixmap=gdk_pixmap_new(widget->window,
+ widget->allocation.width,
+ widget->allocation.height,
+ -1);
+ user_data->dlg.pixmap_width=widget->allocation.width;
+ user_data->dlg.pixmap_height=widget->allocation.height;
+
+ gdk_draw_rectangle(user_data->dlg.pixmap,
+ widget->style->white_gc,
+ TRUE,
+ 0, 0,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ /* create gc for division lines and set the line stype to dash*/
+ user_data->dlg.div_line_gc=gdk_gc_new(user_data->dlg.pixmap);
+ gdk_gc_set_line_attributes(user_data->dlg.div_line_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
+#if GTK_MAJOR_VERSION < 2
+ colormap = gtk_widget_get_colormap (widget);
+ if (!gdk_color_alloc (colormap, &color_div_line)){
+ g_warning ("Couldn't allocate color");
+ }
+ gdk_gc_set_foreground(user_data->dlg.div_line_gc, &color_div_line);
+#else
+ gdk_gc_set_rgb_fg_color(user_data->dlg.div_line_gc, &color_div_line);
+#endif
+
+ /* create gcs for the background items */
+
+ for (i=0; i<MAX_NUM_COL_CONV; i++){
+ user_data->dlg.bg_gc[i]=gdk_gc_new(user_data->dlg.pixmap);
+#if GTK_MAJOR_VERSION < 2
+ colormap = gtk_widget_get_colormap (widget);
+ if (!gdk_color_alloc (colormap, &col[i])){
+ g_warning ("Couldn't allocate color");
+ }
+ gdk_gc_set_foreground(user_data->dlg.bg_gc[i], &col[i]);
+#else
+ gdk_gc_set_rgb_fg_color(user_data->dlg.bg_gc[i], &col[i]);
+#endif
+ }
+
+ dialog_graph_redraw(user_data);
+ return TRUE;
+}
+
+/****************************************************************************/
+static gint h_scrollbar_changed(GtkWidget *widget _U_, gpointer data)
+{
+ graph_analysis_data_t *user_data=(graph_analysis_data_t *)data;
+
+ if ((user_data->dlg.first_node+user_data->dlg.h_scrollbar_adjustment->page_size+1 == user_data->num_nodes)
+ && (user_data->dlg.h_scrollbar_adjustment->value >= user_data->dlg.first_node ))
+ return TRUE;
+
+ if (user_data->dlg.first_node == (guint16) user_data->dlg.h_scrollbar_adjustment->value)
+ return TRUE;
+
+ user_data->dlg.first_node = (guint16) user_data->dlg.h_scrollbar_adjustment->value;
+
+ dialog_graph_redraw(user_data);
+ return TRUE;
+}
+
+/****************************************************************************/
+static gint v_scrollbar_changed(GtkWidget *widget _U_, gpointer data)
+{
+ graph_analysis_data_t *user_data=(graph_analysis_data_t *)data;
+ if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)
+ && (user_data->dlg.v_scrollbar_adjustment->value >= user_data->dlg.first_item ))
+ return TRUE;
+
+ if (user_data->dlg.first_item == user_data->dlg.v_scrollbar_adjustment->value)
+ return TRUE;
+
+ user_data->dlg.first_item = (guint32) user_data->dlg.v_scrollbar_adjustment->value;
+
+ dialog_graph_redraw(user_data);
+ return TRUE;
+}
+
+/****************************************************************************/
+static void create_draw_area(graph_analysis_data_t* user_data, GtkWidget *box)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+
+ hbox=gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(hbox);
+
+ vbox=gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+
+
+ user_data->dlg.draw_area=gtk_drawing_area_new();
+ SIGNAL_CONNECT(user_data->dlg.draw_area, "destroy", quit, user_data);
+ OBJECT_SET_DATA(user_data->dlg.draw_area, "graph_analysis_data_t", user_data);
+
+ WIDGET_SET_SIZE(user_data->dlg.draw_area, user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);
+
+ /* signals needed to handle backing pixmap */
+ SIGNAL_CONNECT(user_data->dlg.draw_area, "expose_event", expose_event, NULL);
+ SIGNAL_CONNECT(user_data->dlg.draw_area, "configure_event", configure_event, user_data);
+
+ gtk_widget_add_events (user_data->dlg.draw_area,
+ GDK_BUTTON_PRESS_MASK);
+ SIGNAL_CONNECT(user_data->dlg.draw_area, "button_press_event", button_press_event, user_data);
+
+ gtk_widget_show(user_data->dlg.draw_area);
+ gtk_box_pack_start(GTK_BOX(vbox), user_data->dlg.draw_area, TRUE, TRUE, 0);
+
+ /* create the associated h_scrollbar */
+ user_data->dlg.h_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
+ user_data->dlg.h_scrollbar=gtk_hscrollbar_new(user_data->dlg.h_scrollbar_adjustment);
+ gtk_widget_show(user_data->dlg.h_scrollbar);
+ gtk_box_pack_end(GTK_BOX(vbox), user_data->dlg.h_scrollbar, FALSE, FALSE, 0);
+ SIGNAL_CONNECT(user_data->dlg.h_scrollbar_adjustment, "value_changed", h_scrollbar_changed, user_data);
+
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+
+ /* create the associated v_scrollbar */
+ user_data->dlg.v_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
+ user_data->dlg.v_scrollbar=gtk_vscrollbar_new(user_data->dlg.v_scrollbar_adjustment);
+ gtk_widget_show(user_data->dlg.v_scrollbar);
+ gtk_box_pack_end(GTK_BOX(hbox), user_data->dlg.v_scrollbar, FALSE, FALSE, 0);
+ SIGNAL_CONNECT(user_data->dlg.v_scrollbar_adjustment, "value_changed", v_scrollbar_changed, user_data);
+
+ gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0);
+}
+
+
+/****************************************************************************/
+static void dialog_graph_create_window(graph_analysis_data_t* user_data)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *bt_close;
+ GtkWidget *label = NULL;
+
+ /* create the main window */
+ user_data->dlg.window=window_new(GTK_WINDOW_TOPLEVEL, "Graph Analysis");
+
+
+ vbox=gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(user_data->dlg.window), vbox);
+ gtk_widget_show(vbox);
+
+ create_draw_area(user_data, vbox);
+
+ hbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show(hbox);
+
+ bt_close = OBJECT_GET_DATA(hbox, GTK_STOCK_CLOSE);
+ window_set_cancel_button(user_data->dlg.window, bt_close, window_cancel_button_cb);
+
+ SIGNAL_CONNECT(user_data->dlg.window, "delete_event", window_delete_event_cb, NULL);
+
+ gtk_widget_show(user_data->dlg.window);
+ window_present(user_data->dlg.window);
+}
+
+/* Return the index array if the node is in the array. Return -1 if there is room in the array
+ * and Return -2 if the array is full
+ */
+/****************************************************************************/
+gint is_node_array(graph_analysis_data_t* user_data, guint32 node)
+{
+ int i;
+ for (i=0; i<MAX_NUM_NODES; i++){
+ if (user_data->nodes[i] == 0) return -1; /* it is not in the array */
+ if (user_data->nodes[i] == node) return i; /* it is in the array */
+ }
+ return -2; /* array full */
+}
+
+
+/* Get the nodes (IPs) from the list */
+/****************************************************************************/
+void get_nodes(graph_analysis_data_t* user_data)
+{
+ GList* list;
+ graph_analysis_item_t *gai;
+ gint index;
+
+ /* fill the node array */
+ list = g_list_first(user_data->graph_info->list);
+ while (list)
+ {
+ gai = list->data;
+ if (gai->display){
+ user_data->num_items++;
+ /* check source IP node */
+ index = is_node_array(user_data, gai->ip_src);
+ switch(index){
+ case -2: /* array full */
+ gai->src_node = NODE_OVERFLOW;
+ break;
+ case -1: /* not in array */
+ user_data->nodes[user_data->num_nodes] = gai->ip_src;
+ gai->src_node = user_data->num_nodes;
+ user_data->num_nodes++;
+ break;
+ default: /* it is in the array, just update the src_node */
+ gai->src_node = (guint16)index;
+ }
+
+ /* check destination IP node */
+ index = is_node_array(user_data, gai->ip_dst);
+ switch(index){
+ case -2: /* array full */
+ gai->dst_node = NODE_OVERFLOW;
+ break;
+ case -1: /* not in array */
+ user_data->nodes[user_data->num_nodes] = gai->ip_dst;
+ gai->dst_node = user_data->num_nodes;
+ user_data->num_nodes++;
+ break;
+ default: /* it is in the array, just update the dst_node */
+ gai->dst_node = (guint16)index;
+ }
+ }
+
+ list = g_list_next(list);
+ }
+}
+
+/****************************************************************************/
+/* XXX only handles IPv4, should add IPv6 support */
+graph_analysis_data_t* graph_analysis_init()
+{
+ graph_analysis_data_t* user_data;
+ /* init */
+ user_data = g_malloc(sizeof(graph_analysis_data_t));
+
+ /* init user_data */
+ graph_analysis_init_dlg(user_data);
+
+ return user_data;
+}
+
+/****************************************************************************/
+void graph_analysis_create(graph_analysis_data_t* user_data)
+{
+ /* reset the data */
+ graph_analysis_reset(user_data);
+
+ /* get nodes (each node is an IP address) */
+ get_nodes(user_data);
+
+ /* create the graph windows */
+ dialog_graph_create_window(user_data);
+
+ /* redraw the graph */
+ dialog_graph_redraw(user_data);
+
+ return;
+}
+
+/****************************************************************************/
+void graph_analysis_update(graph_analysis_data_t* user_data)
+{
+ /* reset the data */
+ graph_analysis_reset(user_data);
+
+ /* get nodes (each node is an IP address) */
+ get_nodes(user_data);
+
+ /* redraw the graph */
+ dialog_graph_redraw(user_data);
+
+ window_present(user_data->dlg.window);
+ return;
+}
diff --git a/gtk/graph_analysis.h b/gtk/graph_analysis.h
new file mode 100644
index 0000000000..2fc3f8d3d6
--- /dev/null
+++ b/gtk/graph_analysis.h
@@ -0,0 +1,121 @@
+/* graph_analysis.h
+ * Graphic Analysis addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Verso Technologies Inc.
+ * By Alejandro Vaquero <alejandrovaquero@yahoo.com>
+ *
+ * based on rtp_analysis.c and io_stat
+ *
+ *
+ * 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.
+ */
+
+#ifndef GRAPH_ANALYSIS_H_INCLUDED
+#define GRAPH_ANALYSIS_H_INCLUDED
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include "gtkglobals.h"
+
+#define MAX_NUM_NODES 10
+
+/* defines an entry in for the graph analysis */
+typedef struct _graph_analysis_item {
+ guint32 frame_num; /* frame number used to "go to" that frame */
+ double time; /* frame time */
+ guint32 ip_src; /* XXX we currently support only IP v4 */
+ guint16 port_src;
+ guint32 ip_dst;
+ guint16 port_dst;
+ gchar *frame_label; /* the label on top of the arrow */
+ gchar *comment; /* a comment that appears at the left of the graph */
+ guint16 conv_num; /* the conversation number, each conversation will be colored */
+ gboolean display; /* indicate if the packet is displayed or not in the graph */
+ guint16 src_node; /* this is used by graph_analysis.c to identify the node */
+ guint16 dst_node; /* a node is an IP address that will be displayed in columns */
+ guint16 line_style; /* the arrow line width in pixels*/
+} graph_analysis_item_t;
+
+/* defines the graph analysis structure */
+typedef struct _graph_analysis_info {
+ int nconv; /* number of conversations in the list */
+ GList* list; /* list with the graph analysis items */
+} graph_analysis_info_t;
+
+/* max number of nodes to display, each node will be an IP address */
+#define MAX_NUM_COL_CONV 10
+#define NODE_OVERFLOW MAX_NUM_NODES+1
+#define NUM_DISPLAY_ITEMS 1000
+
+typedef struct _display_items {
+ guint32 frame_num; /* frame number used to "go to" that frame */
+ double time; /* frame time */
+ guint16 port_src;
+ guint16 port_dst;
+ gchar *frame_label; /* the label on top of the arrow */
+ gchar *comment; /* a comment that appears at the left of the graph */
+ guint16 conv_num; /* the conversation number, each conversation will be colored */
+ guint16 src_node; /* this is used by graph_analysis.c to identify the node */
+ guint16 dst_node; /* a node is an IP address that will be displayed in columns */
+ guint16 line_style; /* the arrow line width in pixels*/
+} display_items_t;
+
+typedef struct _dialog_data_t {
+ GtkWidget *window;
+ gboolean needs_redraw;
+ gint selected_row;
+ GtkWidget *draw_area;
+ GdkPixmap *pixmap;
+ GtkAdjustment *h_scrollbar_adjustment;
+ GtkWidget *h_scrollbar;
+ GtkWidget *v_scrollbar;
+ GtkAdjustment *v_scrollbar_adjustment;
+ GdkGC *div_line_gc;
+ GdkGC *bg_gc[MAX_NUM_COL_CONV];
+ int pixmap_width;
+ int pixmap_height;
+ guint16 first_node; /* the first node on the left to show in the screen */
+ guint32 first_item; /* the first item (row) to show from the top */
+ guint32 selected_item; /* the selected item */
+ display_items_t items[NUM_DISPLAY_ITEMS];
+ guint32 left_x_border;
+} dialog_data_t;
+
+
+
+/* structure that holds general information and the dialog */
+typedef struct _graph_analysis_data_t {
+ /* graphic data */
+ graph_analysis_info_t *graph_info;
+
+ /* dialog associated data */
+ dialog_data_t dlg;
+ guint32 nodes[MAX_NUM_NODES];
+ guint32 num_nodes;
+ guint32 num_items;
+} graph_analysis_data_t;
+
+graph_analysis_data_t* graph_analysis_init();
+void graph_analysis_create(graph_analysis_data_t* user_data);
+void graph_analysis_update(graph_analysis_data_t* user_data);
+
+
+#endif /*GRAPH_ANALYSIS_H_INCLUDED*/
diff --git a/gtk/rtp_stream.c b/gtk/rtp_stream.c
index f5caf80e74..7d58c16d97 100644
--- a/gtk/rtp_stream.c
+++ b/gtk/rtp_stream.c
@@ -211,6 +211,8 @@ static int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _
GList* list;
rtp_sample_t sample;
+ struct _rtp_conversation_info *p_conv_data = NULL;
+
/* gather infos on the stream this packet is part of */
COPY_ADDRESS(&(tmp_strinfo.src_addr), &(pinfo->src));
tmp_strinfo.src_port = pinfo->srcport;
@@ -238,9 +240,20 @@ static int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _
tmp_strinfo.first_frame_num = pinfo->fd->num;
tmp_strinfo.start_sec = pinfo->fd->abs_secs;
tmp_strinfo.start_usec = pinfo->fd->abs_usecs;
+ tmp_strinfo.start_rel_sec = pinfo->fd->rel_secs;
+ tmp_strinfo.start_rel_usec = pinfo->fd->rel_usecs;
tmp_strinfo.tag_vlan_error = 0;
tmp_strinfo.tag_diffserv_error = 0;
tmp_strinfo.vlan_id = 0;
+
+ /* Get the Setup frame number who set this RTP stream */
+
+ p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
+ if (p_conv_data)
+ tmp_strinfo.setup_frame_number = p_conv_data->frame_number;
+ else
+ tmp_strinfo.setup_frame_number = 0xFFFFFFFF;
+
strinfo = g_malloc(sizeof(rtp_stream_info_t));
*strinfo = tmp_strinfo; /* memberwise copy of struct */
tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
@@ -248,6 +261,8 @@ static int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _
/* increment the packets counter for this stream */
++(strinfo->npackets);
+ strinfo->stop_rel_sec = pinfo->fd->rel_secs;
+ strinfo->stop_rel_usec = pinfo->fd->rel_usecs;
/* increment the packets counter of all streams */
++(tapinfo->npackets);
diff --git a/gtk/rtp_stream.h b/gtk/rtp_stream.h
index e34e9f1215..78c904435b 100644
--- a/gtk/rtp_stream.h
+++ b/gtk/rtp_stream.h
@@ -65,10 +65,15 @@ typedef struct _rtp_stream_info {
guint32 npackets;
guint32 first_frame_num; /* frame number of first frame */
+ guint32 setup_frame_number; /* frame number of setup message */
/* start of recording (GMT) of this stream */
guint32 start_sec; /* seconds */
guint32 start_usec; /* microseconds */
gboolean tag_vlan_error;
+ guint32 start_rel_sec; /* start stream rel seconds */
+ guint32 start_rel_usec; /* start stream rel microseconds */
+ guint32 stop_rel_sec; /* stop stream rel seconds */
+ guint32 stop_rel_usec; /* stop stream rel microseconds */
gboolean tag_diffserv_error;
guint16 vlan_id;
diff --git a/gtk/voip_calls.c b/gtk/voip_calls.c
new file mode 100644
index 0000000000..b1cb4d40af
--- /dev/null
+++ b/gtk/voip_calls.c
@@ -0,0 +1,1312 @@
+/* voip_calls.c
+ * VoIP calls summary addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Ericsson, Spain
+ * By Francisco Alcoba <francisco.alcoba@ericsson.com>
+ *
+ * based on h323_calls.c
+ * Copyright 2004, Iskratel, Ltd, Kranj
+ * By Miha Jemec <m.jemec@iskratel.si>
+ *
+ * H323, RTP and Graph Support
+ * By Alejandro Vaquero, alejandro.vaquero@verso.com
+ * Copyright 2005, Verso Technologies Inc.
+ *
+ * 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 "graph_analysis.h"
+#include "voip_calls.h"
+#include "voip_calls_dlg.h"
+#include "rtp_stream.h"
+
+#include "globals.h"
+
+#include <epan/tap.h>
+#include <epan/dissectors/packet-sip.h>
+#include <epan/dissectors/packet-mtp3.h>
+#include <epan/dissectors/packet-isup.h>
+#include <epan/dissectors/packet-h225.h>
+#include <epan/dissectors/packet-h245.h>
+#include <epan/dissectors/packet-q931.h>
+#include <epan/dissectors/packet-sdp.h>
+#include <epan/dissectors/packet-rtp.h>
+#include "rtp_pt.h"
+
+#include "alert_box.h"
+#include "simple_dialog.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <string.h>
+
+
+char *voip_call_state_name[6]={
+ "CALL SETUP",
+ "IN CALL",
+ "CANCELLED",
+ "COMPLETED",
+ "REJECTED",
+ "UNKNOWN"
+ };
+
+/* defines whether we can consider the call active */
+char *voip_protocol_name[3]={
+ "SIP",
+ "ISUP",
+ "H323"
+ };
+
+
+
+/****************************************************************************/
+/* the one and only global voip_calls_tapinfo_t structure */
+static voip_calls_tapinfo_t the_tapinfo_struct =
+ {0, NULL, 0, NULL, 0, 0, 0, 0, NULL};
+
+/* static voip_calls_tapinfo_t the_tapinfo_struct;
+*/
+
+/****************************************************************************/
+/* when there is a [re]reading of packet's */
+void voip_calls_reset(voip_calls_tapinfo_t *tapinfo)
+{
+ voip_calls_info_t *strinfo;
+ sip_calls_info_t *tmp_sipinfo;
+ h323_calls_info_t *tmp_h323info;
+
+ graph_analysis_item_t *graph_item;
+
+ GList* list;
+ GList* list2;
+
+ /* free the data items first */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ strinfo = list->data;
+ g_free(strinfo->from_identity);
+ g_free(strinfo->to_identity);
+ if (strinfo->protocol == VOIP_SIP){
+ tmp_sipinfo = strinfo->prot_info;
+ g_free(tmp_sipinfo->call_identifier);
+ }
+ if (strinfo->protocol == VOIP_H323){
+ tmp_h323info = strinfo->prot_info;
+ g_free(tmp_h323info->guid);
+ /* free the H245 list address */
+ list2 = g_list_first(tmp_h323info->h245_list);
+ while (list2)
+ {
+ g_free(list2->data);
+ list2 = g_list_next(list2);
+ }
+ g_list_free(tmp_h323info->h245_list);
+ tmp_h323info->h245_list = NULL;
+ }
+ g_free(strinfo->prot_info);
+
+ g_free(list->data);
+ list = g_list_next(list);
+ }
+ g_list_free(tapinfo->strinfo_list);
+ tapinfo->strinfo_list = NULL;
+ tapinfo->ncalls = 0;
+ tapinfo->npackets = 0;
+ tapinfo->start_packets = 0;
+ tapinfo->completed_calls = 0;
+ tapinfo->rejected_calls = 0;
+
+ /* free the graph data items first */
+ list = g_list_first(tapinfo->graph_analysis->list);
+ while (list)
+ {
+ graph_item = list->data;
+ g_free(graph_item->frame_label);
+ g_free(graph_item->comment);
+ g_free(list->data);
+ list = g_list_next(list);
+ }
+ g_list_free(tapinfo->graph_analysis->list);
+ tapinfo->graph_analysis->nconv = 0;
+ tapinfo->graph_analysis->list = NULL;
+
+ ++(tapinfo->launch_count);
+
+ return;
+}
+
+/****************************************************************************/
+void graph_analysis_data_init(){
+ the_tapinfo_struct.graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
+ the_tapinfo_struct.graph_analysis->nconv = 0;
+ the_tapinfo_struct.graph_analysis->list = NULL;
+
+}
+
+/****************************************************************************/
+/* Add the RTP streams into the graph data */
+void add_rtp_streams_graph()
+{
+ rtp_stream_info_t *strinfo;
+ GList *strinfo_list;
+ guint nfound;
+ guint item;
+ GList* voip_calls_graph_list;
+ graph_analysis_item_t *gai;
+ graph_analysis_item_t *new_gai;
+ guint16 conv_num;
+ guint32 duration;
+
+ /* Scan for rtpstream */
+ rtpstream_scan();
+
+ /* assigne the RTP streams to calls */
+ nfound = 0;
+ strinfo_list = g_list_first(rtpstream_get_info()->strinfo_list);
+ while (strinfo_list)
+ {
+ strinfo = (rtp_stream_info_t*)(strinfo_list->data);
+
+ /* look in the voip calls graph list if there is a match for this RTP stream */
+ voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
+ item = 0;
+ while (voip_calls_graph_list)
+ {
+ gai = voip_calls_graph_list->data;
+ conv_num = gai->conv_num;
+ if (strinfo->setup_frame_number == gai->frame_num){
+ while(voip_calls_graph_list){
+ gai = voip_calls_graph_list->data;
+ /* add the RTP item to the graph */
+ if (strinfo->first_frame_num<gai->frame_num){
+ new_gai = g_malloc(sizeof(graph_analysis_item_t));
+ new_gai->frame_num = strinfo->first_frame_num;
+ new_gai->time = (double)strinfo->start_rel_sec + (double)strinfo->start_rel_usec/1000000;
+ g_memmove(&new_gai->ip_src, strinfo->src_addr.data, 4);
+ g_memmove(&new_gai->ip_dst, strinfo->dest_addr.data, 4);
+ new_gai->port_src = strinfo->src_port;
+ new_gai->port_dst = strinfo->dest_port;
+ duration = (strinfo->stop_rel_sec*1000000 + strinfo->stop_rel_usec) - (strinfo->start_rel_sec*1000000 + strinfo->start_rel_usec);
+ new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(strinfo->pt, rtp_payload_type_short_vals, "%u"));
+ new_gai->comment = g_strdup_printf("RTP Num packets:%d Duration:%d.%03ds ssrc:%d", strinfo->npackets, duration/1000000,(duration%1000000)/1000, strinfo->ssrc);
+ new_gai->conv_num = conv_num;
+ new_gai->display=FALSE;
+ new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
+ the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item);
+
+ break;
+ }
+ voip_calls_graph_list = g_list_next(voip_calls_graph_list);
+ item++;
+ }
+ break;
+ }
+ voip_calls_graph_list = g_list_next(voip_calls_graph_list);
+ item++;
+ }
+ strinfo_list = g_list_next(strinfo_list);
+ }
+}
+
+/****************************************************************************/
+/* Add a new item into the graph */
+int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, gchar *frame_label, gchar *comment, guint16 call_num)
+{
+ graph_analysis_item_t *gai;
+
+ gai = g_malloc(sizeof(graph_analysis_item_t));
+ gai->frame_num = pinfo->fd->num;
+ gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
+ g_memmove(&gai->ip_src, pinfo->src.data, 4);
+ g_memmove(&gai->ip_dst, pinfo->dst.data, 4);
+ gai->port_src=pinfo->srcport;
+ gai->port_dst=pinfo->destport;
+ if (frame_label != NULL)
+ gai->frame_label = g_strdup(frame_label);
+ else
+ gai->frame_label = g_strdup("");
+
+ if (comment != NULL)
+ gai->comment = g_strdup(comment);
+ else
+ gai->comment = g_strdup("");
+ gai->conv_num=call_num;
+ gai->line_style=1;
+ gai->display=FALSE;
+
+ tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, gai);
+
+ return 1;
+
+}
+
+/****************************************************************************/
+/* Append str to frame_label and comment in a graph item */
+/* return 0 if the frame_num is not in the graph list */
+int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, gchar *new_frame_label, gchar *new_comment)
+{
+ graph_analysis_item_t *gai;
+ GList* list;
+ gchar *tmp_str = NULL;
+ gchar *tmp_str2 = NULL;
+
+ list = g_list_first(tapinfo->graph_analysis->list);
+ while (list)
+ {
+ gai = list->data;
+ if (gai->frame_num == frame_num){
+ tmp_str = gai->frame_label;
+ tmp_str2 = gai->comment;
+
+ if (new_frame_label != NULL){
+ gai->frame_label = g_strdup_printf("%s %s", gai->frame_label, new_frame_label);
+ g_free(tmp_str);
+ }
+
+
+ if (new_comment != NULL){
+ gai->comment = g_strdup_printf("%s %s", gai->comment, new_comment);
+ g_free(tmp_str2);
+ }
+ break;
+ }
+ list = g_list_next (list);
+ }
+ if (tmp_str == NULL) return 0; /* it is not in the list */
+ return 1;
+
+}
+
+/****************************************************************************/
+/* ***************************TAP for SIP **********************************/
+/****************************************************************************/
+
+/****************************************************************************/
+/* whenever a SIP packet is seen by the tap listener */
+int SIPcalls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *SIPinfo)
+{
+
+ /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
+ be compared with existing calls */
+
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ sip_calls_info_t *tmp_sipinfo;
+ GList* list;
+ guint32 tmp_src, tmp_dst;
+ gchar *frame_label = NULL;
+ gchar *comment = NULL;
+
+ sip_info_value_t *pi = SIPinfo;
+
+ /* do not consider packets without call_id */
+ if (pi->tap_call_id ==NULL){
+ return 0;
+ }
+
+ /* check wether we already have a call with these parameters in the list */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_SIP){
+ tmp_sipinfo = tmp_listinfo->prot_info;
+ if (strcmp(tmp_sipinfo->call_identifier,pi->tap_call_id)==0){
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ /* not in the list? then create a new entry if the message is INVITE -i.e. if this session is a call*/
+ if ((strinfo==NULL) &&(pi->request_method!=NULL)){
+ if (strcmp(pi->request_method,"INVITE")==0){
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_CALL_SETUP;
+ strinfo->from_identity=g_strdup(pi->tap_from_addr);
+ strinfo->to_identity=g_strdup(pi->tap_to_addr);
+ g_memmove(&(strinfo->initial_speaker), pinfo->src.data, 4);
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->selected=FALSE;
+ strinfo->start_sec=pinfo->fd->rel_secs;
+ strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->protocol=VOIP_SIP;
+ strinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
+ tmp_sipinfo=strinfo->prot_info;
+ tmp_sipinfo->call_identifier=strdup(pi->tap_call_id);
+ tmp_sipinfo->sip_state=SIP_INVITE_SENT;
+ tmp_sipinfo->invite_cseq=pi->tap_cseq_number;
+ strinfo->npackets = 0;
+ strinfo->call_num = tapinfo->ncalls++;
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
+ }
+
+ g_free(pi->tap_from_addr);
+ g_free(pi->tap_to_addr);
+ g_free(pi->tap_call_id);
+
+ if (strinfo!=NULL){
+
+ /* let's analyze the call state */
+
+ g_memmove(&(tmp_src), pinfo->src.data, 4);
+ g_memmove(&(tmp_dst), pinfo->dst.data, 4);
+
+ if (pi->request_method == NULL){
+ frame_label = g_strdup_printf("%d %s", pi->response_code, pi->reason_phrase );
+ comment = g_strdup_printf("SIP Status");
+
+ if ((pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(tmp_dst==strinfo->initial_speaker)){
+ if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
+ tmp_sipinfo->sip_state = SIP_200_REC;
+ }
+ else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
+ strinfo->call_state = VOIP_REJECTED;
+ tapinfo->rejected_calls++;
+ }
+ }
+
+ }
+ else{
+ frame_label = g_strdup(pi->request_method);
+
+ if ((strcmp(pi->request_method,"INVITE")==0)&&(tmp_src == strinfo->initial_speaker)){
+ tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
+ comment = g_strdup_printf("SIP From: %s To:%s", strinfo->from_identity, strinfo->to_identity);
+ }
+ else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
+ &&(tmp_src == strinfo->initial_speaker)&&(tmp_sipinfo->sip_state==SIP_200_REC)){
+ strinfo->call_state = VOIP_IN_CALL;
+ comment = g_strdup_printf("SIP Request");
+ }
+ else if (strcmp(pi->request_method,"BYE")==0){
+ strinfo->call_state = VOIP_COMPLETED;
+ tapinfo->completed_calls++;
+ comment = g_strdup_printf("SIP Request");
+ }
+ else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
+ &&(tmp_src == strinfo->initial_speaker)&&(strinfo->call_state==VOIP_CALL_SETUP)){
+ strinfo->call_state = VOIP_CANCELLED;
+ tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
+ comment = g_strdup_printf("SIP Request");
+ } else {
+ comment = g_strdup_printf("SIP Request");
+ }
+ }
+
+ strinfo->stop_sec=pinfo->fd->rel_secs;
+ strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+
+ /* add to the graph */
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ g_free(comment);
+ g_free(frame_label);
+ }
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+const voip_calls_tapinfo_t* voip_calls_get_info(void)
+{
+ return &the_tapinfo_struct;
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_SIP_tap_listener=FALSE;
+/****************************************************************************/
+void
+sip_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_SIP_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ error_string = register_tap_listener("sip", &the_tapinfo_struct, NULL,
+ NULL, (void*)SIPcalls_packet, NULL);
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_SIP_tap_listener=TRUE;
+ }
+}
+
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_sip_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_SIP_tap_listener=FALSE;
+}
+
+/****************************************************************************/
+/* ***************************TAP for ISUP **********************************/
+/****************************************************************************/
+
+static gchar isup_called_number[255], isup_calling_number[255];
+static guint16 isup_cic;
+static guint8 isup_message_type;
+
+/****************************************************************************/
+/* whenever a isup_ packet is seen by the tap listener */
+int isup_calls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *isup_info _U_)
+{
+
+ isup_tap_rec_t *pi = isup_info;
+
+ if (pi->calling_number!=NULL){
+ strcpy(isup_calling_number, pi->calling_number);
+ }
+ if (pi->called_number!=NULL){
+ strcpy(isup_called_number, pi->called_number);
+ }
+ isup_message_type = pi->message_type;
+ isup_cic = pinfo->circuit_id;
+
+ return 0;
+}
+
+/****************************************************************************/
+
+static gboolean have_isup_tap_listener=FALSE;
+
+void
+isup_calls_init_tap(void)
+{
+ GString *error_string;
+
+
+ if(have_isup_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("isup", &the_tapinfo_struct,
+ NULL,
+ NULL, (void*)isup_calls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_isup_tap_listener=TRUE;
+ }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_isup_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_isup_tap_listener=FALSE;
+}
+
+
+/****************************************************************************/
+/* ***************************TAP for MTP3 **********************************/
+/****************************************************************************/
+
+
+/****************************************************************************/
+/* whenever a mtp3_ packet is seen by the tap listener */
+int mtp3_calls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *mtp3_info _U_)
+{
+
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ isup_calls_info_t *tmp_isupinfo;
+ gboolean found = FALSE;
+ gboolean forward;
+ gboolean right_pair = TRUE;
+ GList* list;
+
+ mtp3_tap_rec_t *pi = mtp3_info;
+
+ /* check wether we already have a call with these parameters in the list */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
+ tmp_isupinfo = tmp_listinfo->prot_info;
+ if ((tmp_isupinfo->cic == isup_cic)&&(tmp_isupinfo->ni == pi->addr_opc.ni)){
+ if ((tmp_isupinfo->opc == pi->addr_opc.pc)&&(tmp_isupinfo->dpc == pi->addr_dpc.pc)){
+ forward = TRUE;
+ }
+ else if ((tmp_isupinfo->dpc == pi->addr_opc.pc)&&(tmp_isupinfo->opc == pi->addr_dpc.pc)){
+ forward = FALSE;
+ }
+ else{
+ right_pair = FALSE;
+ }
+ if (right_pair){
+ /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
+ cic is no longer active */
+ if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
+ found = TRUE;
+ }
+ else if (isup_message_type != 1){
+ found = TRUE;
+ }
+ else{
+ tmp_listinfo->call_active_state=VOIP_INACTIVE;
+ }
+ }
+ if (found){
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ /* not in the list? then create a new entry if the message is IAM
+ -i.e. if this session is a call*/
+
+
+ if ((strinfo==NULL) &&(isup_message_type==1)){
+
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_UNKNOWN;
+ g_memmove(&(strinfo->initial_speaker), pinfo->src.data, 4);
+ strinfo->selected=FALSE;
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->start_sec=pinfo->fd->rel_secs;
+ strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->protocol=VOIP_ISUP;
+ strinfo->from_identity=g_strdup(isup_calling_number);
+ strinfo->to_identity=g_strdup(isup_called_number);
+ strinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
+ tmp_isupinfo=strinfo->prot_info;
+ tmp_isupinfo->opc = pi->addr_opc.pc;
+ tmp_isupinfo->dpc = pi->addr_dpc.pc;
+ tmp_isupinfo->ni = pi->addr_opc.ni;
+ tmp_isupinfo->cic = pinfo->circuit_id;
+ strinfo->npackets = 0;
+ strinfo->call_num = tapinfo->ncalls++;
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
+
+ if (strinfo!=NULL){
+ strinfo->stop_sec=pinfo->fd->rel_secs;
+ strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+
+ /* Let's analyze the call state */
+
+ switch(isup_message_type){
+ case 1: /* IAM */
+ strinfo->call_state=VOIP_CALL_SETUP;
+ break;
+ case 7: /* CONNECT */
+ case 9: /* ANSWER */
+ strinfo->call_state=VOIP_IN_CALL;
+ break;
+ case 12: /* RELEASE */
+ if (strinfo->call_state==VOIP_CALL_SETUP){
+ if (forward){
+ strinfo->call_state=VOIP_CANCELLED;
+ }
+ else{
+ strinfo->call_state=VOIP_REJECTED;
+ tapinfo->rejected_calls++;
+ }
+ }
+ else if (strinfo->call_state == VOIP_IN_CALL){
+ strinfo->call_state = VOIP_COMPLETED;
+ tapinfo->completed_calls++;
+ }
+ break;
+ }
+
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+ }
+
+
+ return 1;
+}
+
+/****************************************************************************/
+
+static gboolean have_mtp3_tap_listener=FALSE;
+
+void
+mtp3_calls_init_tap(void)
+{
+ GString *error_string;
+
+
+ if(have_mtp3_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("mtp3", &the_tapinfo_struct,
+ NULL,
+ NULL, (void*)mtp3_calls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_mtp3_tap_listener=TRUE;
+ }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_mtp3_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_mtp3_tap_listener=FALSE;
+}
+
+/****************************************************************************/
+/* ***************************TAP for Q931 **********************************/
+/****************************************************************************/
+
+static gchar *q931_calling_number;
+static gchar *q931_called_number;
+static guint8 q931_cause_value;
+static gint32 q931_crv;
+static guint8 q931_message_type;
+static guint32 q931_frame_num;
+
+/****************************************************************************/
+/* whenever a q931_ packet is seen by the tap listener */
+int q931_calls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *q931_info _U_)
+{
+
+ q931_packet_info *pi = q931_info;
+
+ /* free previously allocated q931_calling/ed_number */
+ g_free(q931_calling_number);
+ g_free(q931_called_number);
+
+ if (pi->calling_number!=NULL)
+ q931_calling_number = g_strdup(pi->calling_number);
+ else
+ q931_calling_number = g_strdup("");
+
+ if (pi->called_number!=NULL)
+ q931_called_number = g_strdup(pi->called_number);
+ else
+ q931_called_number = g_strdup("");
+ q931_cause_value = pi->cause_value;
+ q931_frame_num = pinfo->fd->num;
+ q931_crv = pi->crv;
+
+ return 0;
+}
+
+/****************************************************************************/
+static gboolean have_q931_tap_listener=FALSE;
+
+void
+q931_calls_init_tap(void)
+{
+ GString *error_string;
+
+
+ if(have_q931_tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("q931", &the_tapinfo_struct,
+ NULL,
+ NULL, (void*)q931_calls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_q931_tap_listener=TRUE;
+ }
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_q931_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_q931_tap_listener=FALSE;
+}
+
+/****************************************************************************/
+/****************************TAP for H323 ***********************************/
+/****************************************************************************/
+
+#define GUID_LEN 16
+static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+/* defines specific H323 data */
+
+void add_h245_Address(h323_calls_info_t *h323info, guint32 h245_address, guint16 h245_port)
+{
+ h245_address_t *h245_add = NULL;
+
+ h245_add = g_malloc(sizeof(h245_address_t));
+ h245_add->h245_address = h245_address;
+ h245_add->h245_port = h245_port;
+
+ h323info->h245_list = g_list_append(h323info->h245_list, h245_add);
+}
+
+/****************************************************************************/
+/* whenever a H225 packet is seen by the tap listener */
+int H225calls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *H225info)
+{
+
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ h323_calls_info_t *tmp_h323info;
+ gchar *frame_label;
+ gchar *comment;
+ GList* list;
+ guint32 tmp_src, tmp_dst;
+
+ h225_packet_info *pi = H225info;
+
+ /* we ignore packets that are not displayed */
+ if (pinfo->fd->flags.passed_dfilter == 0)
+ return 0;
+
+ /* if not guid and RAS return because did not belong to a call */
+ if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (pi->msg_type == H225_RAS))
+ return 0;
+
+
+ if ( (memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (q931_frame_num == pinfo->fd->num) ){
+ /* check wether we already have a call with this Q931 CRV */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_H323){
+ tmp_h323info = tmp_listinfo->prot_info;
+ if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+ if (strinfo==NULL) return 0;
+ } else {
+ /* check wether we already have a call with this guid in the list */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_H323){
+ tmp_h323info = tmp_listinfo->prot_info;
+ if (memcmp(tmp_h323info->guid, pi->guid,GUID_LEN)==0){
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+ }
+
+ /* not in the list? then create a new entry */
+ if ((strinfo==NULL)){
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_UNKNOWN;
+ strinfo->from_identity=g_strdup("");
+ strinfo->to_identity=g_strdup("");
+
+ g_memmove(&(strinfo->initial_speaker), pinfo->src.data,4);
+ strinfo->selected=FALSE;
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->start_sec=pinfo->fd->rel_secs;
+ strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->protocol=VOIP_H323;
+ strinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
+ tmp_h323info = strinfo->prot_info;
+ tmp_h323info->guid = (guint8 *) g_memdup(pi->guid,GUID_LEN);
+ tmp_h323info->h225SetupAddr = 0;
+ tmp_h323info->h245_list = NULL;
+ tmp_h323info->is_faststart_Setup = FALSE;
+ tmp_h323info->is_faststart_Proc = FALSE;
+ tmp_h323info->is_h245Tunneling = FALSE;
+ tmp_h323info->is_h245 = FALSE;
+ tmp_h323info->q931_crv = -1;
+ tmp_h323info->q931_crv2 = -1;
+ strinfo->call_num = tapinfo->ncalls++;
+ strinfo->npackets = 0;
+
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
+
+ if (strinfo!=NULL){
+
+ /* let's analyze the call state */
+
+ g_memmove(&(tmp_src), pinfo->src.data, 4);
+ g_memmove(&(tmp_dst), pinfo->dst.data, 4);
+
+ strinfo->stop_sec=pinfo->fd->rel_secs;
+ strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+
+ /* change the status */
+ if (pi->msg_type == H225_CS){
+ if (tmp_h323info->q931_crv == -1) {
+ tmp_h323info->q931_crv = q931_crv;
+ } else if (tmp_h323info->q931_crv != q931_crv) {
+ tmp_h323info->q931_crv2 = q931_crv;
+ }
+
+ if (pi->is_h245 == TRUE){
+ add_h245_Address(tmp_h323info, pi->h245_address, pi->h245_port);
+ }
+
+ if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
+
+ frame_label = g_strdup(pi->frame_label);
+
+ switch(pi->cs_type){
+ case H225_SETUP:
+ tmp_h323info->is_faststart_Setup = pi->is_faststart;
+
+ /* set te calling and called number from the Q931 packet */
+ if (q931_frame_num == pinfo->fd->num){
+ if (q931_calling_number != NULL){
+ g_free(strinfo->from_identity);
+ strinfo->from_identity=g_strdup(q931_calling_number);
+ }
+ if (q931_called_number != NULL){
+ g_free(strinfo->to_identity);
+ strinfo->to_identity=g_strdup(q931_called_number);
+ }
+ }
+ if (tmp_h323info->h225SetupAddr == 0) g_memmove(&(tmp_h323info->h225SetupAddr), pinfo->src.data,4);
+ strinfo->call_state=VOIP_CALL_SETUP;
+ comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ (pi->is_faststart==TRUE?"on":"off"));
+ break;
+ case H225_CONNECT:
+ strinfo->call_state=VOIP_IN_CALL;
+ if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
+ comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ (pi->is_faststart==TRUE?"on":"off"));
+ break;
+ case H225_RELEASE_COMPLET:
+ g_memmove(&(tmp_src), pinfo->src.data, 4);
+ if (strinfo->call_state==VOIP_CALL_SETUP){
+ if (tmp_h323info->h225SetupAddr == tmp_src){ /* forward direction */
+ strinfo->call_state=VOIP_CANCELLED;
+ }
+ else{ /* reverse */
+ strinfo->call_state=VOIP_REJECTED;
+ tapinfo->rejected_calls++;
+ }
+ }
+ else if (strinfo->call_state == VOIP_IN_CALL){
+ strinfo->call_state = VOIP_COMPLETED;
+ tapinfo->completed_calls++;
+ }
+ /* get the Q931 Release cause code */
+ if (q931_frame_num == pinfo->fd->num){
+ if (q931_cause_value != 0xFF){
+ comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+ } else { /* Cause not set */
+ comment = g_strdup("H225 No Q931 Rel Cause");
+ }
+ }
+ break;
+ case H225_PROGRESS:
+ case H225_ALERTING:
+ case H225_CALL_PROCEDING:
+ if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
+ comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ (pi->is_faststart==TRUE?"on":"off"));
+ break;
+ default:
+ comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
+ (pi->is_faststart==TRUE?"on":"off"));
+
+ }
+ } else if (pi->msg_type == H225_RAS){
+ frame_label = g_strdup_printf("%s", val_to_str(pi->msg_tag, RasMessage_vals, "<unknown>"));
+ comment = g_strdup("H225 RAS");
+ } else {
+ frame_label = g_strdup("H225: Unknown");
+ comment = g_strdup("");
+ }
+
+ /* add to graph analysis */
+ if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) /* if the frame number exists in graph, append to it*/
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num); /* if not exist, add to the graph */
+
+ g_free(frame_label);
+ g_free(comment);
+ }
+
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_H225_tap_listener=FALSE;
+/****************************************************************************/
+void
+h225_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_H225_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ error_string = register_tap_listener("h225", &the_tapinfo_struct, NULL,
+ NULL, (void*)H225calls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_H225_tap_listener=TRUE;
+ }
+}
+
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_h225_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_H225_tap_listener=FALSE;
+}
+
+
+/****************************************************************************/
+/* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
+int H245dgcalls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *H245info)
+{
+
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ h323_calls_info_t *tmp_h323info;
+ gchar *frame_label;
+ gchar *comment;
+ GList* list;
+ GList* list2;
+ guint32 tmp_src, tmp_dst;
+ h245_address_t *h245_add = NULL;
+
+ h245_packet_info *pi = H245info;
+
+ /* we ignore packets that are not displayed */
+ if (pinfo->fd->flags.passed_dfilter == 0)
+ return 0;
+
+ /* if H245 tunneling is on, append to graph */
+ if (append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) return 1;
+
+
+ /* it is not Tunneling or it is not in the list. So check if there is no tunneling
+ and there is a call with this H245 address */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_H323){
+ tmp_h323info = tmp_listinfo->prot_info;
+
+ g_memmove(&(tmp_src), pinfo->src.data, 4);
+ g_memmove(&(tmp_dst), pinfo->dst.data, 4);
+ list2 = g_list_first(tmp_h323info->h245_list);
+ while (list2)
+ {
+ h245_add=list2->data;
+ if ( ((h245_add->h245_address == tmp_src) && (h245_add->h245_port == pinfo->srcport))
+ || ((h245_add->h245_address == tmp_dst) && (h245_add->h245_port == pinfo->destport)) ){
+ strinfo = (voip_calls_info_t*)(list->data);
+
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+
+ break;
+ }
+ list2 = g_list_next(list2);
+ }
+ if (strinfo!=NULL) break;
+ }
+ list = g_list_next(list);
+ }
+
+ if (strinfo!=NULL){
+ frame_label = g_strdup(pi->frame_label);
+ comment = g_strdup(pi->comment);
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ g_free(frame_label);
+ g_free(comment);
+ }
+
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_H245dg_tap_listener=FALSE;
+/****************************************************************************/
+void
+h245dg_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_H245dg_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ error_string = register_tap_listener("h245dg", &the_tapinfo_struct, NULL,
+ NULL, (void*)H245dgcalls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_H245dg_tap_listener=TRUE;
+ }
+}
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_h245dg_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_H245dg_tap_listener=FALSE;
+}
+
+
+/****************************************************************************/
+/****************************TAP for SDP PROTOCOL ***************************/
+/****************************************************************************/
+/* whenever a SDP packet is seen by the tap listener */
+int SDPcalls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *SDPinfo)
+{
+ sdp_packet_info *pi = SDPinfo;
+
+ /* we ignore packets that are not displayed */
+ if (pinfo->fd->flags.passed_dfilter == 0)
+ return 0;
+
+ /* Append to graph the SDP summary if the packet exists */
+ g_snprintf(pi->summary_str, 50, "SDP (%s)", pi->summary_str);
+ append_to_frame_graph(tapinfo, pinfo->fd->num, pi->summary_str, NULL);
+
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_sdp_tap_listener=FALSE;
+/****************************************************************************/
+void
+sdp_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_sdp_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ error_string = register_tap_listener("sdp", &the_tapinfo_struct, NULL,
+ NULL, (void*)SDPcalls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_sdp_tap_listener=TRUE;
+ }
+}
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_sdp_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_sdp_tap_listener=FALSE;
+}
+
+
+
+
+
+/****************************************************************************/
+/* ***************************TAP for OTHER PROTOCOL **********************************/
+/****************************************************************************/
+
+/****************************************************************************/
+/* redraw the output */
+/*void prot_calls_draw(voip_calls_tapinfo_t *tapinfo _U_)
+{
+ return;
+}
+*/
+/****************************************************************************/
+/* whenever a prot_ packet is seen by the tap listener */
+/*int prot_calls_packet(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *prot_info _U_)
+{
+ if (strinfo!=NULL){
+ strinfo->stop_sec=pinfo->fd->rel_secs;
+ strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ ++(tapinfo->npackets);
+ }
+
+ return 1;
+}
+*/
+/****************************************************************************/
+/*
+static gboolean have_prot__tap_listener=FALSE;
+
+void
+prot_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_prot__tap_listener==FALSE)
+ {
+ error_string = register_tap_listener("prot_", &the_tapinfo_struct,
+ NULL,
+ NULL, (void*)prot_calls_packet, NULL);
+
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_prot__tap_listener=TRUE;
+ }
+}
+*/
+/****************************************************************************/
+/*
+void
+remove_tap_listener_prot__calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&the_tapinfo_struct);
+ unprotect_thread_critical_region();
+
+ have_prot__tap_listener=FALSE;
+}
+*/
+
+/****************************************************************************/
+
+/*void prot_calls_reset(voip_calls_tapinfo_t *tapinfo _U_)
+{
+ return;
+}
+*/
diff --git a/gtk/voip_calls.h b/gtk/voip_calls.h
new file mode 100644
index 0000000000..0cd976513b
--- /dev/null
+++ b/gtk/voip_calls.h
@@ -0,0 +1,191 @@
+/* voip_calls.h
+ * VoIP calls summary addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Ericsson , Spain
+ * By Francisco Alcoba <francisco.alcoba@ericsson.com>
+ *
+ * based on h323_calls.h
+ * Copyright 2004, Iskratel, Ltd, Kranj
+ * By Miha Jemec <m.jemec@iskratel.si>
+ *
+ * H323, RTP and Graph Support
+ * By Alejandro Vaquero, alejandro.vaquero@verso.com
+ * Copyright 2005, Verso Technologies Inc.
+ *
+ * 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.
+ */
+
+#ifndef VOIP_CALLS_H_INCLUDED
+#define VOIP_CALLS_H_INCLUDED
+
+#include <glib.h>
+#include <stdio.h>
+
+/****************************************************************************/
+/* defines voip call state */
+typedef enum _voip_call_state {
+ VOIP_CALL_SETUP,
+ VOIP_IN_CALL,
+ VOIP_CANCELLED,
+ VOIP_COMPLETED,
+ VOIP_REJECTED,
+ VOIP_UNKNOWN
+} voip_call_state;
+
+extern char *voip_call_state_name[6];
+
+typedef enum _voip_call_active_state {
+ VOIP_ACTIVE,
+ VOIP_INACTIVE
+} voip_call_active_state;
+
+typedef enum _voip_protocol {
+ VOIP_SIP,
+ VOIP_ISUP,
+ VOIP_H323
+} voip_protocol;
+
+extern char *voip_protocol_name[3];
+
+/* defines specific SIP data */
+
+typedef enum _sip_call_state {
+ SIP_INVITE_SENT,
+ SIP_200_REC,
+ SIP_CANCEL_SENT
+} sip_call_state;
+
+typedef struct _sip_calls_info {
+ gchar *call_identifier;
+ guint32 invite_cseq;
+ sip_call_state sip_state;
+} sip_calls_info_t;
+
+/* defines specific ISUP data */
+
+typedef struct _isup_calls_info {
+ guint16 cic;
+ guint32 opc, dpc;
+ guint8 ni;
+} isup_calls_info_t;
+
+typedef struct _h245_address {
+ guint32 h245_address;
+ guint16 h245_port;
+} h245_address_t;
+
+/* defines specific H323 data */
+typedef struct _h323_calls_info {
+ guint8 *guid; /* Call ID to identify a H225 */
+ GList* h245_list; /* list of H245 Address and ports for tunneling off calls*/
+ guint32 h225SetupAddr; /* we use the SETUP H225 IP to determine if packets are forward or reverse */
+ gboolean is_h245;
+ gboolean is_faststart_Setup; /* if faststart field is included in Setup*/
+ gboolean is_faststart_Proc; /* if faststart field is included in Proce, Alerting, Progress or Connect*/
+ gboolean is_h245Tunneling;
+ gint32 q931_crv;
+ gint32 q931_crv2;
+} h323_calls_info_t;
+
+/* defines a voip call */
+typedef struct _voip_calls_info {
+ voip_call_state call_state;
+ voip_call_active_state call_active_state;
+ gchar *from_identity;
+ gchar *to_identity;
+ gpointer prot_info;
+ guint32 initial_speaker;
+ guint32 npackets;
+ guint32 first_frame_num; /* frame number of first frame */
+ guint32 last_frame_num;
+ voip_protocol protocol;
+ guint16 call_num;
+ gint32 start_sec, start_usec, stop_sec, stop_usec;
+ gboolean selected;
+
+} voip_calls_info_t;
+
+/* structure that holds the information about all detected calls */
+/* struct holding all information of the tap */
+
+typedef struct _voip_calls_tapinfo {
+ int ncalls; /* number of calls in the list */
+ GList* strinfo_list; /* list with all calls */
+ int npackets; /* total number of packets of all calls */
+ voip_calls_info_t* filter_calls_fwd; /* used as filter in some tap modes */
+ guint32 launch_count; /* number of times the tap has been run */
+ int start_packets;
+ int completed_calls;
+ int rejected_calls;
+ graph_analysis_info_t* graph_analysis;
+} voip_calls_tapinfo_t;
+
+
+/****************************************************************************/
+/* INTERFACE */
+
+/*
+* Registers the voip_calls tap listeners (if not already done).
+* From that point on, the calls list will be updated with every redissection.
+* This function is also the entry point for the initialization routine of the tap system.
+* So whenever voip_calls.c is added to the list of ETHEREAL_TAP_SRCs, the tap will be registered on startup.
+* If not, it will be registered on demand by the voip_calls functions that need it.
+*/
+void sip_calls_init_tap(void);
+void isup_calls_init_tap(void);
+void mtp3_calls_init_tap(void);
+void h225_calls_init_tap(void);
+void h245dg_calls_init_tap(void);
+void q931_calls_init_tap(void);
+void sdp_calls_init_tap(void);
+
+
+/*
+* Removes the voip_calls tap listener (if not already done)
+* From that point on, the voip calls list won't be updated any more.
+*/
+void remove_tap_listener_sip_calls(void);
+void remove_tap_listener_isup_calls(void);
+void remove_tap_listener_mtp3_calls(void);
+void remove_tap_listener_h225_calls(void);
+void remove_tap_listener_h245dg_calls(void);
+void remove_tap_listener_q931_calls(void);
+void remove_tap_listener_sdp_calls(void);
+
+/*
+* Retrieves a constant reference to the unique info structure of the voip_calls tap listener.
+* The user should not modify the data pointed to.
+*/
+const voip_calls_tapinfo_t* voip_calls_get_info(void);
+
+/*
+* Cleans up memory of voip calls tap.
+*/
+void voip_calls_reset(voip_calls_tapinfo_t *tapinfo);
+void isup_calls_reset(voip_calls_tapinfo_t *tapinfo);
+void mtp3_calls_reset(voip_calls_tapinfo_t *tapinfo);
+void q931_calls_reset(voip_calls_tapinfo_t *tapinfo);
+
+void graph_analysis_data_init();
+
+void add_rtp_streams_graph();
+
+#endif /*VOIP_CALLS_H_INCLUDED*/
diff --git a/gtk/voip_calls_dlg.c b/gtk/voip_calls_dlg.c
new file mode 100644
index 0000000000..964eabb5ee
--- /dev/null
+++ b/gtk/voip_calls_dlg.c
@@ -0,0 +1,719 @@
+/* voip_calls_dlg.c
+ * VoIP calls summary addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Ericsson , Spain
+ * By Francisco Alcoba <francisco.alcoba@ericsson.com>
+ *
+ * based on h323_calls_dlg.c
+ * Copyright 2004, Iskratel, Ltd, Kranj
+ * By Miha Jemec <m.jemec@iskratel.si>
+ *
+ * H323, RTP and Graph Support
+ * By Alejandro Vaquero, alejandro.vaquero@verso.com
+ * Copyright 2005, Verso Technologies Inc.
+ *
+ * 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 "register.h"
+
+#include "graph_analysis.h"
+#include "voip_calls_dlg.h"
+#include "voip_calls.h"
+
+#include "globals.h"
+#include "epan/filesystem.h"
+
+#include "tap_menu.h"
+#include "dlg_utils.h"
+#include "ui_util.h"
+#include "compat_macros.h"
+#include "gtkglobals.h"
+
+#include "image/clist_ascend.xpm"
+#include "image/clist_descend.xpm"
+#include "simple_dialog.h"
+
+#include <epan/to_str.h>
+
+#include <string.h>
+
+
+typedef const guint8 * ip_addr_p;
+
+static const gchar FWD_LABEL_TEXT[] = "Select one call.";
+
+/****************************************************************************/
+/* pointer to the one and only dialog window */
+static GtkWidget *voip_calls_dlg = NULL;
+
+static GtkWidget *clist = NULL;
+static GtkWidget *top_label = NULL;
+static GtkWidget *status_label = NULL;
+static GtkWidget *label_fwd = NULL;
+
+/*static GtkWidet *bt_unselect = NULL;*/
+static GtkWidget *bt_filter = NULL;
+static GtkWidget *bt_graph = NULL;
+
+
+static voip_calls_info_t* selected_call_fwd = NULL; /* current selection */
+static GList *last_list = NULL;
+
+static guint32 calls_nb = 0; /* number of displayed calls */
+static guint32 calls_ns = 0; /* number of selected calls */
+
+static graph_analysis_data_t *graph_analysis_data;
+
+#define NUM_COLS 9
+
+/****************************************************************************/
+/* append a line to clist */
+static void add_to_clist(voip_calls_info_t* strinfo)
+{
+ gchar label_text[256];
+ gint added_row;
+ gchar *data[NUM_COLS];
+ gchar field[NUM_COLS][50];
+ gint c;
+ isup_calls_info_t *tmp_isupinfo;
+ h323_calls_info_t *tmp_h323info;
+ gboolean tmp_bool = FALSE;
+ for (c=0;c<NUM_COLS;c++){
+ data[c]=&field[c][0];
+ }
+
+
+ g_snprintf(field[0], 15, "%i.%2i", strinfo->start_sec, strinfo->start_usec/10000);
+ g_snprintf(field[1], 15, "%i.%2i", strinfo->stop_sec, strinfo->stop_usec/10000);
+/* xxx display_signed_time(data[0], sizeof(field[0]), strinfo->start_sec, strinfo->start_usec, USECS); */
+/* display_signed_time(data[1], sizeof(field[0]), strinfo->stop_sec, strinfo->stop_usec, USECS); */
+ g_snprintf(field[2], 30, "%s", ip_to_str((const guint8*)&(strinfo->initial_speaker)));
+ g_snprintf(field[3], 50, "%s", strinfo->from_identity);
+ g_snprintf(field[4], 50, "%s", strinfo->to_identity);
+ g_snprintf(field[5], 15, "%s", voip_protocol_name[strinfo->protocol]);
+ g_snprintf(field[6], 15, "%u", strinfo->npackets);
+ g_snprintf(field[7], 15, "%s", voip_call_state_name[strinfo->call_state]);
+
+ /* Add comments based on the protocol */
+ switch(strinfo->protocol){
+ case VOIP_ISUP:
+ tmp_isupinfo = strinfo->prot_info;
+ g_snprintf(field[8],30, "%i-%i -> %i-%i", tmp_isupinfo->ni, tmp_isupinfo->opc,
+ tmp_isupinfo->ni, tmp_isupinfo->dpc);
+ break;
+ case VOIP_H323:
+ tmp_h323info = strinfo->prot_info;
+ if (strinfo->call_state == VOIP_CALL_SETUP)
+ tmp_bool = tmp_h323info->is_faststart_Setup;
+ else
+ if ((tmp_h323info->is_faststart_Setup == TRUE) && (tmp_h323info->is_faststart_Proc == TRUE)) tmp_bool = TRUE;
+ g_snprintf(field[8],35, "Tunneling: %s Fast Start: %s", (tmp_h323info->is_h245Tunneling==TRUE?"ON":"OFF"),
+ (tmp_bool==TRUE?"ON":"OFF"));
+ break;
+ default:
+ field[8][0]='\0';
+ }
+
+
+ added_row = gtk_clist_append(GTK_CLIST(clist), data);
+
+ /* set data pointer of last row to point to user data for that row */
+ gtk_clist_set_row_data(GTK_CLIST(clist), added_row, strinfo);
+
+ /* Update the top label with the number of detected calls */
+ calls_nb++;
+ g_snprintf(label_text, 256,
+ "Detected %d VoIP %s. Selected %d %s.",
+ calls_nb,
+ plurality(calls_nb, "Call", "Calls"),
+ calls_ns,
+ plurality(calls_ns, "Call", "Calls"));
+ gtk_label_set(GTK_LABEL(top_label), label_text);
+
+ /* Update the status label with the number of total messages */
+ g_snprintf(label_text, 256,
+ "Total: Calls: %d Start packets: %d Completed calls: %d Rejected calls: %d",
+ voip_calls_get_info()->ncalls,
+ voip_calls_get_info()->start_packets,
+ voip_calls_get_info()->completed_calls,
+ voip_calls_get_info()->rejected_calls);
+ gtk_label_set(GTK_LABEL(status_label), label_text);
+}
+
+
+void voip_calls_remove_tap_listener()
+{
+ /* Remove the calls tap listener */
+ remove_tap_listener_sip_calls();
+ remove_tap_listener_isup_calls();
+ remove_tap_listener_mtp3_calls();
+ remove_tap_listener_h225_calls();
+ remove_tap_listener_h245dg_calls();
+ remove_tap_listener_q931_calls();
+ remove_tap_listener_sdp_calls();
+}
+
+/****************************************************************************/
+/* CALLBACKS */
+/****************************************************************************/
+static void
+voip_calls_on_destroy (GtkObject *object _U_,
+ gpointer user_data _U_)
+{
+ /* Clean up memory used by calls tap */
+ voip_calls_reset((voip_calls_tapinfo_t*) voip_calls_get_info());
+
+ /* Note that we no longer have a "VoIP Calls" dialog box. */
+ voip_calls_dlg = NULL;
+}
+
+
+/****************************************************************************/
+static void
+voip_calls_on_unselect (GtkButton *button _U_,
+ gpointer user_data _U_)
+{
+ selected_call_fwd = NULL;
+ gtk_clist_unselect_all(GTK_CLIST(clist));
+ gtk_label_set_text(GTK_LABEL(label_fwd), FWD_LABEL_TEXT);
+
+ /*gtk_widget_set_sensitive(bt_unselect, FALSE);*/
+ gtk_widget_set_sensitive(bt_filter, FALSE);
+}
+
+
+/****************************************************************************/
+static void
+voip_calls_on_filter (GtkButton *button _U_,
+ gpointer user_data _U_)
+{
+ gchar *filter_string = NULL;
+ gchar *filter_string_fwd = NULL;
+ gchar filter_prepend[5];
+ sip_calls_info_t *tmp_sipinfo;
+ isup_calls_info_t *tmp_isupinfo;
+ h323_calls_info_t *tmp_h323info;
+ h245_address_t *h245_add = NULL;
+ GList* list;
+
+ if (selected_call_fwd==NULL)
+ return;
+
+ filter_string=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
+ if (strcmp(filter_string,"")!=0){ /* this means there is already a display filter, we or it */
+ strcpy(filter_prepend," or ");
+ }
+ else{
+ strcpy(filter_prepend,"");
+ }
+
+
+ switch(selected_call_fwd->protocol){
+ case VOIP_SIP:
+ tmp_sipinfo = selected_call_fwd->prot_info;
+ filter_string_fwd = g_strdup_printf("%s(sip.Call-ID == \"%s\") ",
+ filter_prepend, tmp_sipinfo->call_identifier
+ );
+ filter_string = filter_string_fwd;
+ gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string);
+ break;
+ case VOIP_ISUP:
+ tmp_isupinfo = selected_call_fwd->prot_info;
+ filter_string_fwd = g_strdup_printf("%s(isup.cic == %i and frame.number >=%i and frame.number<=%i and mtp3.network_indicator == %i and ((mtp3.dpc == %i) and (mtp3.opc == %i)) or((mtp3.dpc == %i) and (mtp3.opc == %i))) ",
+ filter_prepend, tmp_isupinfo->cic,selected_call_fwd->first_frame_num,
+ selected_call_fwd->last_frame_num,
+ tmp_isupinfo->ni, tmp_isupinfo->dpc, tmp_isupinfo->opc,
+ tmp_isupinfo->opc, tmp_isupinfo->dpc
+ );
+ filter_string = filter_string_fwd;
+ gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string);
+ break;
+ case VOIP_H323:
+ tmp_h323info = selected_call_fwd->prot_info;
+ filter_string_fwd = g_strdup_printf("%s((h225.guid == %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x || q931.call_ref == %x:%x || q931.call_ref == %x:%x) ",
+ filter_prepend, (guint8)tmp_h323info->guid[0], (guint8)tmp_h323info->guid[1], (guint8)tmp_h323info->guid[2],
+ (guint8)tmp_h323info->guid[3], (guint8)tmp_h323info->guid[4], (guint8)tmp_h323info->guid[5], (guint8)tmp_h323info->guid[6],
+ (guint8)tmp_h323info->guid[7], (guint8)tmp_h323info->guid[8], (guint8)tmp_h323info->guid[9], (guint8)tmp_h323info->guid[10],
+ (guint8)tmp_h323info->guid[11], (guint8)tmp_h323info->guid[12], (guint8)tmp_h323info->guid[13], (guint8)tmp_h323info->guid[14],
+ (guint8)tmp_h323info->guid[15], (guint8)(tmp_h323info->q931_crv & 0xff), (guint8)((tmp_h323info->q931_crv & 0xff00)>>8)
+ , (guint8)(tmp_h323info->q931_crv2 & 0xff), (guint8)((tmp_h323info->q931_crv2 & 0xff00)>>8));
+
+ list = g_list_first(tmp_h323info->h245_list);
+ while (list)
+ {
+ h245_add=list->data;
+ filter_string_fwd = g_strdup_printf("%s || (ip.addr == %s && tcp.port == %d && h245) ", filter_string_fwd,
+ ip_to_str((guint8 *)&(h245_add->h245_address)), h245_add->h245_port);
+ list = g_list_next(list);
+ }
+ filter_string_fwd = g_strdup_printf("%s ) ", filter_string_fwd);
+
+ filter_string = filter_string_fwd;
+ gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string);
+ break;
+
+ }
+
+
+ g_free(filter_string);
+
+/*
+ main_filter_packets(&cfile, filter_string, FALSE);
+ voip_calls_dlg_update(voip_calls_get_info()->strinfo_list);
+*/
+}
+
+
+
+
+/****************************************************************************/
+static void
+on_graph_bt_clicked (GtkButton *button _U_,
+ gpointer user_data _U_)
+{
+ graph_analysis_item_t *gai;
+ GList* list;
+ GList* list2;
+ voip_calls_info_t *tmp_listinfo;
+
+ /* reset the "display" parameter in graph analysis */
+ list2 = g_list_first(voip_calls_get_info()->graph_analysis->list);
+ while (list2){
+ gai = list2->data;
+ gai->display = FALSE;
+ list2 = g_list_next(list2);
+ }
+
+
+ /* set the display for selected calls */
+ list = g_list_first(voip_calls_get_info()->strinfo_list);
+ while (list){
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->selected){
+ list2 = g_list_first(voip_calls_get_info()->graph_analysis->list);
+ while (list2){
+ gai = list2->data;
+ if (gai->conv_num == tmp_listinfo->call_num){
+ gai->display = TRUE;
+ }
+ list2 = g_list_next(list2);
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ /* create or refresh the graph windows */
+ if (graph_analysis_data->dlg.window == NULL) /* create the window */
+ graph_analysis_create(graph_analysis_data);
+ else
+ graph_analysis_update(graph_analysis_data); /* refresh it */
+}
+
+static const GdkColor COLOR_SELECT = {0, 0x00ff, 0x80ff, 0x80ff};
+static const GdkColor COLOR_DEFAULT = {0, 0xffff, 0xffff, 0xffff};
+
+/****************************************************************************/
+/* when the user selects a row in the calls list */
+static void
+voip_calls_on_select_row(GtkCList *clist,
+ gint row _U_,
+ gint column _U_,
+ GdkEventButton *event _U_,
+ gpointer user_data _U_)
+{
+ GdkColor color = COLOR_DEFAULT;
+ gchar label_text[80];
+
+ selected_call_fwd = gtk_clist_get_row_data(GTK_CLIST(clist), row);
+
+ if (!selected_call_fwd->selected)
+ calls_ns++;
+ else
+ calls_ns--;
+
+ g_snprintf(label_text, 256,
+ "Detected %d VoIP %s. Selected %d %s.",
+ calls_nb,
+ plurality(calls_nb, "Call", "Calls"),
+ calls_ns,
+ plurality(calls_ns, "Call", "Calls"));
+ gtk_label_set(GTK_LABEL(top_label), label_text);
+
+ g_snprintf(label_text, 80, "Selected Call: From %s To %s, starting time %i.%i",
+ selected_call_fwd->from_identity,
+ selected_call_fwd->to_identity,
+ selected_call_fwd->start_sec,
+ selected_call_fwd->start_usec
+ );
+ gtk_label_set_text(GTK_LABEL(label_fwd), label_text);
+
+ selected_call_fwd->selected=!selected_call_fwd->selected;
+ if (selected_call_fwd->selected)
+ color = COLOR_SELECT;
+ else
+ color = COLOR_DEFAULT;
+
+ gtk_clist_set_background(GTK_CLIST(clist), row, &color);
+
+ /*gtk_widget_set_sensitive(bt_unselect, TRUE);*/
+ gtk_widget_set_sensitive(bt_filter, TRUE);
+
+ /* TODO: activate other buttons when implemented */
+}
+
+
+/****************************************************************************/
+
+typedef struct column_arrows {
+ GtkWidget *table;
+ GtkWidget *ascend_pm;
+ GtkWidget *descend_pm;
+} column_arrows;
+
+
+/****************************************************************************/
+static void
+voip_calls_click_column_cb(GtkCList *clist, gint column, gpointer data)
+{
+ column_arrows *col_arrows = (column_arrows *) data;
+ int i;
+
+ gtk_clist_freeze(clist);
+
+ for (i=0; i<NUM_COLS; i++) {
+ gtk_widget_hide(col_arrows[i].ascend_pm);
+ gtk_widget_hide(col_arrows[i].descend_pm);
+ }
+
+ if (column == clist->sort_column) {
+ if (clist->sort_type == GTK_SORT_ASCENDING) {
+ clist->sort_type = GTK_SORT_DESCENDING;
+ gtk_widget_show(col_arrows[column].descend_pm);
+ } else {
+ clist->sort_type = GTK_SORT_ASCENDING;
+ gtk_widget_show(col_arrows[column].ascend_pm);
+ }
+ } else {
+ clist->sort_type = GTK_SORT_ASCENDING;
+ gtk_widget_show(col_arrows[column].ascend_pm);
+ gtk_clist_set_sort_column(clist, column);
+ }
+ gtk_clist_thaw(clist);
+
+ gtk_clist_sort(clist);
+}
+
+
+/****************************************************************************/
+static gint
+voip_calls_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
+{
+ char *text1 = NULL;
+ char *text2 = NULL;
+ int i1, i2;
+
+ const GtkCListRow *row1 = (const GtkCListRow *) ptr1;
+ const GtkCListRow *row2 = (const GtkCListRow *) ptr2;
+
+ text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
+ text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
+
+ switch(clist->sort_column){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ return strcmp (text1, text2);
+ case 6:
+ i1=atoi(text1);
+ i2=atoi(text2);
+ return i1-i2;
+ }
+ g_assert_not_reached();
+ return 0;
+}
+
+
+/****************************************************************************/
+/* INTERFACE */
+/****************************************************************************/
+
+static void voip_calls_dlg_create (void)
+{
+ GtkWidget *voip_calls_dlg_w;
+ GtkWidget *main_vb;
+ GtkWidget *scrolledwindow;
+ GtkWidget *hbuttonbox;
+ GtkWidget *bt_close;
+ GtkTooltips *tooltips = gtk_tooltips_new();
+
+ gchar *titles[NUM_COLS] = {"Start Time", "Stop Time", "Initial Speaker", "From", "To", "Protocol", "Packets", "State", "Comments"};
+ column_arrows *col_arrows;
+ GtkWidget *column_lb;
+ int i;
+
+ voip_calls_dlg_w=window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: VoIP Calls");
+
+ gtk_window_set_default_size(GTK_WINDOW(voip_calls_dlg_w), 840, 350);
+
+ main_vb = gtk_vbox_new (FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(voip_calls_dlg_w), main_vb);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vb), 12);
+
+ top_label = gtk_label_new ("Detected 0 VoIP Calls. Selected 0 Calls.");
+ gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8);
+
+ scrolledwindow = scrolled_window_new (NULL, NULL);
+ gtk_box_pack_start (GTK_BOX (main_vb), scrolledwindow, TRUE, TRUE, 0);
+
+ clist = gtk_clist_new (NUM_COLS);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow), clist);
+
+ gtk_clist_set_column_width (GTK_CLIST (clist), 0, 60);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 1, 60);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 2, 80);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 3, 130);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 4, 130);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 5, 50);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 6, 45);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 7, 60);
+ gtk_clist_set_column_width (GTK_CLIST (clist), 8, 100);
+
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 0, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 1, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 2, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 3, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 4, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 5, GTK_JUSTIFY_CENTER);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 6, GTK_JUSTIFY_CENTER);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 7, GTK_JUSTIFY_LEFT);
+ gtk_clist_set_column_justification(GTK_CLIST(clist), 8, GTK_JUSTIFY_LEFT);
+
+ gtk_clist_column_titles_show (GTK_CLIST (clist));
+
+ gtk_clist_set_compare_func(GTK_CLIST(clist), voip_calls_sort_column);
+ gtk_clist_set_sort_column(GTK_CLIST(clist), 0);
+ gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING);
+
+ gtk_widget_show(voip_calls_dlg_w);
+
+ /* sort by column feature */
+ col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * NUM_COLS);
+
+ for (i=0; i<NUM_COLS; i++) {
+ col_arrows[i].table = gtk_table_new(2, 2, FALSE);
+ gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
+ column_lb = gtk_label_new(titles[i]);
+ gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_widget_show(column_lb);
+
+ col_arrows[i].ascend_pm = xpm_to_widget(clist_ascend_xpm);
+ gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ col_arrows[i].descend_pm = xpm_to_widget(clist_descend_xpm);
+ gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ /* make start time be the default sort order */
+ if (i == 0) {
+ gtk_widget_show(col_arrows[i].ascend_pm);
+ }
+ gtk_clist_set_column_widget(GTK_CLIST(clist), i, col_arrows[i].table);
+ gtk_widget_show(col_arrows[i].table);
+ }
+
+ SIGNAL_CONNECT(clist, "click-column", voip_calls_click_column_cb, col_arrows);
+
+ label_fwd = gtk_label_new (FWD_LABEL_TEXT);
+ gtk_box_pack_start (GTK_BOX (main_vb), label_fwd, FALSE, FALSE, 0);
+
+ status_label = gtk_label_new ("Total: Calls: 0 Start packets: 0 Completed calls: 0 Rejected calls: 0");
+ gtk_box_pack_start (GTK_BOX (main_vb), status_label, FALSE, FALSE, 8);
+
+ /* button row */
+ hbuttonbox = gtk_hbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX (main_vb), hbuttonbox, FALSE, FALSE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_SPREAD);
+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox), 30);
+
+ /*bt_unselect = gtk_button_new_with_label ("Unselect");
+ gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_unselect);
+ gtk_tooltips_set_tip (tooltips, bt_unselect, "Unselect this conversation", NULL);*/
+
+ bt_filter = gtk_button_new_with_label ("Prepare filter");
+ gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_filter);
+ gtk_tooltips_set_tip (tooltips, bt_filter, "Prepare a display filter of the selected conversation", NULL);
+
+ bt_graph = gtk_button_new_with_label("Graph");
+ gtk_container_add(GTK_CONTAINER(hbuttonbox), bt_graph);
+ gtk_widget_show(bt_graph);
+ SIGNAL_CONNECT(bt_graph, "clicked", on_graph_bt_clicked, NULL);
+
+ bt_close = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_close);
+ GTK_WIDGET_SET_FLAGS(bt_close, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip (tooltips, bt_close, "Close this dialog", NULL);
+
+ SIGNAL_CONNECT(clist, "select_row", voip_calls_on_select_row, NULL);
+ /*SIGNAL_CONNECT(bt_unselect, "clicked", voip_calls_on_unselect, NULL);*/
+ SIGNAL_CONNECT(bt_filter, "clicked", voip_calls_on_filter, NULL);
+
+ window_set_cancel_button(voip_calls_dlg_w, bt_close, window_cancel_button_cb);
+
+ SIGNAL_CONNECT(voip_calls_dlg_w, "delete_event", window_delete_event_cb, NULL);
+ SIGNAL_CONNECT(voip_calls_dlg_w, "destroy", voip_calls_on_destroy, NULL);
+
+ gtk_widget_show_all(voip_calls_dlg_w);
+ window_present(voip_calls_dlg_w);
+
+ voip_calls_on_unselect(NULL, NULL);
+
+ voip_calls_dlg = voip_calls_dlg_w;
+}
+
+
+/****************************************************************************/
+/* PUBLIC */
+/****************************************************************************/
+
+/****************************************************************************/
+/* update the contents of the dialog box clist */
+/* list: pointer to list of voip_calls_info_t* */
+
+void voip_calls_dlg_update(GList *list)
+{
+ gchar label_text[256];
+
+ if (voip_calls_dlg != NULL) {
+
+ voip_calls_remove_tap_listener();
+
+ /* Add the RTP streams info for the graph */
+ add_rtp_streams_graph();
+
+ gtk_clist_clear(GTK_CLIST(clist));
+ calls_nb = 0;
+ calls_ns = 0;
+ g_snprintf(label_text, 256,
+ "Total: Calls: %d Start packets: %d Completed calls: %d Rejected calls: %d",
+ voip_calls_get_info()->ncalls,
+ voip_calls_get_info()->start_packets,
+ voip_calls_get_info()->completed_calls,
+ voip_calls_get_info()->rejected_calls);
+ gtk_label_set(GTK_LABEL(status_label), label_text);
+
+ list = g_list_first(list);
+ while (list)
+ {
+ add_to_clist((voip_calls_info_t*)(list->data));
+ list = g_list_next(list);
+ }
+
+ g_snprintf(label_text, 256,
+ "Detected %d VoIP %s. Selected %d %s.",
+ calls_nb,
+ plurality(calls_nb, "Call", "Calls"),
+ calls_ns,
+ plurality(calls_ns, "Call", "Calls"));
+ gtk_label_set(GTK_LABEL(top_label), label_text);
+
+ voip_calls_on_unselect(NULL, NULL);
+ }
+
+ last_list = list;
+}
+
+
+/****************************************************************************/
+/* update the contents of the dialog box clist */
+/* list: pointer to list of voip_calls_info_t* */
+void voip_calls_dlg_show(GList *list)
+{
+ if (voip_calls_dlg != NULL) {
+ /* There's already a dialog box; reactivate it. */
+ reactivate_window(voip_calls_dlg);
+ /* Another list since last call? */
+ if (list != last_list) {
+ voip_calls_dlg_update(list);
+ }
+ }
+ else {
+ /* Create and show the dialog box */
+ voip_calls_dlg_create();
+ voip_calls_dlg_update(list);
+ }
+}
+
+/* init function for tap */
+static void
+voip_calls_init_tap(char *dummy _U_)
+{
+ graph_analysis_data_init();
+
+ /* Clean up memory used by calls tap */
+ voip_calls_reset((voip_calls_tapinfo_t*) voip_calls_get_info());
+
+ /* Register the tap listener */
+ sip_calls_init_tap();
+ mtp3_calls_init_tap();
+ isup_calls_init_tap();
+ h225_calls_init_tap();
+ h245dg_calls_init_tap();
+ q931_calls_init_tap();
+ sdp_calls_init_tap();
+
+
+ /* Scan for VoIP calls calls (redissect all packets) */
+ retap_packets(&cfile);
+
+ /* Show the dialog box with the list of calls */
+ voip_calls_dlg_show(voip_calls_get_info()->strinfo_list);
+
+
+ /* Tap listener will be removed and cleaned up in voip_calls_on_destroy */
+
+}
+
+
+/****************************************************************************/
+/* entry point when called via the GTK menu */
+void voip_calls_launch(GtkWidget *w _U_, gpointer data _U_)
+{
+ voip_calls_init_tap("");
+
+ /* init the Graph Analysys */
+ graph_analysis_data = graph_analysis_init();
+ graph_analysis_data->graph_info = voip_calls_get_info()->graph_analysis;
+}
+
+/****************************************************************************/
+void
+register_tap_listener_voip_calls_dlg(void)
+{
+ register_ethereal_tap("voip,calls",voip_calls_init_tap);
+ register_tap_menu_item("VoIP Calls...", REGISTER_TAP_GROUP_NONE,
+ voip_calls_launch, NULL, NULL, NULL);
+
+}
diff --git a/gtk/voip_calls_dlg.h b/gtk/voip_calls_dlg.h
new file mode 100644
index 0000000000..0c54061516
--- /dev/null
+++ b/gtk/voip_calls_dlg.h
@@ -0,0 +1,55 @@
+/* voip_calls_dlg.h
+ * VoIP conversations addition for ethereal
+ *
+ * $Id$
+ *
+ * Copyright 2004, Ericsson , Spain
+ * By Francisco Alcoba <francisco.alcoba@ericsson.com>
+ *
+ * based on h323_conversations_dlg.h
+ * Copyright 2004, Iskratel, Ltd, Kranj
+ * By Miha Jemec <m.jemec@iskratel.si>
+ *
+ * H323, RTP and Graph Support
+ * By Alejandro Vaquero, alejandro.vaquero@verso.com
+ * Copyright 2005, Verso Technologies Inc.
+ *
+ * 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.
+ */
+
+#ifndef VOIP_CALLS_DLG_H_INCLUDED
+#define VOIP_CALLS_DLG_H_INCLUDED
+
+#include <gtk/gtk.h>
+
+/**
+ * Create or reactivate the voip calls dialog box.
+ *
+ * @param list pointer to list of rtp_stream_info_t*
+ */
+void voip_calls_dlg_show(GList *list);
+
+/**
+ * Update the contents of the dialog box clist with that of list.
+ *
+ * @param list pointer to list of rtp_stream_info_t*
+ */
+void voip_calls_dlg_update(GList *list);
+
+#endif /* VOIP_CALLS_DLG_H_INCLUDED*/
diff --git a/rtp_pt.h b/rtp_pt.h
index 5508c066de..890c433707 100644
--- a/rtp_pt.h
+++ b/rtp_pt.h
@@ -63,5 +63,6 @@
#define PT_H263 34 /* from Chunrong Zhu of Intel; see the Web page */
ETH_VAR_IMPORT const value_string rtp_payload_type_vals[];
+ETH_VAR_IMPORT const value_string rtp_payload_type_short_vals[];
#endif