Warningfix:
[obnox/wireshark/wip.git] / gtk / sctp_chunk_stat_dlg.c
1 /* 
2  * Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24  
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28 #include <string.h>
29
30 #include <gtk/gtk.h>
31
32 #include "epan/filesystem.h"
33
34 #include "../globals.h"
35
36 #include "gtk/dlg_utils.h"
37 #include "gtk/gui_utils.h"
38 #include "gtk/main.h"
39 #include "gtk/sctp_stat.h"
40
41 static GtkWidget *sctp_chunk_stat_dlg=NULL;
42 static GtkWidget *clist = NULL;
43 static GList *last_list = NULL;
44 static sctp_assoc_info_t* selected_stream = NULL;  /* current selection */
45
46 #define NUM_COLS   14
47 #define FRAME_LIMIT 8
48
49 enum chunk_types {
50         DATA          = 0,
51         INIT          = 1,
52         INIT_ACK      = 2,
53         SACK          = 3,
54         HEARTBEAT     = 4,
55         HEARTBEAT_ACK = 5,
56         ABORT         = 6,
57         SHUTDOWN      = 7,
58         SHUTDOWN_ACK  = 8,
59         SCTP_ERROR    = 9,
60         COOKIE_ECHO   = 10,
61         COOKIE_ACK    = 11
62 };
63 enum
64 {
65    IP_ADDR_COLUMN,
66    DATA_COLUMN,
67    INIT_COLUMN,
68    INIT_ACK_COLUMN,
69    SACK_COLUMN,
70    HEARTBEAT_COLUMN,
71    HEARTBEAT_ACK_COLUMN,
72    ABORT_COLUMN,
73    SHUTDOWN_COLUMN,
74    SHUTDOWN_ACK_COLUMN,
75    ERROR_COLUMN,
76    COOKIE_ECHO_COLUMN,
77    COOKIE_ACK_COLUMN,
78    OTHERS_COLUMN,
79    N_COLUMN /* The number of columns */
80 };
81
82 /* Create list */
83 static
84 GtkWidget* create_list(void)
85 {
86
87     GtkListStore *list_store;
88     GtkWidget *list;
89     GtkTreeViewColumn *column;
90     GtkCellRenderer *renderer;
91     GtkTreeSortable *sortable;
92         GtkTreeView     *list_view;
93         GtkTreeSelection  *selection;
94
95         /* Create the store */
96     list_store = gtk_list_store_new(N_COLUMN,   /* Total number of columns XXX  */
97                                 G_TYPE_STRING,  /* IP Address                                   */
98                                 G_TYPE_INT,             /* DATA                                                 */
99                                                                 G_TYPE_INT,             /* INIT                                                 */
100                                                                 G_TYPE_INT,             /* INIT_ACK                                             */
101                                                                 G_TYPE_INT,             /* SACK                                                 */
102                                                                 G_TYPE_INT,             /* HEARTBEAT                                    */
103                                                                 G_TYPE_INT,             /* HEARTBEAT_ACK                                */
104                                                                 G_TYPE_INT,             /* ABORT                                                */
105                                                                 G_TYPE_INT,             /* SHUTDOWN                                             */
106                                                                 G_TYPE_INT,             /* SHUTDOWN_ACK                                 */
107                                                                 G_TYPE_INT,             /* ERROR                                                */
108                                                                 G_TYPE_INT,             /* COOKIE_ECHO                                  */
109                                                                 G_TYPE_INT,             /* COOKIE_ACK                                   */
110                                                                 G_TYPE_INT);    /* Others                                               */
111     /* Create a view */
112     list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
113
114         list_view = GTK_TREE_VIEW(list);
115         sortable = GTK_TREE_SORTABLE(list_store);
116
117 #if GTK_CHECK_VERSION(2,6,0)
118         /* Speed up the list display */
119         gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
120 #endif
121
122     /* Setup the sortable columns */
123     gtk_tree_sortable_set_sort_column_id(sortable, IP_ADDR_COLUMN, GTK_SORT_ASCENDING);
124     gtk_tree_view_set_headers_clickable(list_view, FALSE);
125
126     /* The view now holds a reference.  We can get rid of our own reference */
127     g_object_unref (G_OBJECT (list_store));
128
129     /* 
130          * Create the first column packet, associating the "text" attribute of the
131      * cell_renderer to the first column of the model 
132          */
133         /* 1:st column */
134         renderer = gtk_cell_renderer_text_new ();
135     column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, 
136                 "text", IP_ADDR_COLUMN, 
137                 NULL);
138
139         gtk_tree_view_column_set_sort_column_id(column, IP_ADDR_COLUMN);
140     gtk_tree_view_column_set_resizable(column, TRUE);
141     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
142     gtk_tree_view_column_set_min_width(column, 135);
143
144         /* Add the column to the view. */
145     gtk_tree_view_append_column (list_view, column);
146
147     /* 2:nd column... */
148     renderer = gtk_cell_renderer_text_new ();
149     column = gtk_tree_view_column_new_with_attributes ("DATA", renderer, 
150                 "text", DATA_COLUMN,
151                 NULL);
152     gtk_tree_view_column_set_sort_column_id(column, DATA_COLUMN);
153     gtk_tree_view_column_set_resizable(column, TRUE);
154     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
155     gtk_tree_view_column_set_min_width(column, 50);
156     gtk_tree_view_append_column (list_view, column);
157
158     /* 3:d column... */
159     renderer = gtk_cell_renderer_text_new ();
160     column = gtk_tree_view_column_new_with_attributes ("INIT", renderer, 
161                 "text", INIT_COLUMN,
162                 NULL);
163     gtk_tree_view_column_set_sort_column_id(column, INIT_COLUMN);
164     gtk_tree_view_column_set_resizable(column, TRUE);
165     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
166     gtk_tree_view_column_set_min_width(column, 50);
167     gtk_tree_view_append_column (list_view, column);
168
169     /* 4:th column... */
170     renderer = gtk_cell_renderer_text_new ();
171     column = gtk_tree_view_column_new_with_attributes ("INIT_ACK", renderer, 
172                 "text", INIT_ACK_COLUMN,
173                 NULL);
174     gtk_tree_view_column_set_sort_column_id(column, INIT_ACK_COLUMN);
175     gtk_tree_view_column_set_resizable(column, TRUE);
176     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
177     gtk_tree_view_column_set_min_width(column, 50);
178     gtk_tree_view_append_column (list_view, column);
179
180         /* 5:th column... */
181     renderer = gtk_cell_renderer_text_new ();
182     column = gtk_tree_view_column_new_with_attributes ("SACK", renderer, 
183                 "text", SACK_COLUMN,
184                 NULL);
185     gtk_tree_view_column_set_sort_column_id(column, SACK_COLUMN);
186     gtk_tree_view_column_set_resizable(column, TRUE);
187     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
188     gtk_tree_view_column_set_min_width(column, 35);
189     gtk_tree_view_append_column (list_view, column);
190
191     /* 6:th column... */
192     renderer = gtk_cell_renderer_text_new ();
193     column = gtk_tree_view_column_new_with_attributes ("HEARTBEAT", renderer, 
194                 "text", HEARTBEAT_COLUMN,
195                 NULL);
196     gtk_tree_view_column_set_sort_column_id(column, HEARTBEAT_COLUMN);
197     gtk_tree_view_column_set_resizable(column, TRUE);
198     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
199     gtk_tree_view_column_set_min_width(column, 60);
200     gtk_tree_view_append_column (list_view, column);
201
202     /* 7:th column... */
203     renderer = gtk_cell_renderer_text_new ();
204     column = gtk_tree_view_column_new_with_attributes ("HEARTBEAT_ACK", renderer, 
205                 "text", HEARTBEAT_ACK_COLUMN,
206                 NULL);
207     gtk_tree_view_column_set_sort_column_id(column, HEARTBEAT_ACK_COLUMN);
208     gtk_tree_view_column_set_resizable(column, TRUE);
209     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
210     gtk_tree_view_column_set_min_width(column, 90);
211     gtk_tree_view_append_column (list_view, column);
212
213     /* 8:th column... */
214     renderer = gtk_cell_renderer_text_new ();
215     column = gtk_tree_view_column_new_with_attributes ("ABORT", renderer, 
216                 "text", ABORT_COLUMN,
217                 NULL);
218     gtk_tree_view_column_set_sort_column_id(column, ABORT_COLUMN);
219     gtk_tree_view_column_set_resizable(column, TRUE);
220     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
221     gtk_tree_view_column_set_min_width(column, 40);
222     gtk_tree_view_append_column (list_view, column);
223
224
225     /* 9:th column... */
226     renderer = gtk_cell_renderer_text_new ();
227     column = gtk_tree_view_column_new_with_attributes ("SHUTDOWN", renderer, 
228                 "text", SHUTDOWN_COLUMN,
229                 NULL);
230     gtk_tree_view_column_set_sort_column_id(column, SHUTDOWN_COLUMN);
231     gtk_tree_view_column_set_resizable(column, TRUE);
232     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
233     gtk_tree_view_column_set_min_width(column, 65);
234     gtk_tree_view_append_column (list_view, column);
235
236     /* 10:th column... */
237     renderer = gtk_cell_renderer_text_new ();
238     column = gtk_tree_view_column_new_with_attributes ("SHUTDOWN_ACK", renderer, 
239                 "text", SHUTDOWN_ACK_COLUMN,
240                 NULL);
241     gtk_tree_view_column_set_sort_column_id(column, SHUTDOWN_ACK_COLUMN);
242     gtk_tree_view_column_set_resizable(column, TRUE);
243     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
244     gtk_tree_view_column_set_min_width(column, 90);
245     gtk_tree_view_append_column (list_view, column);
246
247     /* 11:th column... */
248     renderer = gtk_cell_renderer_text_new ();
249     column = gtk_tree_view_column_new_with_attributes ("ERROR", renderer, 
250                 "text", ERROR_COLUMN,
251                 NULL);
252     gtk_tree_view_column_set_sort_column_id(column, ERROR_COLUMN);
253     gtk_tree_view_column_set_resizable(column, TRUE);
254     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
255     gtk_tree_view_column_set_min_width(column, 40);
256     gtk_tree_view_append_column (list_view, column);
257
258     /* 12:th column... */
259     renderer = gtk_cell_renderer_text_new ();
260     column = gtk_tree_view_column_new_with_attributes ("COOKIE_ECHO", renderer, 
261                 "text", COOKIE_ECHO,
262                 NULL);
263     gtk_tree_view_column_set_sort_column_id(column, COOKIE_ECHO_COLUMN);
264     gtk_tree_view_column_set_resizable(column, TRUE);
265     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
266     gtk_tree_view_column_set_min_width(column, 80);
267     gtk_tree_view_append_column (list_view, column);
268
269     /* 13:th column... */
270     renderer = gtk_cell_renderer_text_new ();
271     column = gtk_tree_view_column_new_with_attributes ("COOKIE_ACK", renderer, 
272                 "text", COOKIE_ACK_COLUMN,
273                 NULL);
274     gtk_tree_view_column_set_sort_column_id(column, COOKIE_ACK_COLUMN);
275     gtk_tree_view_column_set_resizable(column, TRUE);
276     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
277     gtk_tree_view_column_set_min_width(column, 80);
278     gtk_tree_view_append_column (list_view, column);
279
280     /* 14:th column... */
281     renderer = gtk_cell_renderer_text_new ();
282     column = gtk_tree_view_column_new_with_attributes ("Others", renderer, 
283                 "text", OTHERS_COLUMN,
284                 NULL);
285     gtk_tree_view_column_set_sort_column_id(column, OTHERS_COLUMN);
286     gtk_tree_view_column_set_resizable(column, TRUE);
287     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
288     gtk_tree_view_column_set_min_width(column, 35);
289     gtk_tree_view_append_column (list_view, column);
290
291         /* Now enable the sorting of each column */
292     gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
293     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
294
295         /* Setup the selection handler */
296         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
297         gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
298
299         return list;
300
301 }
302
303 static const char *chunk_name(int type)
304 {
305 #define CASE(x) case x: s=#x; break
306         const char *s = "unknown";
307         switch (type)
308         {
309                 CASE(DATA);
310                 CASE(INIT);
311                 CASE(INIT_ACK);
312                 CASE(SACK);
313                 CASE(HEARTBEAT);
314                 CASE(HEARTBEAT_ACK);
315                 CASE(ABORT);
316                 CASE(SHUTDOWN);
317                 CASE(SHUTDOWN_ACK);
318                 CASE(SCTP_ERROR);
319                 CASE(COOKIE_ECHO);
320                 CASE(COOKIE_ACK);
321         }
322         return s;
323 }
324
325 typedef struct column_arrows {
326         GtkWidget *table;
327         GtkWidget *ascend_pm;
328         GtkWidget *descend_pm;
329 } column_arrows;
330
331
332 static void
333 chunk_dlg_destroy(GtkObject *object _U_, gpointer user_data)
334 {
335         struct sctp_udata *u_data=(struct sctp_udata*)user_data;
336         decrease_childcount(u_data->parent);
337         remove_child(u_data, u_data->parent);
338         g_free(u_data->io);
339         g_free(u_data);
340 }
341
342 static void
343 on_destroy(GtkObject *object _U_, gpointer user_data)
344 {
345         struct sctp_udata *u_data=(struct sctp_udata*)user_data;
346         decrease_childcount(u_data->parent);
347         remove_child(u_data, u_data->parent);
348         g_free(u_data->io);
349         g_free(u_data);
350 }
351
352
353 static void add_to_clist(sctp_addr_chunk* sac)
354 {
355     GtkListStore *list_store = NULL;
356         GtkTreeIter  iter;
357         gchar field[1][MAX_ADDRESS_LEN];
358
359         list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (clist))); /* Get store */
360                 
361         if (sac->addr->type==AT_IPv4)
362         {
363                 g_snprintf(field[0], MAX_ADDRESS_LEN, "%s", ip_to_str((const guint8 *)(sac->addr->data)));
364         }
365         else if (sac->addr->type==AT_IPv6)
366         {
367                 g_snprintf(field[0], MAX_ADDRESS_LEN, "%s", ip6_to_str((const struct e_in6_addr *)(sac->addr->data)));
368         }
369
370 #if GTK_CHECK_VERSION(2,6,0)
371         gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
372 #else
373         gtk_list_store_append  (list_store, &iter);
374         gtk_list_store_set  (list_store, &iter,
375 #endif
376            IP_ADDR_COLUMN,              field[0],
377            DATA_COLUMN,                 sac->addr_count[0],
378            INIT_COLUMN,                 sac->addr_count[1],
379            INIT_ACK_COLUMN,             sac->addr_count[2],
380            SACK_COLUMN,                 sac->addr_count[3],
381            HEARTBEAT_COLUMN,    sac->addr_count[4],
382            HEARTBEAT_ACK_COLUMN,sac->addr_count[5],
383            ABORT_COLUMN,                sac->addr_count[6],
384            SHUTDOWN_COLUMN,             sac->addr_count[7],
385            SHUTDOWN_ACK_COLUMN, sac->addr_count[8],
386            ERROR_COLUMN,                sac->addr_count[9],
387            COOKIE_ECHO_COLUMN,  sac->addr_count[10],
388            COOKIE_ACK_COLUMN,   sac->addr_count[11],
389            OTHERS_COLUMN,               sac->addr_count[12],
390            -1);
391 }
392
393 void sctp_chunk_stat_dlg_update(struct sctp_udata* udata, unsigned int direction)
394 {
395         GList *list=NULL;
396         sctp_addr_chunk* sac;
397
398         if (udata->io->window != NULL)
399         {
400                 gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(clist))));
401                 if (udata->assoc->addr_chunk_count!=NULL)
402                 {
403                         list = g_list_first(udata->assoc->addr_chunk_count);
404         
405                         while (list)
406                         {
407                                 sac = (sctp_addr_chunk*)(list->data);
408                                 if (sac->direction==direction)
409                                 {
410                                         add_to_clist(sac);
411                                         list = g_list_next(list);
412                                 }
413                                 else
414                                         list = g_list_next(list);
415                         }
416                 }
417         }
418         last_list = list;
419 }
420
421
422
423 static void
424 sctp_chunk_stat_on_close (GtkButton *button _U_, gpointer         user_data)
425 {
426         struct sctp_udata *udata;
427
428         udata = (struct sctp_udata *)user_data;
429         gtk_grab_remove(udata->io->window);
430         gtk_widget_destroy(udata->io->window);
431 }
432
433 static void
434 on_close_dlg (GtkButton *button _U_, gpointer user_data)
435 {
436         struct sctp_udata *udata;
437
438         udata = (struct sctp_udata *)user_data;
439         gtk_grab_remove(udata->io->window);
440         gtk_widget_destroy(udata->io->window);
441 }
442
443
444 static void path_window_set_title(struct sctp_udata *u_data, unsigned int direction)
445 {
446         char *title;
447         if(!u_data->io->window){
448                 return;
449         }
450         title = g_strdup_printf("SCTP Path Chunk Statistics for Endpoint %u: %s Port1 %u  Port2 %u",direction,
451                                 cf_get_display_name(&cfile), u_data->assoc->port1, u_data->assoc->port2);
452         gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
453         g_free(title);
454 }
455
456 static void
457 gtk_sctpstat_dlg(struct sctp_udata *u_data, unsigned int direction)
458 {
459         GtkWidget *vbox1;
460         GtkWidget *scrolledwindow1;
461         GtkWidget *hbuttonbox2;
462         GtkWidget *bt_close;
463
464
465         sctp_graph_t* io=g_malloc(sizeof(sctp_graph_t));
466         io->window=NULL;
467         u_data->io=io;
468         u_data->io->window= gtk_window_new (GTK_WINDOW_TOPLEVEL);
469         gtk_window_set_default_size(GTK_WINDOW(u_data->io->window), 600, 300);
470         gtk_window_set_position (GTK_WINDOW (u_data->io->window), GTK_WIN_POS_CENTER);
471         path_window_set_title(u_data, direction);
472         g_signal_connect(u_data->io->window, "destroy", G_CALLBACK(chunk_dlg_destroy), u_data);
473
474         /* Container for each row of widgets */
475         vbox1 = gtk_vbox_new(FALSE, 2);
476         gtk_container_set_border_width(GTK_CONTAINER(vbox1), 8);
477         gtk_container_add(GTK_CONTAINER(u_data->io->window), vbox1);
478         gtk_widget_show(vbox1);
479
480         scrolledwindow1 = scrolled_window_new (NULL, NULL);
481         gtk_widget_show (scrolledwindow1);
482         gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0);
483
484         clist = create_list();
485         gtk_widget_show (clist);
486         gtk_container_add (GTK_CONTAINER (scrolledwindow1), clist);
487
488         gtk_widget_show(u_data->io->window);
489
490
491         hbuttonbox2 = gtk_hbutton_box_new();
492         gtk_box_pack_start(GTK_BOX(vbox1), hbuttonbox2, FALSE, FALSE, 0);
493         gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox2), 10);
494         gtk_button_box_set_layout(GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_SPREAD);
495         gtk_box_set_spacing(GTK_BOX (hbuttonbox2), 0);
496         gtk_widget_show(hbuttonbox2);
497
498         bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
499         gtk_container_add (GTK_CONTAINER (hbuttonbox2), bt_close);
500         gtk_widget_show (bt_close);
501
502         g_signal_connect(bt_close, "clicked", G_CALLBACK(sctp_chunk_stat_on_close), u_data);
503
504         cf_retap_packets(&cfile, FALSE);
505
506 }
507
508
509 static void chunk_window_set_title(struct sctp_udata *u_data)
510 {
511         char *title;
512         if(!u_data->io->window){
513                 return;
514         }
515         title = g_strdup_printf("SCTP Association Chunk Statistics: %s Port1 %u  Port2 %u",
516                                 cf_get_display_name(&cfile), u_data->assoc->port1, u_data->assoc->port2);
517         gtk_window_set_title(GTK_WINDOW(u_data->io->window), title);
518         g_free(title);
519 }
520
521 static void sctp_chunk_dlg(struct sctp_udata *u_data)
522 {
523         GtkWidget *main_vb, *table;
524         GtkWidget *label, *h_button_box;
525         GtkWidget *close_bt;
526         gchar label_txt[50];
527         int i, row;
528         
529         sctp_graph_t* io=g_malloc(sizeof(sctp_graph_t));
530         io->window=NULL;
531         u_data->io=io;
532         u_data->io->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
533         gtk_window_set_position (GTK_WINDOW (u_data->io->window), GTK_WIN_POS_CENTER);
534         gtk_widget_set_size_request(u_data->io->window, 500, 400);
535         g_signal_connect(u_data->io->window, "destroy", G_CALLBACK(on_destroy), u_data);
536
537         /* Container for each row of widgets */
538         main_vb = gtk_vbox_new(FALSE, 12);
539         gtk_container_set_border_width(GTK_CONTAINER(main_vb), 12);
540         gtk_container_add(GTK_CONTAINER(u_data->io->window), main_vb);
541          
542          /* table */
543         table = gtk_table_new(1, 4, FALSE);
544         gtk_table_set_col_spacings(GTK_TABLE(table), 6);
545         gtk_table_set_row_spacings(GTK_TABLE(table), 3);
546         gtk_container_add(GTK_CONTAINER(main_vb), table);
547         row = 0;
548                         
549         label = gtk_label_new("ChunkType");
550         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
551         gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, row, row+1);   
552         label = gtk_label_new("Association");
553         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
554         gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, row, row+1);
555         label = gtk_label_new("Endpoint 1");
556         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
557         gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, row, row+1);
558         label = gtk_label_new("Endpoint 2");
559         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
560         gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, row, row+1);
561         row ++;
562         label = gtk_label_new("");
563         gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, row, row+1);   
564         label = gtk_label_new("");
565         gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, row, row+1);
566         label = gtk_label_new("");
567         gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, row, row+1);
568         label = gtk_label_new("");
569         gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, row, row+1);
570         row ++;
571
572         for (i=0; i<NUM_CHUNKS-1; i++)
573         {
574                 label = gtk_label_new(chunk_name(i));
575                 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
576                 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, row, row+1);   
577                 g_snprintf(label_txt, 10, "%u", selected_stream->chunk_count[i]);
578                 label = gtk_label_new(label_txt);
579                 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
580                 gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, row, row+1);
581                 g_snprintf(label_txt, 10, "%u", selected_stream->ep1_chunk_count[i]);
582                 label = gtk_label_new(label_txt);
583                 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
584                 gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, row, row+1);
585                 g_snprintf(label_txt, 10, "%u", selected_stream->ep2_chunk_count[i]);
586                 label = gtk_label_new(label_txt);
587                 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
588                 gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, row, row+1);
589                 row ++;
590         }
591         
592         label = gtk_label_new("Others");
593         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
594         gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, row, row+1);
595         g_snprintf(label_txt, 10, "%u", selected_stream->chunk_count[12]);
596         label = gtk_label_new(label_txt);
597         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
598         gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, row, row+1);
599         g_snprintf(label_txt, 10, "%u", selected_stream->ep1_chunk_count[12]);
600         label = gtk_label_new(label_txt);
601         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
602         gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, row, row+1);
603         g_snprintf(label_txt, 10, "%u", selected_stream->ep2_chunk_count[12]);
604         label = gtk_label_new(label_txt);
605         gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
606         gtk_table_attach_defaults(GTK_TABLE(table), label, 3, 4, row, row+1);
607         
608         h_button_box=gtk_hbutton_box_new();
609         gtk_box_pack_start(GTK_BOX(main_vb), h_button_box, FALSE, FALSE, 0);
610         gtk_container_set_border_width(GTK_CONTAINER(h_button_box), 10);
611         gtk_button_box_set_layout(GTK_BUTTON_BOX (h_button_box), GTK_BUTTONBOX_SPREAD);
612         gtk_box_set_spacing(GTK_BOX (h_button_box), 0);
613         gtk_widget_show(h_button_box);
614         
615         close_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
616         gtk_box_pack_start(GTK_BOX(h_button_box), close_bt, FALSE, FALSE, 0);
617         gtk_widget_show(close_bt);
618         g_signal_connect(close_bt, "clicked", G_CALLBACK(on_close_dlg), u_data);
619         
620         gtk_widget_show_all(u_data->io->window);
621         chunk_window_set_title(u_data);
622 }
623
624 void sctp_chunk_dlg_show(struct sctp_analyse* userdata)
625 {
626         gint i;
627         struct sctp_udata *u_data;
628
629         u_data=g_malloc(sizeof(struct sctp_udata));
630         u_data->assoc=g_malloc(sizeof(sctp_assoc_info_t));
631         u_data->assoc=userdata->assoc;
632         u_data->io=NULL;
633         u_data->parent = userdata;
634
635         if (selected_stream==NULL)
636                 selected_stream=g_malloc(sizeof(sctp_assoc_info_t));
637
638         selected_stream=u_data->assoc;
639         for (i=0; i<NUM_CHUNKS; i++)
640         {
641                 selected_stream->chunk_count[i]=u_data->assoc->chunk_count[i];
642         }
643         set_child(u_data, u_data->parent);
644         increase_childcount(u_data->parent);
645         sctp_chunk_dlg(u_data);
646 }
647
648 void sctp_chunk_stat_dlg_show(unsigned int direction, struct sctp_analyse* userdata)
649 {
650         struct sctp_udata *u_data;
651
652         u_data=g_malloc(sizeof(struct sctp_udata));
653         u_data->assoc=g_malloc(sizeof(sctp_assoc_info_t));
654         u_data->assoc=userdata->assoc;
655         u_data->io=NULL;
656         u_data->parent = userdata;
657         
658         if (selected_stream==NULL)
659                 selected_stream=g_malloc(sizeof(sctp_assoc_info_t));
660         selected_stream=u_data->assoc;
661         selected_stream->addr_chunk_count=u_data->assoc->addr_chunk_count;
662
663         set_child(u_data, u_data->parent);
664         increase_childcount(u_data->parent);
665         gtk_sctpstat_dlg(u_data, direction);
666         sctp_chunk_stat_dlg_update(u_data,direction);
667 }
668
669 GtkWidget* get_chunk_stat_dlg(void)
670 {
671         return sctp_chunk_stat_dlg;
672 }