Rename "register_ethereal_tap()" to "register_tap_listener_cmd_arg()" as
[obnox/wireshark/wip.git] / gtk / sctp_stat.c
1 /* 
2  * Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
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
29 #include <stdio.h>
30 #include <gtk/gtk.h>
31 #include "simple_dialog.h"      /* Both is used for error handling */
32 #include "globals.h"
33 #include "epan/packet_info.h"   /* Needed for packet_info */
34 #include <epan/tap.h>           /* Needed for register_tap_listener */
35 #include "tap_menu.h"
36 #include "dlg_utils.h"
37 #include "compat_macros.h"
38 #include "register.h"
39 #include <string.h>
40 #include "sctp_stat.h"
41 #include <math.h>
42 #include "epan/address.h"
43
44 #define SCTP_HEARTBEAT_CHUNK_ID          4
45 #define SCTP_HEARTBEAT_ACK_CHUNK_ID      5
46 #define SCTP_ABORT_CHUNK_ID              6
47 #define SCTP_SHUTDOWN_CHUNK_ID           7
48 #define SCTP_SHUTDOWN_ACK_CHUNK_ID       8
49 #define SCTP_ERROR_CHUNK_ID              9
50 #define SCTP_COOKIE_ECHO_CHUNK_ID       10
51 #define SCTP_COOKIE_ACK_CHUNK_ID        11
52 #define SCTP_ECNE_CHUNK_ID              12
53 #define SCTP_CWR_CHUNK_ID               13
54 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
55 #define SCTP_FORWARD_TSN_CHUNK_ID      192
56 #define SCTP_ASCONF_ACK_CHUNK_ID      0x80
57 #define SCTP_PKTDROP_CHUNK_ID         0X81
58 #define SCTP_ASCONF_CHUNK_ID          0XC1
59 #define SCTP_IETF_EXT                  255
60
61 #define SCTP_ABORT_CHUNK_T_BIT        0x01
62
63 #define PARAMETER_TYPE_LENGTH            2
64 #define PARAMETER_LENGTH_LENGTH          2
65 #define PARAMETER_HEADER_LENGTH          (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
66
67 #define PARAMETER_HEADER_OFFSET          0
68 #define PARAMETER_TYPE_OFFSET            PARAMETER_HEADER_OFFSET
69 #define PARAMETER_LENGTH_OFFSET          (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
70 #define PARAMETER_VALUE_OFFSET           (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
71
72 #define IPV6_ADDRESS_LENGTH 16
73 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
74 #define IPV4_ADDRESS_LENGTH 4
75 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
76 #define IPV4ADDRESS_PARAMETER_ID             0x0005
77 #define IPV6ADDRESS_PARAMETER_ID             0x0006
78
79 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH    4
80 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
81 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
82 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
83                                                  SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
84
85 #define INIT_CHUNK_INITIAL_TSN_LENGTH                4
86 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH            (INIT_CHUNK_INITIATE_TAG_LENGTH + \
87                                                       INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
88                                                       INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
89                                                       INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
90                                                       INIT_CHUNK_INITIAL_TSN_LENGTH)    
91 #define CHUNK_HEADER_LENGTH           (CHUNK_TYPE_LENGTH + \
92                                        CHUNK_FLAGS_LENGTH + \
93                                        CHUNK_LENGTH_LENGTH)
94 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET  (INIT_CHUNK_INITIAL_TSN_OFFSET + \
95                                                       INIT_CHUNK_INITIAL_TSN_LENGTH ) 
96
97 static const value_string chunk_type_values[] = {
98   { SCTP_DATA_CHUNK_ID,              "DATA" },
99   { SCTP_INIT_CHUNK_ID,              "INIT" },
100   { SCTP_INIT_ACK_CHUNK_ID,          "INIT_ACK" },
101   { SCTP_SACK_CHUNK_ID,              "SACK" },
102   { SCTP_HEARTBEAT_CHUNK_ID,         "HEARTBEAT" },
103   { SCTP_HEARTBEAT_ACK_CHUNK_ID,     "HEARTBEAT_ACK" },
104   { SCTP_ABORT_CHUNK_ID,             "ABORT" },
105   { SCTP_SHUTDOWN_CHUNK_ID,          "SHUTDOWN" },
106   { SCTP_SHUTDOWN_ACK_CHUNK_ID,      "SHUTDOWN_ACK" },
107   { SCTP_ERROR_CHUNK_ID,             "ERROR" },
108   { SCTP_COOKIE_ECHO_CHUNK_ID,       "COOKIE_ECHO" },
109   { SCTP_COOKIE_ACK_CHUNK_ID,        "COOKIE_ACK" },
110   { SCTP_ECNE_CHUNK_ID,              "ECNE" },
111   { SCTP_CWR_CHUNK_ID,               "CWR" },
112   { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
113   { SCTP_FORWARD_TSN_CHUNK_ID,       "FORWARD TSN" },
114   { SCTP_ASCONF_ACK_CHUNK_ID,        "ASCONF_ACK" },
115   { SCTP_PKTDROP_CHUNK_ID,           "PKTDROP" },
116   { SCTP_ASCONF_CHUNK_ID,            "ASCONF" },
117   { SCTP_IETF_EXT,                   "IETF_EXTENSION" },
118   { 0,                               NULL } };
119
120
121 #define FORWARD_STREAM                     0
122 #define BACKWARD_STREAM                    1
123 #define FORWARD_ADD_FORWARD_VTAG           2
124 #define BACKWARD_ADD_FORWARD_VTAG          3
125 #define BACKWARD_ADD_BACKWARD_VTAG         4
126 #define ADDRESS_FORWARD_STREAM             5
127 #define ADDRESS_BACKWARD_STREAM            6
128 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG   7
129 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG  8
130 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
131 #define ASSOC_NOT_FOUND                    10
132
133 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
134
135 static
136 void free_first(gpointer data, gpointer user_data _U_)
137 {
138         g_free(data);
139 }
140
141 void tsn_free(gpointer data, gpointer user_data _U_)
142 {
143         tsn_t *tsn;
144
145         tsn = (tsn_t *) data;
146         if (tsn->tsns != NULL)
147         {
148                 g_list_foreach(tsn->tsns, free_first, NULL);
149                 g_list_free(tsn->tsns);
150                 tsn->tsns=NULL;
151         }
152 }
153
154 static void
155 reset(void *arg)
156 {
157         sctp_allassocs_info_t *tapdata = arg;
158         GList* list;
159         sctp_assoc_info_t * info;
160
161         list = g_list_first(tapdata->assoc_info_list);
162         while (list)
163         {
164                 info = (sctp_assoc_info_t *) (list->data);
165
166                 if (info->addr1 != NULL)
167                 {
168                         g_list_foreach(info->addr1, free_first, NULL);
169                         g_list_free(info->addr1);
170                         info->addr1 = NULL;
171                 }
172
173                 if (info->addr2 != NULL)
174                 {
175                         g_list_foreach(info->addr2,free_first, NULL);
176                         g_list_free(info->addr2);
177                         info->addr2 = NULL;
178                 }
179
180                 if (info->error_info_list != NULL)
181                 {
182                         g_list_foreach(info->error_info_list, free_first, NULL);
183                         g_list_free(info->error_info_list);
184                         info->error_info_list = NULL;
185                 }
186
187                 if (info->frame_numbers != NULL)
188                 {
189                         g_list_free(info->frame_numbers);
190                         info->frame_numbers = NULL;
191                 }
192
193                 if (info->tsn1 != NULL)
194                 {
195                         g_list_foreach(info->tsn1, tsn_free, NULL);
196                         g_list_free(info->tsn1);
197                         info->tsn1 = NULL;
198                 }
199
200                 if (info->tsn2 != NULL)
201                 {
202                         g_list_foreach(info->tsn2, tsn_free, NULL);
203                         g_list_free(info->tsn2);
204                         info->tsn2 = NULL;
205                 }
206
207                 if (info->sack1 != NULL)
208                 {
209                         g_list_foreach(info->sack1, tsn_free, NULL);
210                         g_list_free(info->sack1);
211                         info->sack1 = NULL;
212                 }
213
214                 if (info->sack2 != NULL)
215                 {
216                         g_list_foreach(info->sack2, tsn_free, NULL);
217                         g_list_free(info->sack2);
218                         info->sack2 = NULL;
219                 }
220
221                 if (info->sort_tsn1 != NULL)
222                         g_ptr_array_free(info->sort_tsn1, TRUE);
223
224                 if (info->sort_tsn2 != NULL)
225                         g_ptr_array_free(info->sort_tsn2, TRUE);
226
227                 if (info->sort_sack1 != NULL)
228                         g_ptr_array_free(info->sort_sack1, TRUE);
229
230                 if (info->sort_sack2 != NULL)
231                         g_ptr_array_free(info->sort_sack2, TRUE);
232
233                 if (info->min_max != NULL)
234                 {
235                         g_slist_foreach(info->min_max, free_first, NULL);
236                         info->min_max = NULL;
237                 }
238
239                 g_free(list->data);
240                 list = g_list_next(list);
241         }
242         g_list_free(tapdata->assoc_info_list);
243         tapdata->sum_tvbs = 0;
244         tapdata->assoc_info_list = NULL;
245 }
246
247
248 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
249 {
250         gboolean ok = FALSE;
251
252         if (check_data->adler32_calculated)
253         {
254                 data->n_adler32_calculated++;
255                 if (check_data->adler32_correct)
256                         data->n_adler32_correct++;
257         }
258         if (check_data->crc32c_calculated)
259         {
260                 data->n_crc32c_calculated++;
261                 if (check_data->crc32c_correct)
262                         data->n_crc32c_correct++;
263         }
264         if (data->n_adler32_calculated > 0)
265         {
266                 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
267                 {
268                         strcpy(data->checksum_type,"ADLER32");
269                         data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
270                         ok = TRUE;
271                 }
272         }
273
274         if (data->n_crc32c_calculated>0)
275         {
276                 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
277                 {
278                         strcpy(data->checksum_type,"CRC32C");
279                         data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
280                         ok = TRUE;
281                 }
282         }
283
284         if (!ok)
285         {
286                 strcpy(data->checksum_type,"UNKNOWN");
287                 data->n_checksum_errors=0;
288         }
289
290         return(data);
291
292 }
293
294
295 gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
296 {
297
298         const struct _sctp_assoc_info* a = aa;
299         const struct _sctp_assoc_info* b = bb;
300
301         if (a == b)
302                 return(0);
303
304         if (a == NULL || b == NULL)
305                 return(1);
306
307         /* assoc known*/
308         if ((a->port1 == b->port1) &&
309             (a->port2 == b->port2) &&
310             (a->verification_tag1 == b->verification_tag1) &&
311             ((a->verification_tag1 != 0 || 
312              (b->verification_tag2 != 0))))
313                 return(FORWARD_STREAM);
314
315         if ((a->port1 == b->port2) &&
316             (a->port2 == b->port1) &&
317             (a->verification_tag1 == b->verification_tag2))
318                 return(BACKWARD_STREAM);
319
320         /*forward stream verifivation tag can be added*/
321         if ((a->port1 == b->port1) &&
322             (a->port2 == b->port2) &&
323             (a->verification_tag1 != 0) &&
324             (b->verification_tag1 == 0) &&
325             (b->verification_tag2 !=0))
326                 return (FORWARD_ADD_FORWARD_VTAG);
327                 
328         if ((a->port1 == b->port2) &&
329             (a->port2 == b->port1) &&
330             (a->verification_tag1 == b->verification_tag2) &&
331             (b->verification_tag1 == 0))
332                 return (BACKWARD_ADD_FORWARD_VTAG);
333                 
334         /*backward stream verification tag can be added */
335         if ((a->port1 == b->port2) &&
336             (a->port2 == b->port1) &&
337             (a->verification_tag1 !=0) &&
338             (b->verification_tag1 != 0) &&
339             (b->verification_tag2 == 0))
340                 return(BACKWARD_ADD_BACKWARD_VTAG);
341
342         return(ASSOC_NOT_FOUND);
343 }
344
345
346 gint sctp_assoc_address_cmp(gconstpointer aa, gconstpointer bb)
347 {
348         GList *srclist, *dstlist;
349         const struct _sctp_tmp_info* a = aa;
350         const struct _sctp_assoc_info* b = bb;
351         address *srcstore=NULL;
352         address *dststore=NULL;
353         address *src=NULL;
354         address *dst=NULL;
355         gboolean src_v4=FALSE;
356         gboolean src_v6=FALSE;
357         gboolean dst_v4=FALSE;
358         gboolean dst_v6=FALSE;
359         guint8* addr;
360
361         src = g_malloc(sizeof(address));
362         if (a->src.type == AT_IPv4)
363         {
364                 src->type = AT_IPv4;
365                 src->len  = 4;
366                 src_v4    = TRUE;
367         }
368         else if (a->src.type==AT_IPv6)
369         {
370                 src->type = AT_IPv6;
371                 src->len  = 16;
372                 src_v6    = TRUE;
373         }
374         addr = g_malloc(src->len);
375         memcpy(addr, a->src.data, src->len);
376         src->data = addr;
377
378         dst = g_malloc(sizeof(address));
379         if (a->dst.type == AT_IPv4)
380         {
381                 dst->type = AT_IPv4;
382                 dst->len  = 4;
383                 dst_v4    = TRUE;
384         }
385         else if (a->dst.type==AT_IPv6)
386         {
387                 dst->type = AT_IPv6;
388                 dst->len  = 16;
389                 dst_v6    = TRUE;
390         }
391         addr = g_malloc(dst->len);
392         memcpy(addr, a->dst.data, dst->len);
393         dst->data = addr;
394
395         srclist = g_list_first(b->addr1);
396         while (srclist)
397         {
398                 srcstore = (address *) (srclist->data);
399                 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
400                 {
401                         if (*src->data==*srcstore->data && a->port1 == b->port1)
402                         {
403                                 dstlist = g_list_first(b->addr2);
404                                 while (dstlist)
405                                 {
406                                                 dststore = (address *) (dstlist->data);
407                                                 if ((dststore->type==AT_IPv4 && dst_v4==TRUE) ||(dststore->type==AT_IPv6 && dst_v6==TRUE) )
408                                                 {
409                                                         if (*dst->data==*dststore->data && a->port2 == b->port2)
410                                                         {
411                                                                 if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
412                                                                         return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
413                                                                 else
414                                                                         return ADDRESS_FORWARD_STREAM;
415                                                         }
416                                                         else
417                                                                 dstlist=g_list_next(dstlist);
418                                                 }
419                                                 else
420                                                         dstlist=g_list_next(dstlist);
421                                 }
422                                 srclist=g_list_next(srclist);
423                         }
424                         else
425                                 srclist=g_list_next(srclist);
426                 }
427                 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
428                 {
429                         if (*src->data == *srcstore->data  && a->port1 == b->port1)
430                         {
431                                 dstlist = g_list_first(b->addr2);
432                                 while (dstlist)
433                                 {
434                                         dststore = (address *) (dstlist->data);
435                                         if ((dststore->type==AT_IPv4 && dst_v4==TRUE) || (dststore->type==AT_IPv6 && dst_v6==TRUE))
436                                         {
437                                                 if (*dst->data==*dststore->data && a->port2 == b->port2)
438                                                 {
439                                                         if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
440                                                                 return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
441                                                         else
442                                                                 return ADDRESS_FORWARD_STREAM;
443                                                 }
444                                                 else
445                                                         dstlist=g_list_next(dstlist);
446                                         }
447                                         else
448                                                 dstlist=g_list_next(dstlist);
449                                 }
450                                 srclist=g_list_next(srclist);
451                         }
452                         else
453                                 srclist=g_list_next(srclist);
454                 }
455                 else
456                         srclist=g_list_next(srclist);
457         }
458
459         g_free(src);
460         g_free(dst);
461
462         src = g_malloc(sizeof(address));
463         if (a->dst.type == AT_IPv4)
464         {
465                 src->type = AT_IPv4;
466                 src->len  = 4;
467                 src_v4    = TRUE;
468         }
469         else if (a->dst.type==AT_IPv6)
470         {
471                 src->type = AT_IPv6;
472                 src->len  = 16;
473                 src_v6    = TRUE;
474         }
475         addr = g_malloc(src->len);
476         memcpy(addr, a->dst.data, src->len);
477         src->data = addr;
478         
479         dst = g_malloc(sizeof(address));
480         if (a->src.type == AT_IPv4)
481         {
482                 dst->type = AT_IPv4;
483                 dst->len  = 4;
484                 dst_v4    = TRUE;
485         }
486         else if (a->src.type==AT_IPv6)
487         {
488                 dst->type = AT_IPv6;
489                 dst->len  = 16;
490                 dst_v6    = TRUE;
491         }
492         addr = g_malloc(dst->len);
493         memcpy(addr, a->src.data, dst->len);
494         dst->data = addr;
495         
496         srclist = g_list_first(b->addr1);
497         while (srclist)
498         {
499                 srcstore = (address *) (srclist->data);
500                 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
501                 {
502                         if (*src->data==*srcstore->data && a->port2 == b->port1)
503                         {
504                                 dstlist = g_list_first(b->addr2);
505                                 while (dstlist)
506                                 {
507                                                 dststore = (address *) (dstlist->data);
508                                                 if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
509                                                 {
510                                                         if (*dst->data==*dststore->data && a->port1 == b->port2)
511                                                         {
512                                                                 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
513                                                                         return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
514                                                                 else if ((a->verification_tag1 !=0)     && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
515                                                                         return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
516                                                                 else
517                                                                         return ADDRESS_BACKWARD_STREAM;
518                                                         }
519                                                         else
520                                                                 dstlist=g_list_next(dstlist);
521                                                 }
522                                                 else
523                                                         dstlist=g_list_next(dstlist);
524                                 }
525                                 srclist=g_list_next(srclist);
526                         }
527                         else
528                                 srclist=g_list_next(srclist);
529                 }
530                 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
531                 {
532                         if (*src->data == *srcstore->data && a->port2 == b->port1)
533                         {
534                                 dstlist = g_list_first(b->addr2);
535                                 while (dstlist)
536                                 {
537                                         dststore = (address *) (dstlist->data);
538                                         if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
539                                         {
540                                                 if (*dst->data==*dststore->data && a->port1 == b->port2)
541                                                 {
542                                                                 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
543                                                                         return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
544                                                                 else if ((a->verification_tag1 !=0)     && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
545                                                                         return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
546                                                                 else
547                                                                         return ADDRESS_BACKWARD_STREAM;
548                                                 }
549                                                 else
550                                                         dstlist=g_list_next(dstlist);
551                                         }
552                                         else
553                                                 dstlist=g_list_next(dstlist);
554                                 }
555                                 srclist=g_list_next(srclist);
556                         }
557                         else
558                                 srclist=g_list_next(srclist);
559                 }
560                 else
561                         srclist=g_list_next(srclist);
562         }
563
564
565         g_free(src);
566         g_free(dst);
567         return ASSOC_NOT_FOUND;
568 }
569
570
571
572
573
574
575 sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
576 {
577         sctp_allassocs_info_t *assoc_info;
578         sctp_assoc_info_t *info = NULL;
579         GList* list;
580         guint8 cmp;
581
582         assoc_info = &sctp_tapinfo_struct;
583         if ((list = g_list_first(assoc_info->assoc_info_list))!=NULL)
584         {
585                 while (list)
586                 {
587                         cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
588                         if (cmp==ASSOC_NOT_FOUND)
589                         {
590                                 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
591                         }
592                         switch (cmp)
593                         {
594                         case FORWARD_STREAM:
595                                 info = (sctp_assoc_info_t*)(list->data);
596                                 info->direction = 1;
597                                 return info;
598                         case BACKWARD_STREAM:
599                                 info = (sctp_assoc_info_t*)(list->data);
600                                 info->direction = 2;
601                                 return info;
602                         case FORWARD_ADD_FORWARD_VTAG:
603                                 info = (sctp_assoc_info_t*)(list->data);
604                                 info->verification_tag1=needle->verification_tag1;
605                                 info->direction = 1;
606                                 return info;
607                         case BACKWARD_ADD_FORWARD_VTAG:
608                                 info = (sctp_assoc_info_t*)(list->data);
609                                 info->verification_tag1=needle->verification_tag1;
610                                 info->direction = 2;
611                                 return info;
612                         case BACKWARD_ADD_BACKWARD_VTAG:
613                                 info = (sctp_assoc_info_t*)(list->data);
614                                 info->verification_tag2=needle->verification_tag1;
615                                 info->direction = 2;
616                                 return info;
617                         case ADDRESS_FORWARD_STREAM:    
618                                 info = (sctp_assoc_info_t*)(list->data);
619                                 info->direction = 1;
620                                 info->check_address=TRUE;
621                                 return info;
622                         case ADDRESS_BACKWARD_STREAM:
623                                 info = (sctp_assoc_info_t*)(list->data);
624                                 info->direction = 2;
625                                 info->check_address=TRUE;
626                                 return info;
627                         case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
628                                 info = (sctp_assoc_info_t*)(list->data);
629                                 info->verification_tag1=needle->verification_tag1;
630                                 info->direction = 1;
631                                 info->check_address=TRUE;
632                                 return info;
633                         case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
634                                 info = (sctp_assoc_info_t*)(list->data);
635                                 info->verification_tag1=needle->verification_tag1;
636                                 info->direction = 2;
637                                 info->check_address=TRUE;
638                                 return info;
639                         case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
640                                 info = (sctp_assoc_info_t*)(list->data);
641                                 info->verification_tag2=needle->verification_tag1;
642                                 info->direction = 2;
643                                 info->check_address=TRUE;
644                                 return info;
645                         }
646
647                         list = g_list_next(list);
648                 }
649         }
650         return NULL;
651 }
652
653 sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, unsigned int direction, unsigned int type)
654 {
655         GList *list;
656         address *v=NULL;
657         sctp_addr_chunk *ch=NULL;
658         guint8 * dat;
659         int i;
660
661                 list = g_list_first(info->addr_chunk_count);
662                 
663         while (list)
664         {
665                 ch = (sctp_addr_chunk *)(list->data);
666                 if (ch->direction == direction)
667                 {
668                         v = (address *) (ch->addr);
669                         if (*(vadd->data)==*(v->data))
670                         {
671                                 ch->addr_count[type]++;
672                                 return info;
673                         }
674                         else
675                         {
676                                 list = g_list_next(list);
677                         }
678                 }
679                 else
680                         list = g_list_next(list);
681         }
682         ch = g_malloc(sizeof(sctp_addr_chunk));
683         ch->direction = direction;
684         ch->addr = g_malloc(sizeof(address)); 
685         ch->addr->type = vadd->type;
686         ch->addr->len = vadd->len;
687         dat = g_malloc(vadd->len);
688         memcpy(dat, vadd->data, vadd->len);
689         ch->addr->data = dat;
690         for (i=0; i<13; i++)
691                 ch->addr_count[i]=0;
692         ch->addr_count[type]++;
693         info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
694         
695         return info;
696 }
697
698 sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
699 {
700         GList *list;
701         address *v=NULL;
702         
703         if (direction == 1)
704                 list = g_list_first(info->addr1);
705         else
706                 list = g_list_first(info->addr2);
707                 
708         while (list)
709         {
710                 v = (address *) (list->data);
711                 if (v->type == AT_IPv4 && vadd->type == AT_IPv4)
712                 {
713                         if (*vadd->data!=*v->data)
714                         {
715                                 list = g_list_next(list);
716                         }
717                         else
718                         {
719                                 g_free(vadd);
720                                 return info;
721                         }
722                 }
723                 else if (v->type == AT_IPv6 && vadd->type == AT_IPv6)
724                 {
725                         if (strcmp(ip6_to_str((const struct e_in6_addr *)(vadd->data)), ip6_to_str((const struct e_in6_addr *)v->data)))
726                         {
727                                 list = g_list_next(list);
728                         }
729                         else
730                         {
731                                 g_free(vadd);
732                                 return info;
733                         }
734                 }
735                 else
736                 {
737                         list= g_list_next(list);
738                 }
739         }
740
741         if (direction == 1)
742                 info->addr1 = g_list_append(info->addr1, vadd);
743         else if (direction==2)
744                 info->addr2 = g_list_append(info->addr2, vadd);
745         
746         return info;
747 }
748
749 static int
750 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
751 {
752         struct _sctp_info *sctp_info;
753         guint32 chunk_number=0, tsnumber;
754         sctp_tmp_info_t tmp_info;
755         sctp_assoc_info_t *info = NULL;
756         sctp_error_info_t *error = NULL;
757         char str[200];
758         guint16 type, length;
759         address *store=NULL;
760         tsn_t   *tsn=NULL;
761         tsn_t   *sack=NULL;
762         guint8 *t_s_n=NULL;
763         gboolean sackchunk=FALSE;
764         gboolean datachunk=FALSE;
765         guint32 max;
766         struct tsn_sort *tsn_s;
767         guint8* addr=NULL;
768         int i;
769
770         sctp_allassocs_info_t *assoc_info=NULL;
771         assoc_info = &sctp_tapinfo_struct;
772
773         sctp_info = (struct _sctp_info *) data;
774         max =0xFFFFFFFF;
775
776         type = pinfo->src.type;
777
778         if (type == AT_IPv4)
779         {
780                 tmp_info.src.type = AT_IPv4;
781                 tmp_info.src.len= 4;
782         }
783         else if (type == AT_IPv6)
784         {
785                 tmp_info.src.type=AT_IPv6;
786                 tmp_info.src.len=16;
787         }
788         
789         addr=malloc(tmp_info.src.len);
790         memcpy(addr, pinfo->src.data, tmp_info.src.len);
791         tmp_info.src.data= addr;
792
793         type = pinfo->dst.type;
794
795         if (type == AT_IPv4)
796         {
797                 tmp_info.dst.type=AT_IPv4;
798                 tmp_info.dst.len = 4;
799         }
800         else if (type == AT_IPv6)
801         {
802                 tmp_info.dst.type=AT_IPv6;
803                 tmp_info.dst.len=16;
804         }
805         
806         addr=malloc(tmp_info.dst.len);
807         memcpy(addr, pinfo->dst.data, tmp_info.dst.len);
808         tmp_info.dst.data= addr;
809
810         tmp_info.port1 = pinfo->srcport;
811         tmp_info.port2 = pinfo->destport;
812         tmp_info.verification_tag1=sctp_info->verification_tag;
813         tmp_info.verification_tag2=0;
814         tmp_info.n_tvbs=0;
815
816         info=find_assoc(&tmp_info);
817         if (!info)
818         {
819                 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
820                 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
821
822                 if (sctp_info->number_of_tvbs>0)
823                 {
824                         info = g_malloc(sizeof(sctp_assoc_info_t));
825                         memset(info, 0, sizeof(sctp_assoc_info_t));
826                         info->src.type = tmp_info.src.type;
827                         info->src.len=tmp_info.src.len;
828                         addr=malloc(tmp_info.dst.len);
829                         memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
830                         info->src.data = addr;
831                         info->dst.type = tmp_info.dst.type;
832                         info->dst.len = tmp_info.dst.len;
833                         addr=malloc(tmp_info.dst.len);
834                         memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
835                         info->dst.data = addr;
836                         info->port1=tmp_info.port1;
837                         info->port2=tmp_info.port2;
838                         info->verification_tag1=tmp_info.verification_tag1;
839                         info->verification_tag2=tmp_info.verification_tag2;
840                         info->n_tvbs=tmp_info.n_tvbs;
841                         info->init=FALSE;
842                         info->initack=FALSE;
843                         info->direction=0;
844                         info=calc_checksum(sctp_info, info);
845                         info->n_packets=1;
846                         info->error_info_list=NULL;
847                         info->min_secs=0xffffffff;
848                         info->min_usecs=0xffffffff;
849                         info->max_secs=0;
850                         info->max_usecs=0;
851                         info->min_tsn2=0xFFFFFFFF;
852                         info->min_tsn1=0xffffffff;
853                         info->max_tsn1=0;
854                         info->max_tsn2=0;
855                         info->max_bytes1=0;
856                         info->max_bytes2=0;
857                         info->n_data_chunks=0;
858                         info->n_data_bytes=0;
859                         info->n_data_chunks_ep1=0;
860                         info->n_data_bytes_ep1=0;
861                         info->n_data_chunks_ep2=0;
862                         info->n_data_bytes_ep2=0;
863                         info->n_sack_chunks_ep1=0;
864                         info->n_sack_chunks_ep2=0;
865                         info->n_array_tsn1=0;
866                         info->n_array_tsn2=0;
867                         info->max_window1=0;
868                         info->max_window2=0;
869                         info->min_max=NULL;
870                         info->sort_tsn1=g_ptr_array_new();
871                         info->sort_tsn2=g_ptr_array_new();
872                         info->sort_sack1=g_ptr_array_new();
873                         info->sort_sack2=g_ptr_array_new();
874                         for (i=0; i < NUM_CHUNKS; i++)
875                         {
876                                 info->chunk_count[i]=0;
877                                 info->ep1_chunk_count[i]=0;
878                                 info->ep2_chunk_count[i]=0;
879                         }
880                         info->addr_chunk_count=NULL;
881                         
882                         if (((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_CHUNK_ID) ||
883                             ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_ACK_CHUNK_ID) ||
884                             ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_DATA_CHUNK_ID) ||
885                             ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_SACK_CHUNK_ID))
886                         {
887                                 tsn = g_malloc(sizeof(tsn_t));
888                                 sack = g_malloc(sizeof(tsn_t));
889                                 tsn->tsns = NULL;
890                                 sack->tsns = NULL;
891                                 sack->src.type=tsn->src.type = tmp_info.src.type;
892                                 sack->src.len=tsn->src.len = tmp_info.src.len;
893                                 addr = malloc(tmp_info.src.len);
894                                 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
895                                 tsn->src.data = addr;
896                                 addr = malloc(tmp_info.src.len);
897                                 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
898                                 sack->src.data = addr;
899                                 sack->dst.type=tsn->dst.type = tmp_info.dst.type;
900                                 sack->dst.len=tsn->dst.len = tmp_info.dst.len;
901                                 addr = malloc(tmp_info.dst.len);
902                                 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
903                                 tsn->dst.data = addr;
904                                 addr = malloc(tmp_info.dst.len);
905                                 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
906                                 sack->dst.data = addr;
907                                 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_secs;
908                                 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_usecs;
909                                 if (((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_DATA_CHUNK_ID) ||
910                                         ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_SACK_CHUNK_ID))
911                                 {
912                                         if (tsn->secs<info->min_secs)
913                                         {
914                                                 info->min_secs=tsn->secs;
915                                                 info->min_usecs=tsn->usecs;
916                                         }
917                                         else if (tsn->secs==info->min_secs && tsn->usecs < info->min_usecs)
918                                                 info->min_usecs=tsn->usecs;
919
920                                         if (tsn->secs>info->max_secs)
921                                         {
922                                                 info->max_secs=tsn->secs;
923                                                 info->max_usecs=tsn->usecs;
924                                         }
925                                         else if (tsn->secs==info->max_secs && tsn->usecs > info->max_usecs)
926                                                 info->max_usecs=tsn->usecs;
927                                 }
928
929                                 sack->frame_number=tsn->frame_number = pinfo->fd->num;
930                         }
931                         if ((tvb_get_guint8(sctp_info->tvb[0],0)==SCTP_INIT_CHUNK_ID) || (tvb_get_guint8(sctp_info->tvb[0],0)==SCTP_INIT_ACK_CHUNK_ID))
932                         {
933                                 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
934                                 info->verification_tag2=tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
935                                 info->instream1=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
936                                 info->outstream1=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
937                                 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
938                                 {
939                                 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
940                                         if (type == IPV4ADDRESS_PARAMETER_ID)
941                                         {
942                                                 store = g_malloc(sizeof (address));
943                                                 store->type = AT_IPv4;;
944                                                 store->len  = 4;
945                                                 store->data = malloc(4);
946                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
947                                                 info = add_address(store, info, 1);
948                                         }
949                                         else if (type == IPV6ADDRESS_PARAMETER_ID)
950                                         {
951                                                 store = g_malloc(sizeof (address));
952                                                 store->type = AT_IPv6;;
953                                                 store->len  = 16;
954                                                 store->data = malloc(16);
955                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);     
956                                                 info = add_address(store, info, 1);
957                                         }
958                                 }
959                                 
960                                 if (tvb_get_guint8(sctp_info->tvb[0],0)==SCTP_INIT_CHUNK_ID)
961                                 {
962                                         info->init = TRUE;
963                                 }
964                                 else
965                                 {
966                                         info->initack_dir = 1;
967                                         info->initack     = TRUE;
968                                 }
969                                 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
970                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
971                                 info=add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
972                         }
973                         else
974                         {
975                                 if (((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_INIT_CHUNK_ID) &&
976                                     ((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_INIT_ACK_CHUNK_ID) &&
977                                     ((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_DATA_CHUNK_ID) &&
978                                     ((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_SACK_CHUNK_ID))
979                                 {
980                                         tsn  = g_malloc(sizeof(tsn_t));
981                                         sack = g_malloc(sizeof(tsn_t));
982                                         tsn->tsns  = NULL;
983                                         sack->tsns = NULL;
984                                 }
985                                 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
986                                 {
987                                         if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0))<12)
988                                         {
989                                                 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
990                                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
991                                                 info=add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
992                                         }
993                                         else
994                                         {
995                                                 info->chunk_count[12]++;
996                                                 info->ep1_chunk_count[12]++;
997                                                 info=add_chunk_count(&tmp_info.src, info, 1, 12);
998                                         }
999                                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0)==SCTP_DATA_CHUNK_ID)
1000                                         {
1001                                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1002                                                 info->n_data_chunks++;
1003                                                 info->n_data_bytes+=length;
1004                                                 info->outstream1=tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1005                                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1006                                                 if (tsnumber<info->min_tsn1)
1007                                                         info->min_tsn1=tsnumber;
1008                                                 if (tsnumber>info->max_tsn1)
1009                                                 {
1010                                                         length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1011                                                         info->n_data_chunks_ep1++;
1012                                                         info->n_data_bytes_ep1+=length;
1013                                                         info->max_tsn1=tsnumber;
1014                                                 }
1015                                                 t_s_n = g_malloc(16);
1016                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1017                                                 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1018                                                 datachunk = TRUE;
1019                                                 tsn_s = g_malloc(sizeof(struct tsn_sort));
1020                                                 tsn_s->tsnumber=tsnumber;
1021                                                 tsn_s->secs=tsn->secs;
1022                                                 tsn_s->usecs=tsn->usecs;
1023                                                 tsn_s->offset=0;
1024                                                 tsn_s->length=length-DATA_CHUNK_HEADER_LENGTH;
1025                                                 g_ptr_array_add(info->sort_tsn1, tsn_s);
1026                                                 info->n_array_tsn1++;
1027                                         }
1028                                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0)==SCTP_SACK_CHUNK_ID)
1029                                         {
1030                                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1031                                                 if (tsnumber<info->min_tsn2)
1032                                                         info->min_tsn2=tsnumber;
1033                                                 if (tsnumber>info->max_tsn2)
1034                                                         info->max_tsn2=tsnumber;
1035                                                 info->n_sack_chunks_ep2++;
1036                                                 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1037                                                 t_s_n = g_malloc(length);
1038                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1039                                                 sack->tsns = g_list_append(sack->tsns, t_s_n);
1040                                                 sackchunk=TRUE;
1041                                                 tsn_s = g_malloc(sizeof(struct tsn_sort));
1042                                                 tsn_s->tsnumber=tsnumber;
1043                                                 tsn_s->secs=tsn->secs;
1044                                                 tsn_s->usecs=tsn->usecs;
1045                                                 tsn_s->offset=0;
1046                                                 tsn_s->length= tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1047                                                 if (tsn_s->length>info->max_window1)
1048                                                         info->max_window1=tsn_s->length;
1049                                                 g_ptr_array_add(info->sort_sack2, tsn_s);
1050                                                 info->n_sack_chunks_ep2++;
1051                                         }
1052                                 }
1053                         }
1054                         if (info->verification_tag1!=0 || info->verification_tag2!=0)
1055                         {
1056                                 store = g_malloc(sizeof (address));
1057                                 store->type = tmp_info.src.type;
1058                                 store->len = tmp_info.src.len;
1059                                 addr=malloc(tmp_info.src.len);
1060                                 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1061                                 store->data = addr;
1062                                 info = add_address(store, info, 1);
1063                                 store = g_malloc(sizeof (address));
1064                                 store->type = tmp_info.dst.type;
1065                                 store->len = tmp_info.dst.len;
1066                                 addr = malloc(tmp_info.dst.len);
1067                                 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1068                                 store->data = addr;
1069                                 info = add_address(store, info, 2);
1070                                 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1071                                 if (datachunk==TRUE)
1072                                         info->tsn1 = g_list_prepend(info->tsn1, tsn);
1073                                 if (sackchunk == TRUE)
1074                                         info->sack2 = g_list_prepend(info->sack2, sack);
1075                                 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
1076                         }
1077                         else
1078                         {
1079                                 error = g_malloc(sizeof(sctp_error_info_t));
1080                                 error->frame_number = pinfo->fd->num;
1081                                 strcpy(str,"");
1082                                 strcpy(error->chunk_info,"");
1083                                 if ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_CHUNK_ID)
1084                                         strcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"));
1085                                 else
1086                                         for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1087                                                 strcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"));
1088                                 error->info_text="INFOS";
1089                                 info->error_info_list = g_list_append(info->error_info_list, error);
1090                         }
1091                 }
1092         }
1093         else
1094         {
1095                 if (((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_CHUNK_ID) ||
1096                     ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_ACK_CHUNK_ID) ||
1097                     ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_DATA_CHUNK_ID) ||
1098                     ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_SACK_CHUNK_ID))
1099                 {
1100
1101                         tsn = g_malloc(sizeof(tsn_t));
1102                         sack = g_malloc(sizeof(tsn_t));
1103                         tsn->tsns = NULL;
1104                         sack->tsns = NULL;
1105                         sack->src.type=tsn->src.type = tmp_info.src.type;
1106                         sack->src.len=tsn->src.len = tmp_info.src.len;
1107                         addr = malloc(tmp_info.src.len);
1108                         memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1109                         tsn->src.data = addr;
1110                         addr = malloc(tmp_info.src.len);
1111                         memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1112                         sack->src.data = addr;
1113                         sack->dst.type=tsn->dst.type = tmp_info.dst.type;
1114                         sack->dst.len=tsn->dst.len = tmp_info.dst.len;
1115                         addr = malloc(tmp_info.dst.len);
1116                         memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1117                         tsn->dst.data = addr;                   
1118                         addr = malloc(tmp_info.dst.len);
1119                         memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1120                         sack->dst.data = addr;
1121                         sack->secs=tsn->secs = (guint32)pinfo->fd->rel_secs;
1122                         sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_usecs;
1123                         if (((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_DATA_CHUNK_ID) ||
1124                         ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_SACK_CHUNK_ID))
1125                         {
1126                                 if (tsn->secs<info->min_secs)
1127                                 {
1128                                         info->min_secs=tsn->secs;
1129                                         info->min_usecs=tsn->usecs;
1130                                 }
1131                                 else if (tsn->secs==info->min_secs && tsn->usecs<info->min_usecs)
1132                                         info->min_usecs=tsn->usecs;
1133
1134                                 if (tsn->secs>info->max_secs)
1135                                         {
1136                                                 info->max_secs=tsn->secs;
1137                                                 info->max_usecs=tsn->usecs;
1138                                         }
1139                                         else if (tsn->secs==info->max_secs && tsn->usecs > info->max_usecs)
1140                                                 info->max_usecs=tsn->usecs;
1141                         }
1142                         sack->frame_number=tsn->frame_number = pinfo->fd->num;
1143                 }
1144                 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1145
1146                 store = g_malloc(sizeof (address));
1147                 store->type = tmp_info.src.type;
1148                 store->len = tmp_info.src.len;
1149                 addr = malloc(tmp_info.src.len);
1150                 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1151                 store->data = addr;
1152                         
1153                 if (info->direction==1)
1154                         info = add_address(store, info, 1);
1155                 else if (info->direction==2)
1156                         info = add_address(store, info, 2);
1157                         
1158                 store = g_malloc(sizeof (address));
1159                 store->type = tmp_info.dst.type;
1160                 store->len = tmp_info.dst.len;
1161                 addr = malloc(tmp_info.dst.len);
1162                 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1163                 store->data = addr;
1164                 
1165                 if (info->direction==1)
1166                         info = add_address(store, info, 2);
1167                 else if (info->direction==2)
1168                         info = add_address(store, info, 1);
1169
1170                 if (((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_ACK_CHUNK_ID) ||
1171                     ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_CHUNK_ID))
1172                 {
1173                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1174
1175                         if (info->direction==2)
1176                         {
1177                                 if (tsnumber<info->min_tsn2)
1178                                         info->min_tsn2 = tsnumber;
1179                                 if (tsnumber > info->max_tsn2)
1180                                         info->max_tsn2 = tsnumber;
1181                                 info->instream2=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1182                                 info->outstream2=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1183                                 //info->initack_dir=2;
1184                                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1185                         }
1186                         else if (info->direction==1)
1187                         {
1188                                 if (tsnumber<info->min_tsn1)
1189                                         info->min_tsn1 = tsnumber;
1190                                 if (tsnumber > info->max_tsn1)
1191                                         info->max_tsn1 = tsnumber;
1192                                 info->instream1=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1193                                 info->outstream1=tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1194                                 //info->initack_dir=1;
1195                                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1196                         }
1197                         info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1198                         if (info->direction==1)
1199                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1200                         else
1201                                 info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1202                         info=add_chunk_count(&tmp_info.src, info, info->direction, tvb_get_guint8(sctp_info->tvb[0],0));
1203                         for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1204                         {
1205                                 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1206                                         if (type == IPV4ADDRESS_PARAMETER_ID)
1207                                         {
1208                                                 store = g_malloc(sizeof (address));
1209                                                 store->type = AT_IPv4;;
1210                                                 store->len = 4;
1211                                                 store->data = malloc(4);
1212                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1213                                                 info = add_address(store, info, info->direction);
1214                                         }
1215                                         else if (type == IPV6ADDRESS_PARAMETER_ID)
1216                                         {
1217                                                 store = g_malloc(sizeof (address));
1218                                                 store->type = AT_IPv6;;
1219                                                 store->len = 16;
1220                                                 store->data = malloc(16);
1221                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1222                                                 info = add_address(store, info, info->direction);
1223                                         }
1224                                         }
1225                         if ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_ACK_CHUNK_ID)
1226                         {
1227                                 info->initack = TRUE;
1228                                 info->initack_dir = info->direction;
1229                         }
1230                         else
1231                         if ((tvb_get_guint8(sctp_info->tvb[0],0))==SCTP_INIT_CHUNK_ID)
1232                         {
1233                                 info->init = TRUE;
1234                         }
1235                 }
1236                 else
1237                 {
1238                         if (((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_INIT_ACK_CHUNK_ID) &&
1239                             ((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_DATA_CHUNK_ID) &&
1240                             ((tvb_get_guint8(sctp_info->tvb[0],0))!=SCTP_SACK_CHUNK_ID))
1241                         {
1242                                 sack = g_malloc(sizeof(tsn_t));
1243                                 sack->tsns = NULL;
1244                                 tsn = g_malloc(sizeof(tsn_t));
1245                                 tsn->tsns = NULL;
1246                         }
1247                 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1248                 {
1249                         if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0))<12)
1250                         {
1251                                 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1252                                 if (info->direction==1)
1253                                         info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1254                                 else
1255                                         info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1256                                 info=add_chunk_count(&tmp_info.src, info,info->direction, tvb_get_guint8(sctp_info->tvb[0],0));
1257                         }
1258                         else
1259                         {
1260                                 info->chunk_count[12]++;
1261                                 if (info->direction==1)
1262                                         info->ep1_chunk_count[12]++;
1263                                 else
1264                                         info->ep2_chunk_count[12]++;
1265                                 info=add_chunk_count(&tmp_info.src, info, info->direction,12);
1266                         }
1267                         if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1268                         {
1269                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1270                                 t_s_n = g_malloc(16);
1271                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1272                                 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1273                                 datachunk = TRUE;
1274                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1275                                 info->n_data_chunks++;
1276                                 info->n_data_bytes+=length;
1277                                 tsn_s = g_malloc(sizeof(struct tsn_sort));
1278                                 tsn_s->tsnumber=tsnumber;
1279                                 tsn_s->secs=tsn->secs;
1280                                 tsn_s->usecs=tsn->usecs;
1281                                 tsn_s->offset=0;
1282                                 tsn_s->length=length;
1283
1284                                 if (info->direction == 1)
1285                                 {
1286                                         if(tsnumber<info->min_tsn1)
1287                                                 info->min_tsn1 = tsnumber;
1288                                         if ((info->init==TRUE || (info->initack==TRUE && info->initack_dir==1))&& tsnumber>=info->min_tsn1 && tsnumber<=info->max_tsn1)
1289                                         {
1290                                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1291                                                 info->n_data_chunks_ep1++;
1292                                                 info->n_data_bytes_ep1+=length;
1293                                         }
1294                                         if(tsnumber>info->max_tsn1)
1295                                         {
1296                                                 info->max_tsn1 = tsnumber;
1297                                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1298                                                 info->n_data_chunks_ep1++;
1299                                                 info->n_data_bytes_ep1+=length;
1300                                         }
1301                                         if (info->init==FALSE)
1302                                                 info->outstream1=tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1303                                         if (info->initack==FALSE)
1304                                                 info->instream2=tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1305
1306                                         g_ptr_array_add(info->sort_tsn1, tsn_s);
1307                                         info->n_array_tsn1++;
1308                                 }
1309                                 else if (info->direction == 2)
1310                                 {
1311
1312                                         if(tsnumber<info->min_tsn2)
1313                                                 info->min_tsn2 = tsnumber;
1314
1315                                         if ((info->initack==TRUE && info->initack_dir==2)&& tsnumber>=info->min_tsn2 && tsnumber<=info->max_tsn2)
1316                                         {
1317                                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1318                                                 info->n_data_chunks_ep2++;
1319                                                 info->n_data_bytes_ep2+=length;
1320                                         }
1321                                         if(tsnumber>info->max_tsn2)
1322                                         {
1323                                                 info->max_tsn2 = tsnumber;
1324                                                 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1325                                                 info->n_data_chunks_ep2++;
1326                                                 info->n_data_bytes_ep2+=length;
1327                                         }
1328                                         if (info->init==FALSE)
1329                                                 info->instream1=tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1330                                         if (info->initack==FALSE)
1331                                                 info->outstream2=tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1332
1333                                         g_ptr_array_add(info->sort_tsn2, tsn_s);
1334                                         info->n_array_tsn2++;
1335                                 }
1336                         }
1337                         else if (tvb_get_guint8(sctp_info->tvb[chunk_number],0)==SCTP_SACK_CHUNK_ID)
1338                         {
1339                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1340                                 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1341                                 t_s_n = g_malloc(length);
1342                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1343                                 sack->tsns = g_list_append(sack->tsns, t_s_n);
1344                                 sackchunk=TRUE;
1345                                 tsn_s=g_malloc(sizeof(struct tsn_sort));
1346                                 tsn_s->tsnumber=tsnumber;
1347                                 tsn_s->secs=tsn->secs;
1348                                 tsn_s->usecs=tsn->usecs;
1349                                 tsn_s->offset=0;
1350                                 tsn_s->length= tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1351
1352
1353                                 if (info->direction == 2)
1354                                 {
1355                                         if(tsnumber<info->min_tsn1)
1356                                                 info->min_tsn1 = tsnumber;
1357                                         if(tsnumber>info->max_tsn1)
1358                                                 info->max_tsn1 = tsnumber;
1359                                         if (tsn_s->length>info->max_window1)
1360                                                         info->max_window1=tsn_s->length;
1361                                         g_ptr_array_add(info->sort_sack1, tsn_s);
1362                                         info->n_sack_chunks_ep1++;
1363                                 }
1364                                 else if (info->direction == 1)
1365                                 {
1366
1367                                         if(tsnumber<info->min_tsn2)
1368                                                 info->min_tsn2 = tsnumber;
1369                                         if(tsnumber>info->max_tsn2)
1370                                                 info->max_tsn2 = tsnumber;
1371                                         if (tsn_s->length>info->max_window2)
1372                                                         info->max_window2=tsn_s->length;
1373                                         g_ptr_array_add(info->sort_sack2, tsn_s);
1374                                         info->n_sack_chunks_ep2++;
1375                                 }
1376                         }
1377                 }
1378
1379                 }
1380                 if (datachunk==TRUE)
1381                 {
1382                         if (info->direction == 1)
1383                                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1384                         else if (info->direction == 2)
1385                                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1386                 }
1387                 if (sackchunk==TRUE)
1388                 {
1389                         if (info->direction == 1)
1390                                         info->sack2 = g_list_prepend(info->sack2, sack);
1391                                 else if(info->direction == 2)
1392                                         info->sack1 = g_list_prepend(info->sack1, sack);
1393                 }
1394                 info->n_tvbs+=sctp_info->number_of_tvbs;
1395                 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
1396                 info = calc_checksum(sctp_info, info);
1397                 info->n_packets++;
1398         }
1399         return(1);
1400 }
1401
1402
1403 /* XXX just copied from gtk/rpc_stat.c */
1404 void protect_thread_critical_region(void);
1405 void unprotect_thread_critical_region(void);
1406
1407 /****************************************************************************/
1408 void
1409 remove_tap_listener_sctp_stat(void)
1410 {
1411         if (sctp_tapinfo_struct.is_registered) {
1412                 protect_thread_critical_region();
1413                 remove_tap_listener(&sctp_tapinfo_struct);
1414                 unprotect_thread_critical_region();
1415                 sctp_tapinfo_struct.is_registered = FALSE;
1416         }
1417 }
1418
1419
1420 void sctp_stat_scan(void)
1421 {
1422         if (!sctp_tapinfo_struct.is_registered)
1423                 register_tap_listener_sctp_stat();
1424 }
1425
1426 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1427 {
1428         return &sctp_tapinfo_struct;
1429 }
1430
1431
1432 static void
1433 gtk_sctpstat_init(char *dummy _U_)
1434 {
1435
1436 }
1437
1438 static void sctp_update(void *dummy _U_)
1439 {
1440         if (get_stat_dlg()!=NULL)
1441                 sctp_stat_dlg_update();
1442 }
1443
1444 void
1445 register_tap_listener_sctp_stat(void)
1446 {
1447         GString *error_string;
1448
1449         if (!sctp_tapinfo_struct.is_registered)
1450         {
1451                 register_tap_listener_cmd_arg("sctp",gtk_sctpstat_init);
1452                 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, reset, packet, sctp_update))) {
1453                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
1454                         g_string_free(error_string, TRUE);
1455                         return;
1456                 }
1457                 sctp_tapinfo_struct.is_registered=TRUE;
1458         }
1459 }