diff options
-rw-r--r-- | epan/dissectors/packet-t38.c | 88 | ||||
-rw-r--r-- | epan/dissectors/packet-t38.h | 16 | ||||
-rw-r--r-- | epan/libethereal.def | 1 | ||||
-rw-r--r-- | gtk/Makefile.common | 1 | ||||
-rw-r--r-- | gtk/graph_analysis.c | 52 | ||||
-rw-r--r-- | gtk/graph_analysis.h | 6 | ||||
-rw-r--r-- | gtk/voip_calls.c | 2 |
7 files changed, 154 insertions, 12 deletions
diff --git a/epan/dissectors/packet-t38.c b/epan/dissectors/packet-t38.c index 512046f290..ab03a8a090 100644 --- a/epan/dissectors/packet-t38.c +++ b/epan/dissectors/packet-t38.c @@ -51,6 +51,7 @@ #include <glib.h> #include <epan/packet.h> #include <epan/conversation.h> +#include <epan/tap.h> #include <stdio.h> #include <string.h> @@ -67,6 +68,8 @@ static guint global_t38_tcp_port = PORT_T38; static guint global_t38_udp_port = PORT_T38; +static int t38_tap = -1; + /* * Variables to allow for proper deletion of dissector registration when * the user changes port from the gui. @@ -171,6 +174,13 @@ static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* Preferences bool to control whether or not setup info should be shown */ static gboolean global_t38_show_setup_info = TRUE; +/* Can tap up to 4 T38 packets within same packet */ +/* We only tap the primary part, not the redundancy */ +#define MAX_T38_MESSAGES_IN_PACKET 4 +static t38_packet_info t38_info_arr[MAX_T38_MESSAGES_IN_PACKET]; +static int t38_info_current=0; +static t38_packet_info *t38_info=NULL; + /* Set up an T38 conversation */ void t38_add_address(packet_info *pinfo, address *addr, int port, @@ -292,7 +302,7 @@ static const per_choice_t t30_indicator_choice[] = { { 0, NULL, 0, NULL } }; -static const value_string t30_indicator_vals[] = { +const value_string t30_indicator_vals[] = { { 0, "no-signal" }, { 1, "cng" }, { 2, "ced" }, @@ -330,6 +340,11 @@ dissect_t38_t30_indicator(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_t col_append_fstr(pinfo->cinfo, COL_INFO, " t30ind: %s", val_to_str(T30ind_value,t30_indicator_vals,"<unknown>")); } + + /* info for tap */ + if (primary_part) + t38_info->t30ind_value = T30ind_value; + return offset; } @@ -397,6 +412,12 @@ dissect_t38_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree col_append_fstr(pinfo->cinfo, COL_INFO, " data:%s:", val_to_str(Data_value,data_vals,"<unknown>")); } + + + /* info for tap */ + if (primary_part) + t38_info->data_value = Data_value; + return offset; } @@ -419,6 +440,10 @@ dissect_t38_Type_of_msg(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto ett_t38_Type_of_msg, Type_of_msg_choice, &Type_of_msg_value); + /* info for tap */ + if (primary_part) + t38_info->type_msg = Type_of_msg_value; + return offset; } @@ -511,6 +536,16 @@ dissect_t38_Data_Field_field_type(tvbuff_t *tvb, int offset, packet_info *pinfo, val_to_str(Data_Field_field_type_value,Data_Field_field_type_vals,"<unknown>")); } + /* info for tap */ + if (primary_part) { + if ( (t38_info->t38_info_data_item_index < MAX_T38_DATA_ITEMS) && (t38_info->t38_info_data_item_index >= 0) ){ /*sanity check */ + t38_info->data_type[t38_info->t38_info_data_item_index] = Data_Field_field_type_value; + + if (t38_info->t38_info_data_item_index++ == MAX_T38_DATA_ITEMS-1) t38_info->t38_info_data_item_index = 1; + } + } + + return offset; } @@ -535,6 +570,16 @@ dissect_t38_Data_Field_field_data(tvbuff_t *tvb, int offset, packet_info *pinfo, tvb_bytes_to_str(value_tvb,0,7)); } } + + + /* info for tap */ + if (primary_part) { + if ( (t38_info->t38_info_data_item_index <= MAX_T38_DATA_ITEMS) && (t38_info->t38_info_data_item_index > 0) ){ /*sanity check */ + t38_info->data_len[t38_info->t38_info_data_item_index-1] = value_len; + t38_info->data[t38_info->t38_info_data_item_index-1] = tvb_memdup(value_tvb,0,value_len); + } + } + return offset; } @@ -591,6 +636,10 @@ dissect_t38_seq_number(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_t38_seq_number, 0, 65535, &seq_number, NULL, FALSE); + + /* info for tap */ + if (primary_part) + t38_info->seq_num = seq_number; if (check_col(pinfo->cinfo, COL_INFO)){ col_append_fstr(pinfo->cinfo, COL_INFO, "Seq=%05u ",seq_number); @@ -630,7 +679,8 @@ dissect_t38_secondary_ifp_packets(tvbuff_t *tvb, int offset, packet_info *pinfo, { /* When the field-data is not present, we MUST offset 1 byte*/ if((Data_Field_field_type_value != 0) && - (Data_Field_field_type_value != 6)) + (Data_Field_field_type_value != 6) && + (Data_Field_field_type_value != 7)) { offset=offset+8; } @@ -745,6 +795,7 @@ dissect_t38_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_item *it; proto_tree *tr; guint32 offset=0; + int i; /* * XXX - heuristic to check for misidentified packets. @@ -757,6 +808,25 @@ dissect_t38_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } } + /* tap info */ + t38_info_current++; + if (t38_info_current==MAX_T38_MESSAGES_IN_PACKET) { + t38_info_current=0; + } + t38_info = &t38_info_arr[t38_info_current]; + + t38_info->seq_num = 0; + t38_info->type_msg = 0; + t38_info->data_value = 0; + t38_info->t30ind_value =0; + + t38_info->t38_info_data_item_index = 0; + for (i=0; i<MAX_T38_DATA_ITEMS; i++) { + t38_info->data_type[i] = 0; + t38_info->data[i] = NULL; + t38_info->data_len[i] = 0; + } + if (check_col(pinfo->cinfo, COL_PROTOCOL)){ col_set_str(pinfo->cinfo, COL_PROTOCOL, "T.38"); } @@ -794,6 +864,18 @@ dissect_t38_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) col_append_fstr(pinfo->cinfo, COL_INFO, " [Malformed?]"); } } + + /* if is a valid t38 packet, add to tap */ + if (!pinfo->in_error_pkt) + tap_queue_packet(t38_tap, pinfo, t38_info); + else { /* if not, free the data */ + for (i=0; i<MAX_T38_DATA_ITEMS; i++) { + t38_info->data_type[i] = 0; + g_free(t38_info->data[i]); + t38_info->data[i] = NULL; + t38_info->data_len[i] = 0; + } + } } static void @@ -1037,6 +1119,8 @@ proto_register_t38(void) proto_register_subtree_array(ett, array_length(ett)); register_dissector("t38", dissect_t38, proto_t38); + t38_tap = register_tap("t38"); + t38_module = prefs_register_protocol(proto_t38, proto_reg_handoff_t38); prefs_register_bool_preference(t38_module, "use_pre_corrigendum_asn1_specification", "Use the Pre-Corrigendum ASN.1 specification", diff --git a/epan/dissectors/packet-t38.h b/epan/dissectors/packet-t38.h index 49b1421d18..e740643d27 100644 --- a/epan/dissectors/packet-t38.h +++ b/epan/dissectors/packet-t38.h @@ -25,6 +25,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define MAX_T38_DATA_ITEMS 4 +typedef struct _t38_packet_info { + guint16 seq_num; /* UDPTLPacket sequence number */ + guint32 type_msg; /* 0=t30-indicator 1=data */ + guint32 t30ind_value; + guint32 data_value; /* standard and speed */ + + int t38_info_data_item_index; /* this will have the number of Data Items in the packet and is used as the index when decoding the packet */ + guint32 data_type[MAX_T38_DATA_ITEMS]; + guint8 *data[MAX_T38_DATA_ITEMS]; + gint data_len[MAX_T38_DATA_ITEMS]; +} t38_packet_info; + + /* Info to save in T38 conversation / packet-info */ #define MAX_T38_SETUP_METHOD_SIZE 7 struct _t38_conversation_info @@ -38,3 +52,5 @@ void t38_add_address(packet_info *pinfo, address *addr, int port, int other_port, const gchar *setup_method, guint32 setup_frame_number); + +ETH_VAR_IMPORT const value_string t30_indicator_vals[]; diff --git a/epan/libethereal.def b/epan/libethereal.def index 797bb92280..b85c264a0b 100644 --- a/epan/libethereal.def +++ b/epan/libethereal.def @@ -557,6 +557,7 @@ stats_tree_reset stats_tree_tick_pivot stats_tree_tick_range string_to_name_resolve +t30_indicator_vals DATA T_h323_message_body_vals DATA tap_push_tapped_queue tap_queue_init diff --git a/gtk/Makefile.common b/gtk/Makefile.common index a6d934e1dd..e1393bde76 100644 --- a/gtk/Makefile.common +++ b/gtk/Makefile.common @@ -157,6 +157,7 @@ ETHEREAL_TAP_SRC = \ sctp_stat_dlg.c \ sip_stat.c \ smb_stat.c \ + t38_analysis.c \ tcp_graph.c \ voip_calls_dlg.c \ wsp_stat.c diff --git a/gtk/graph_analysis.c b/gtk/graph_analysis.c index 2e1e4a046b..624debaa7b 100644 --- a/gtk/graph_analysis.c +++ b/gtk/graph_analysis.c @@ -136,6 +136,8 @@ static void graph_analysis_init_dlg(graph_analysis_data_t* user_data) user_data->num_nodes = 0; user_data->num_items = 0; + user_data->on_destroy_user_data = NULL; + user_data->data = NULL; for (i=0; i<MAX_NUM_NODES; i++){ user_data->nodes[i].type = AT_NONE; user_data->nodes[i].len = 0; @@ -165,13 +167,14 @@ static void graph_analysis_init_dlg(graph_analysis_data_t* user_data) user_data->dlg.selected_item=0xFFFFFFFF; /*not item selected */ user_data->dlg.window=NULL; user_data->dlg.inverse = FALSE; + user_data->dlg.title=NULL; } /****************************************************************************/ /* CALLBACKS */ /****************************************************************************/ -/* close the dialog window and remove the tap listener */ +/* close the dialog window */ static void on_destroy(GtkWidget *win _U_, graph_analysis_data_t *user_data _U_) { int i; @@ -183,6 +186,12 @@ static void on_destroy(GtkWidget *win _U_, graph_analysis_data_t *user_data _U_) user_data->nodes[i].data = NULL; } user_data->dlg.window = NULL; + g_free(user_data->dlg.title); + user_data->dlg.title = NULL; + + if(user_data->on_destroy_user_data){ + user_data->on_destroy_user_data(user_data->data); + } } #define RIGHT_ARROW 1 @@ -649,7 +658,7 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data) top_y_border=TOP_Y_BORDER; /* to display the node address */ bottom_y_border=2; - draw_height=user_data->dlg.draw_area->allocation.height-top_y_border-bottom_y_border; + draw_height=user_data->dlg.draw_area->allocation.height-top_y_border-bottom_y_border; first_item = user_data->dlg.first_item; display_items = draw_height/ITEM_HEIGHT; @@ -734,7 +743,7 @@ static void dialog_graph_draw(graph_analysis_data_t* user_data) pango_layout_get_pixel_size(layout, &label_width, &label_height); #endif - /* resize the "time" draw area */ + /* resize the "time" draw area */ left_x_border=3; user_data->dlg.left_x_border = left_x_border; @@ -1359,8 +1368,8 @@ static gint configure_event(GtkWidget *widget, GdkEventConfigure *event _U_) gdk_gc_set_rgb_fg_color(user_data->dlg.bg_gc[i], &col[i]); #endif } - - dialog_graph_redraw(user_data); + + dialog_graph_redraw(user_data); return TRUE; } @@ -1429,6 +1438,7 @@ static gint configure_event_time(GtkWidget *widget, GdkEventConfigure *event _U_ dialog_graph_redraw(user_data); + return TRUE; } #if GTK_MAJOR_VERSION >= 2 @@ -1561,9 +1571,9 @@ static void create_draw_area(graph_analysis_data_t* user_data, GtkWidget *box) gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_time, FALSE, FALSE, 0); - user_data->dlg.hpane = gtk_hpaned_new(); - gtk_paned_pack1(GTK_PANED (user_data->dlg.hpane), user_data->dlg.scroll_window, FALSE, TRUE); - gtk_paned_pack2(GTK_PANED (user_data->dlg.hpane), scroll_window_comments, TRUE, TRUE); + user_data->dlg.hpane = gtk_hpaned_new(); + gtk_paned_pack1(GTK_PANED (user_data->dlg.hpane), user_data->dlg.scroll_window, FALSE, TRUE); + gtk_paned_pack2(GTK_PANED (user_data->dlg.hpane), scroll_window_comments, TRUE, TRUE); #if GTK_MAJOR_VERSION >= 2 SIGNAL_CONNECT(user_data->dlg.hpane, "notify::position", pane_callback, user_data); #endif @@ -1596,7 +1606,10 @@ static void dialog_graph_create_window(graph_analysis_data_t* user_data) GtkTooltips *tooltips = gtk_tooltips_new(); /* create the main window */ - user_data->dlg.window=window_new(GTK_WINDOW_TOPLEVEL, "Graph Analysis"); + if (user_data->dlg.title) + user_data->dlg.window=window_new(GTK_WINDOW_TOPLEVEL, user_data->dlg.title); + else + user_data->dlg.window=window_new(GTK_WINDOW_TOPLEVEL, "Graph Analysis"); vbox=gtk_vbox_new(FALSE, 0); @@ -1787,3 +1800,24 @@ void graph_analysis_update(graph_analysis_data_t* user_data) return; } + +/****************************************************************************/ +void graph_analysis_redraw(graph_analysis_data_t* user_data) +{ + /* get nodes (each node is an address) */ + get_nodes(user_data); + + user_data->dlg.pixmap_width = user_data->num_nodes * NODE_WIDTH; + WIDGET_SET_SIZE(user_data->dlg.draw_area, user_data->dlg.pixmap_width, user_data->dlg.pixmap_height); + if ( user_data->num_nodes < 6) + WIDGET_SET_SIZE(user_data->dlg.scroll_window, NODE_WIDTH*user_data->num_nodes, user_data->dlg.pixmap_height); + else + WIDGET_SET_SIZE(user_data->dlg.scroll_window, NODE_WIDTH*5, user_data->dlg.pixmap_height); + + + /* 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 index cc92a88fe8..508c149a28 100644 --- a/gtk/graph_analysis.h +++ b/gtk/graph_analysis.h @@ -104,9 +104,10 @@ typedef struct _dialog_data_t { display_items_t items[NUM_DISPLAY_ITEMS]; guint32 left_x_border; char *save_file; + char *title; /* Graph analysis window's title */ } dialog_data_t; - +typedef void (*destroy_user_data_cb)(void *data); /* structure that holds general information and the dialog */ typedef struct _graph_analysis_data_t { @@ -118,11 +119,14 @@ typedef struct _graph_analysis_data_t { address nodes[MAX_NUM_NODES]; guint32 num_nodes; guint32 num_items; + destroy_user_data_cb on_destroy_user_data; /* callback info for destroy */ + void *data; /* data to be passes when on destroy */ } graph_analysis_data_t; graph_analysis_data_t* graph_analysis_init(void); void graph_analysis_create(graph_analysis_data_t* user_data); void graph_analysis_update(graph_analysis_data_t* user_data); +void graph_analysis_redraw(graph_analysis_data_t* user_data); #endif /*GRAPH_ANALYSIS_H_INCLUDED*/ diff --git a/gtk/voip_calls.c b/gtk/voip_calls.c index 034828436e..56eea3c55c 100644 --- a/gtk/voip_calls.c +++ b/gtk/voip_calls.c @@ -168,6 +168,8 @@ void voip_calls_reset(voip_calls_tapinfo_t *tapinfo) graph_item = list->data; g_free(graph_item->frame_label); g_free(graph_item->comment); + g_free((void *)graph_item->src_addr.data); + g_free((void *)graph_item->dst_addr.data); g_free(list->data); list = g_list_next(list); } |