replace malloc and alike calls by their GLib pendants -> g_malloc
[metze/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         if ((a->port1 == b->port2) &&
321             (a->port2 == b->port1) &&
322             (a->verification_tag2 == b->verification_tag1))
323                 return(BACKWARD_STREAM);
324
325         /*forward stream verifivation tag can be added*/
326         if ((a->port1 == b->port1) &&
327             (a->port2 == b->port2) &&
328             (a->verification_tag1 != 0) &&
329             (b->verification_tag1 == 0) &&
330             (b->verification_tag2 !=0))
331                 return (FORWARD_ADD_FORWARD_VTAG);
332                 
333         if ((a->port1 == b->port2) &&
334             (a->port2 == b->port1) &&
335             (a->verification_tag1 == b->verification_tag2) &&
336             (b->verification_tag1 == 0))
337                 return (BACKWARD_ADD_FORWARD_VTAG);
338                 
339         /*backward stream verification tag can be added */
340         if ((a->port1 == b->port2) &&
341             (a->port2 == b->port1) &&
342             (a->verification_tag1 !=0) &&
343             (b->verification_tag1 != 0) &&
344             (b->verification_tag2 == 0))
345                 return(BACKWARD_ADD_BACKWARD_VTAG);
346
347         return(ASSOC_NOT_FOUND);
348 }
349
350
351 gint sctp_assoc_address_cmp(gconstpointer aa, gconstpointer bb)
352 {
353         GList *srclist, *dstlist;
354         const struct _sctp_tmp_info* a = aa;
355         const struct _sctp_assoc_info* b = bb;
356         address *srcstore=NULL;
357         address *dststore=NULL;
358         address *src=NULL;
359         address *dst=NULL;
360         gboolean src_v4=FALSE;
361         gboolean src_v6=FALSE;
362         gboolean dst_v4=FALSE;
363         gboolean dst_v6=FALSE;
364         guint8* addr;
365
366         src = g_malloc(sizeof(address));
367         if (a->src.type == AT_IPv4)
368         {
369                 src->type = AT_IPv4;
370                 src->len  = 4;
371                 src_v4    = TRUE;
372         }
373         else if (a->src.type==AT_IPv6)
374         {
375                 src->type = AT_IPv6;
376                 src->len  = 16;
377                 src_v6    = TRUE;
378         }
379         addr = g_malloc(src->len);
380         memcpy(addr, a->src.data, src->len);
381         src->data = addr;
382
383         dst = g_malloc(sizeof(address));
384         if (a->dst.type == AT_IPv4)
385         {
386                 dst->type = AT_IPv4;
387                 dst->len  = 4;
388                 dst_v4    = TRUE;
389         }
390         else if (a->dst.type==AT_IPv6)
391         {
392                 dst->type = AT_IPv6;
393                 dst->len  = 16;
394                 dst_v6    = TRUE;
395         }
396         addr = g_malloc(dst->len);
397         memcpy(addr, a->dst.data, dst->len);
398         dst->data = addr;
399
400         srclist = g_list_first(b->addr1);
401         while (srclist)
402         {
403                 srcstore = (address *) (srclist->data);
404                 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
405                 {
406                         if (*src->data==*srcstore->data && a->port1 == b->port1)
407                         {
408                                 dstlist = g_list_first(b->addr2);
409                                 while (dstlist)
410                                 {
411                                                 dststore = (address *) (dstlist->data);
412                                                 if ((dststore->type==AT_IPv4 && dst_v4==TRUE) ||(dststore->type==AT_IPv6 && dst_v6==TRUE) )
413                                                 {
414                                                         if (*dst->data==*dststore->data && a->port2 == b->port2)
415                                                         {
416                                                                 if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
417                                                                         return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
418                                                                 else
419                                                                         return ADDRESS_FORWARD_STREAM;
420                                                         }
421                                                         else
422                                                                 dstlist=g_list_next(dstlist);
423                                                 }
424                                                 else
425                                                         dstlist=g_list_next(dstlist);
426                                 }
427                                 srclist=g_list_next(srclist);
428                         }
429                         else
430                                 srclist=g_list_next(srclist);
431                 }
432                 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
433                 {
434                         if (*src->data == *srcstore->data  && a->port1 == b->port1)
435                         {
436                                 dstlist = g_list_first(b->addr2);
437                                 while (dstlist)
438                                 {
439                                         dststore = (address *) (dstlist->data);
440                                         if ((dststore->type==AT_IPv4 && dst_v4==TRUE) || (dststore->type==AT_IPv6 && dst_v6==TRUE))
441                                         {
442                                                 if (*dst->data==*dststore->data && a->port2 == b->port2)
443                                                 {
444                                                         if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
445                                                                 return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
446                                                         else
447                                                                 return ADDRESS_FORWARD_STREAM;
448                                                 }
449                                                 else
450                                                         dstlist=g_list_next(dstlist);
451                                         }
452                                         else
453                                                 dstlist=g_list_next(dstlist);
454                                 }
455                                 srclist=g_list_next(srclist);
456                         }
457                         else
458                                 srclist=g_list_next(srclist);
459                 }
460                 else
461                         srclist=g_list_next(srclist);
462         }
463
464         g_free(src);
465         g_free(dst);
466
467         src = g_malloc(sizeof(address));
468         if (a->dst.type == AT_IPv4)
469         {
470                 src->type = AT_IPv4;
471                 src->len  = 4;
472                 src_v4    = TRUE;
473         }
474         else if (a->dst.type==AT_IPv6)
475         {
476                 src->type = AT_IPv6;
477                 src->len  = 16;
478                 src_v6    = TRUE;
479         }
480         addr = g_malloc(src->len);
481         memcpy(addr, a->dst.data, src->len);
482         src->data = addr;
483         
484         dst = g_malloc(sizeof(address));
485         if (a->src.type == AT_IPv4)
486         {
487                 dst->type = AT_IPv4;
488                 dst->len  = 4;
489                 dst_v4    = TRUE;
490         }
491         else if (a->src.type==AT_IPv6)
492         {
493                 dst->type = AT_IPv6;
494                 dst->len  = 16;
495                 dst_v6    = TRUE;
496         }
497         addr = g_malloc(dst->len);
498         memcpy(addr, a->src.data, dst->len);
499         dst->data = addr;
500         
501         srclist = g_list_first(b->addr1);
502         while (srclist)
503         {
504                 srcstore = (address *) (srclist->data);
505                 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
506                 {
507                         if (*src->data==*srcstore->data && a->port2 == b->port1)
508                         {
509                                 dstlist = g_list_first(b->addr2);
510                                 while (dstlist)
511                                 {
512                                                 dststore = (address *) (dstlist->data);
513                                                 if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
514                                                 {
515                                                         if (*dst->data==*dststore->data && a->port1 == b->port2)
516                                                         {
517                                                                 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
518                                                                         return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
519                                                                 else if ((a->verification_tag1 !=0)     && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
520                                                                         return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
521                                                                 else
522                                                                         return ADDRESS_BACKWARD_STREAM;
523                                                         }
524                                                         else
525                                                                 dstlist=g_list_next(dstlist);
526                                                 }
527                                                 else
528                                                         dstlist=g_list_next(dstlist);
529                                 }
530                                 srclist=g_list_next(srclist);
531                         }
532                         else
533                                 srclist=g_list_next(srclist);
534                 }
535                 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
536                 {
537                         if (*src->data == *srcstore->data && a->port2 == b->port1)
538                         {
539                                 dstlist = g_list_first(b->addr2);
540                                 while (dstlist)
541                                 {
542                                         dststore = (address *) (dstlist->data);
543                                         if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
544                                         {
545                                                 if (*dst->data==*dststore->data && a->port1 == b->port2)
546                                                 {
547                                                                 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
548                                                                         return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
549                                                                 else if ((a->verification_tag1 !=0)     && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
550                                                                         return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
551                                                                 else
552                                                                         return ADDRESS_BACKWARD_STREAM;
553                                                 }
554                                                 else
555                                                         dstlist=g_list_next(dstlist);
556                                         }
557                                         else
558                                                 dstlist=g_list_next(dstlist);
559                                 }
560                                 srclist=g_list_next(srclist);
561                         }
562                         else
563                                 srclist=g_list_next(srclist);
564                 }
565                 else
566                         srclist=g_list_next(srclist);
567         }
568
569
570         g_free(src);
571         g_free(dst);
572         return ASSOC_NOT_FOUND;
573 }
574
575
576
577
578
579
580 sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
581 {
582         sctp_allassocs_info_t *assoc_info;
583         sctp_assoc_info_t *info = NULL;
584         GList* list;
585         guint8 cmp;
586
587         assoc_info = &sctp_tapinfo_struct;
588         if ((list = g_list_first(assoc_info->assoc_info_list))!=NULL)
589         {
590                 while (list)
591                 {
592                         cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
593                         /*if (cmp==ASSOC_NOT_FOUND)
594                         {
595                                 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
596                         }*/
597                         switch (cmp)
598                         {
599                         case FORWARD_STREAM:
600                                 info = (sctp_assoc_info_t*)(list->data);
601                                 info->direction = 1;
602                                 return info;
603                         case BACKWARD_STREAM:
604                                 info = (sctp_assoc_info_t*)(list->data);
605                                 info->direction = 2;
606                                 return info;
607                         case FORWARD_ADD_FORWARD_VTAG:
608                                 info = (sctp_assoc_info_t*)(list->data);
609                                 info->verification_tag1=needle->verification_tag1;
610                                 info->direction = 1;
611                                 return info;
612                         case BACKWARD_ADD_FORWARD_VTAG:
613                                 info = (sctp_assoc_info_t*)(list->data);
614                                 info->verification_tag1=needle->verification_tag1;
615                                 info->direction = 2;
616                                 return info;
617                         case BACKWARD_ADD_BACKWARD_VTAG:
618                                 info = (sctp_assoc_info_t*)(list->data);
619                                 info->verification_tag2=needle->verification_tag1;
620                                 info->direction = 2;
621                                 return info;
622                         case ADDRESS_FORWARD_STREAM:    
623                                 info = (sctp_assoc_info_t*)(list->data);
624                                 info->direction = 1;
625                                 info->check_address=TRUE;
626                                 return info;
627                         case ADDRESS_BACKWARD_STREAM:
628                                 info = (sctp_assoc_info_t*)(list->data);
629                                 info->direction = 2;
630                                 info->check_address=TRUE;
631                                 return info;
632                         case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
633                                 info = (sctp_assoc_info_t*)(list->data);
634                                 info->verification_tag1=needle->verification_tag1;
635                                 info->direction = 1;
636                                 info->check_address=TRUE;
637                                 return info;
638                         case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
639                                 info = (sctp_assoc_info_t*)(list->data);
640                                 info->verification_tag1=needle->verification_tag1;
641                                 info->direction = 2;
642                                 info->check_address=TRUE;
643                                 return info;
644                         case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
645                                 info = (sctp_assoc_info_t*)(list->data);
646                                 info->verification_tag2=needle->verification_tag1;
647                                 info->direction = 2;
648                                 info->check_address=TRUE;
649                                 return info;
650                         }
651
652                         list = g_list_next(list);
653                 }
654         }
655         return NULL;
656 }
657
658 sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
659 {
660         GList *list;
661         address *v=NULL;
662         sctp_addr_chunk *ch=NULL;
663         guint8 * dat;
664         int i;
665
666                 list = g_list_first(info->addr_chunk_count);
667                 
668         while (list)
669         {
670                 ch = (sctp_addr_chunk *)(list->data);
671                 if (ch->direction == direction)
672                 {
673                         v = (address *) (ch->addr);
674                         if (*(vadd->data)==*(v->data))
675                         {
676                                 ch->addr_count[type]++;
677                                 return info;
678                         }
679                         else
680                         {
681                                 list = g_list_next(list);
682                         }
683                 }
684                 else
685                         list = g_list_next(list);
686         }
687         ch = g_malloc(sizeof(sctp_addr_chunk));
688         ch->direction = direction;
689         ch->addr = g_malloc(sizeof(address)); 
690         ch->addr->type = vadd->type;
691         ch->addr->len = vadd->len;
692         dat = g_malloc(vadd->len);
693         memcpy(dat, vadd->data, vadd->len);
694         ch->addr->data = dat;
695         for (i=0; i<13; i++)
696                 ch->addr_count[i] = 0;
697         ch->addr_count[type]++;
698         info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
699         
700         return info;
701 }
702
703 sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
704 {
705         GList *list;
706         address *v=NULL;
707         
708         if (direction == 1)
709                 list = g_list_first(info->addr1);
710         else
711                 list = g_list_first(info->addr2);
712                 
713         while (list)
714         {
715                 v = (address *) (list->data);
716                 if (v->type == AT_IPv4 && vadd->type == AT_IPv4)
717                 {
718                         if (*vadd->data!=*v->data)
719                         {
720                                 list = g_list_next(list);
721                         }
722                         else
723                         {
724                                 g_free(vadd);
725                                 return info;
726                         }
727                 }
728                 else if (v->type == AT_IPv6 && vadd->type == AT_IPv6)
729                 {
730                         if (strcmp(ip6_to_str((const struct e_in6_addr *)(vadd->data)), ip6_to_str((const struct e_in6_addr *)v->data)))
731                         {
732                                 list = g_list_next(list);
733                         }
734                         else
735                         {
736                                 g_free(vadd);
737                                 return info;
738                         }
739                 }
740                 else
741                 {
742                         list = g_list_next(list);
743                 }
744         }
745
746         if (direction == 1)
747                 info->addr1 = g_list_append(info->addr1, vadd);
748         else if (direction==2)
749                 info->addr2 = g_list_append(info->addr2, vadd);
750         
751         return info;
752 }
753
754 static int
755 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
756 {
757         struct _sctp_info *sctp_info;
758         guint32 chunk_number = 0, tsnumber;
759         sctp_tmp_info_t tmp_info;
760         sctp_assoc_info_t *info = NULL;
761         sctp_error_info_t *error = NULL;
762         char str[200];
763         guint16 type, length;
764         address *store = NULL;
765         tsn_t   *tsn = NULL;
766         tsn_t   *sack = NULL;
767         guint8  *t_s_n = NULL;
768         gboolean sackchunk = FALSE;
769         gboolean datachunk = FALSE;
770         guint32 max;
771         struct tsn_sort *tsn_s;
772         guint8* addr = NULL;
773         int i;
774
775         sctp_allassocs_info_t *assoc_info=NULL;
776         assoc_info = &sctp_tapinfo_struct;
777
778         sctp_info = (struct _sctp_info *) data;
779         max =0xFFFFFFFF;
780
781         type = sctp_info->ip_src.type;
782
783         if (type == AT_IPv4)
784         {
785                 tmp_info.src.type = AT_IPv4;
786                 tmp_info.src.len  = 4;
787         }
788         else if (type == AT_IPv6)
789         {
790                 tmp_info.src.type = AT_IPv6;
791                 tmp_info.src.len  = 16;
792         }
793         
794         addr = g_malloc(tmp_info.src.len);
795         memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
796         tmp_info.src.data = addr;
797
798         type = sctp_info->ip_dst.type;
799
800         if (type == AT_IPv4)
801         {
802                 tmp_info.dst.type = AT_IPv4;
803                 tmp_info.dst.len  = 4;
804         }
805         else if (type == AT_IPv6)
806         {
807                 tmp_info.dst.type = AT_IPv6;
808                 tmp_info.dst.len  = 16;
809         }
810         
811         addr = g_malloc(tmp_info.dst.len);
812         memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
813         tmp_info.dst.data = addr;
814
815         tmp_info.port1 = sctp_info->sport;
816         tmp_info.port2 = sctp_info->dport;
817
818         if (sctp_info->vtag_reflected)
819         {
820                 tmp_info.verification_tag2 = sctp_info->verification_tag;
821                 tmp_info.verification_tag1 = 0;
822         }
823         else
824         {
825                 tmp_info.verification_tag1 = sctp_info->verification_tag;
826                 tmp_info.verification_tag2 = 0;
827         }
828         tmp_info.n_tvbs = 0;
829
830         info = find_assoc(&tmp_info);
831         if (!info)
832         {
833                 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
834                 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
835
836                 if (sctp_info->number_of_tvbs > 0)
837                 {
838                         info = g_malloc(sizeof(sctp_assoc_info_t));
839                         memset(info, 0, sizeof(sctp_assoc_info_t));
840                         info->src.type = tmp_info.src.type;
841                         info->src.len  = tmp_info.src.len;
842                         addr = g_malloc(tmp_info.dst.len);
843                         memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
844                         info->src.data = addr;
845                         info->dst.type = tmp_info.dst.type;
846                         info->dst.len  = tmp_info.dst.len;
847                         addr = g_malloc(tmp_info.dst.len);
848                         memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
849                         info->dst.data = addr;
850                         info->port1 = tmp_info.port1;
851                         info->port2 = tmp_info.port2;
852                         info->verification_tag1 = tmp_info.verification_tag1;
853                         info->verification_tag2 = tmp_info.verification_tag2;
854                         info->n_tvbs            = tmp_info.n_tvbs;
855                         info->init              = FALSE;
856                         info->initack           = FALSE;
857                         info->direction         = 0;
858                         info = calc_checksum(sctp_info, info);
859                         info->n_packets         = 1;
860                         info->error_info_list   = NULL;
861                         info->min_secs          = 0xffffffff;
862                         info->min_usecs         = 0xffffffff;
863                         info->max_secs          = 0;
864                         info->max_usecs         = 0;
865                         info->min_tsn2          = 0xFFFFFFFF;
866                         info->min_tsn1          = 0xffffffff;
867                         info->max_tsn1          = 0;
868                         info->max_tsn2          = 0;
869                         info->max_bytes1        = 0;
870                         info->max_bytes2        = 0;
871                         info->n_data_chunks     = 0;
872                         info->n_data_bytes      = 0;
873                         info->n_data_chunks_ep1 = 0;
874                         info->n_data_bytes_ep1  = 0;
875                         info->n_data_chunks_ep2 = 0;
876                         info->n_data_bytes_ep2  = 0;
877                         info->n_sack_chunks_ep1 = 0;
878                         info->n_sack_chunks_ep2 = 0;
879                         info->n_array_tsn1      = 0;
880                         info->n_array_tsn2      = 0;
881                         info->max_window1       = 0;
882                         info->max_window2       = 0;
883                         info->min_max           = NULL;
884                         info->sort_tsn1         = g_ptr_array_new();
885                         info->sort_tsn2         = g_ptr_array_new();
886                         info->sort_sack1        = g_ptr_array_new();
887                         info->sort_sack2        = g_ptr_array_new();
888                         for (i=0; i < NUM_CHUNKS; i++)
889                         {
890                                 info->chunk_count[i] = 0;
891                                 info->ep1_chunk_count[i] = 0;
892                                 info->ep2_chunk_count[i] = 0;
893                         }
894                         info->addr_chunk_count = NULL;
895                         
896                         if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
897                             ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
898                             ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
899                             ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
900                         {
901                                 tsn  = g_malloc(sizeof(tsn_t));
902                                 sack = g_malloc(sizeof(tsn_t));
903                                 tsn->tsns  = NULL;
904                                 sack->tsns = NULL;
905                                 sack->src.type=tsn->src.type = tmp_info.src.type;
906                                 sack->src.len=tsn->src.len   = tmp_info.src.len;
907                                 addr = g_malloc(tmp_info.src.len);
908                                 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
909                                 tsn->src.data = addr;
910                                 addr = g_malloc(tmp_info.src.len);
911                                 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
912                                 sack->src.data = addr;
913                                 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
914                                 sack->dst.len  =tsn->dst.len   = tmp_info.dst.len;
915                                 addr = g_malloc(tmp_info.dst.len);
916                                 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
917                                 tsn->dst.data = addr;
918                                 addr = g_malloc(tmp_info.dst.len);
919                                 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
920                                 sack->dst.data = addr;
921                                 sack->secs=tsn->secs   = (guint32)pinfo->fd->rel_secs;
922                                 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_usecs;
923                                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
924                                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
925                                 {
926                                         if (tsn->secs < info->min_secs)
927                                         {
928                                                 info->min_secs  = tsn->secs;
929                                                 info->min_usecs = tsn->usecs;
930                                         }
931                                         else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
932                                                 info->min_usecs = tsn->usecs;
933
934                                         if (tsn->secs > info->max_secs)
935                                         {
936                                                 info->max_secs  = tsn->secs;
937                                                 info->max_usecs = tsn->usecs;
938                                         }
939                                         else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
940                                                 info->max_usecs = tsn->usecs;
941                                 }
942
943                                 sack->frame_number = tsn->frame_number = pinfo->fd->num;
944                         }
945                         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))
946                         {
947                                 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
948                                 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
949                                 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
950                                 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
951                                 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
952                                 {
953                                 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
954                                         if (type == IPV4ADDRESS_PARAMETER_ID)
955                                         {
956                                                 store = g_malloc(sizeof (address));
957                                                 store->type = AT_IPv4;;
958                                                 store->len  = 4;
959                                                 store->data = g_malloc(4);
960                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
961                                                 info = add_address(store, info, 1);
962                                         }
963                                         else if (type == IPV6ADDRESS_PARAMETER_ID)
964                                         {
965                                                 store = g_malloc(sizeof (address));
966                                                 store->type = AT_IPv6;;
967                                                 store->len  = 16;
968                                                 store->data = g_malloc(16);
969                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);     
970                                                 info = add_address(store, info, 1);
971                                         }
972                                 }
973                                 
974                                 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
975                                 {
976                                         info->init = TRUE;
977                                 }
978                                 else
979                                 {
980                                         info->initack_dir = 1;
981                                         info->initack     = TRUE;
982                                 }
983                                 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
984                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
985                                 info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
986                         }
987                         else
988                         {
989                                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
990                                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
991                                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
992                                     ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID))
993                                 {
994                                         tsn  = g_malloc(sizeof(tsn_t));
995                                         sack = g_malloc(sizeof(tsn_t));
996                                         tsn->tsns  = NULL;
997                                         sack->tsns = NULL;
998                                 }
999                                 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1000                                 {
1001                                         if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
1002                                         {
1003                                                 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1004                                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1005                                                 info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
1006                                         }
1007                                         else
1008                                         {
1009                                                 info->chunk_count[12]++;
1010                                                 info->ep1_chunk_count[12]++;
1011                                                 info = add_chunk_count(&tmp_info.src, info, 1, 12);
1012                                         }
1013                                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID)
1014                                         {
1015                                                 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1016                                                 info->n_data_chunks++;
1017                                                 info->n_data_bytes+=length;
1018                                                 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1019                                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1020                                                 if (tsnumber < info->min_tsn1)
1021                                                         info->min_tsn1 = tsnumber;
1022                                                 if (tsnumber > info->max_tsn1)
1023                                                 {
1024                                                         length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1025                                                         info->n_data_chunks_ep1++;
1026                                                         info->n_data_bytes_ep1+=length;
1027                                                         info->max_tsn1 = tsnumber;
1028                                                 }
1029                                                 t_s_n = g_malloc(16);
1030                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1031                                                 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1032                                                 datachunk = TRUE;
1033                                                 tsn_s = g_malloc(sizeof(struct tsn_sort));
1034                                                 tsn_s->tsnumber = tsnumber;
1035                                                 tsn_s->secs     = tsn->secs;
1036                                                 tsn_s->usecs    = tsn->usecs;
1037                                                 tsn_s->offset   = 0;
1038                                                 tsn_s->length   = length-DATA_CHUNK_HEADER_LENGTH;
1039                                                 g_ptr_array_add(info->sort_tsn1, tsn_s);
1040                                                 info->n_array_tsn1++;
1041                                         }
1042                                         if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID)
1043                                         {
1044                                                 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1045                                                 if (tsnumber < info->min_tsn2)
1046                                                         info->min_tsn2 = tsnumber;
1047                                                 if (tsnumber > info->max_tsn2)
1048                                                         info->max_tsn2 = tsnumber;
1049                                                 info->n_sack_chunks_ep2++;
1050                                                 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1051                                                 t_s_n = g_malloc(length);
1052                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1053                                                 sack->tsns = g_list_append(sack->tsns, t_s_n);
1054                                                 sackchunk = TRUE;
1055                                                 tsn_s = g_malloc(sizeof(struct tsn_sort));
1056                                                 tsn_s->tsnumber = tsnumber;
1057                                                 tsn_s->secs     = tsn->secs;
1058                                                 tsn_s->usecs    = tsn->usecs;
1059                                                 tsn_s->offset   = 0;
1060                                                 tsn_s->length   =  tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1061                                                 if (tsn_s->length > info->max_window1)
1062                                                         info->max_window1 = tsn_s->length;
1063                                                 g_ptr_array_add(info->sort_sack2, tsn_s);
1064                                                 info->n_sack_chunks_ep2++;
1065                                         }
1066                                 }
1067                         }
1068                         if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
1069                         {
1070                                 store = g_malloc(sizeof (address));
1071                                 store->type = tmp_info.src.type;
1072                                 store->len  = tmp_info.src.len;
1073                                 addr = g_malloc(tmp_info.src.len);
1074                                 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1075                                 store->data = addr;
1076                                 info  = add_address(store, info, 1);
1077                                 store = g_malloc(sizeof (address));
1078                                 store->type = tmp_info.dst.type;
1079                                 store->len  = tmp_info.dst.len;
1080                                 addr = g_malloc(tmp_info.dst.len);
1081                                 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1082                                 store->data = addr;
1083                                 info = add_address(store, info, 2);
1084                                 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1085                                 if (datachunk == TRUE)
1086                                         info->tsn1 = g_list_prepend(info->tsn1, tsn);
1087                                 if (sackchunk == TRUE)
1088                                         info->sack2 = g_list_prepend(info->sack2, sack);
1089                                 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
1090                         }
1091                         else
1092                         {
1093                                 error = g_malloc(sizeof(sctp_error_info_t));
1094                                 error->frame_number = pinfo->fd->num;
1095                                 strcpy(str,"");
1096                                 strcpy(error->chunk_info,"");
1097                                 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1098                                         strcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"));
1099                                 else
1100                                         for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1101                                                 strcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"));
1102                                 error->info_text = "INFOS";
1103                                 info->error_info_list = g_list_append(info->error_info_list, error);
1104                         }
1105                 }
1106         } /* endif (!info) */
1107         else
1108         {
1109                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
1110                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1111                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
1112                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
1113                 {
1114
1115                         tsn  = g_malloc(sizeof(tsn_t));
1116                         sack = g_malloc(sizeof(tsn_t));
1117                         tsn->tsns  = NULL;
1118                         sack->tsns = NULL;
1119                         sack->src.type = tsn->src.type = tmp_info.src.type;
1120                         sack->src.len  = tsn->src.len = tmp_info.src.len;
1121                         addr = g_malloc(tmp_info.src.len);
1122                         memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1123                         tsn->src.data = addr;
1124                         addr = g_malloc(tmp_info.src.len);
1125                         memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1126                         sack->src.data = addr;
1127                         sack->dst.type = tsn->dst.type = tmp_info.dst.type;
1128                         sack->dst.len  = tsn->dst.len = tmp_info.dst.len;
1129                         addr = g_malloc(tmp_info.dst.len);
1130                         memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1131                         tsn->dst.data = addr;                   
1132                         addr = g_malloc(tmp_info.dst.len);
1133                         memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1134                         sack->dst.data = addr;
1135                         sack->secs=tsn->secs = (guint32)pinfo->fd->rel_secs;
1136                         sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_usecs;
1137                         if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
1138                         ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
1139                         {
1140                                 if (tsn->secs < info->min_secs)
1141                                 {
1142                                         info->min_secs  = tsn->secs;
1143                                         info->min_usecs = tsn->usecs;
1144                                 }
1145                                 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1146                                         info->min_usecs = tsn->usecs;
1147
1148                                 if (tsn->secs > info->max_secs)
1149                                         {
1150                                                 info->max_secs  = tsn->secs;
1151                                                 info->max_usecs = tsn->usecs;
1152                                         }
1153                                         else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1154                                                 info->max_usecs = tsn->usecs;
1155                         }
1156                         sack->frame_number = tsn->frame_number = pinfo->fd->num;
1157                 }
1158                 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1159
1160                 store = g_malloc(sizeof (address));
1161                 store->type = tmp_info.src.type;
1162                 store->len  = tmp_info.src.len;
1163                 addr = g_malloc(tmp_info.src.len);
1164                 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1165                 store->data = addr;
1166                         
1167                 if (info->direction == 1)
1168                         info = add_address(store, info, 1);
1169                 else if (info->direction == 2)
1170                         info = add_address(store, info, 2);
1171                         
1172                 store = g_malloc(sizeof (address));
1173                 store->type = tmp_info.dst.type;
1174                 store->len  = tmp_info.dst.len;
1175                 addr = g_malloc(tmp_info.dst.len);
1176                 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1177                 store->data = addr;
1178                 
1179                 if (info->direction == 1)
1180                         info = add_address(store, info, 2);
1181                 else if (info->direction == 2)
1182                         info = add_address(store, info, 1);
1183
1184                 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1185                     ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1186                 {
1187                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1188
1189                         if (info->direction == 2)
1190                         {
1191                                 if (tsnumber < info->min_tsn2)
1192                                         info->min_tsn2 = tsnumber;
1193                                 if (tsnumber > info->max_tsn2)
1194                                         info->max_tsn2 = tsnumber;
1195                                 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1196                                 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1197                                 /*info->initack_dir=2;*/
1198                                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1199                         }
1200                         else if (info->direction == 1)
1201                         {
1202                                 if (tsnumber < info->min_tsn1)
1203                                         info->min_tsn1 = tsnumber;
1204                                 if (tsnumber > info->max_tsn1)
1205                                         info->max_tsn1 = tsnumber;
1206                                 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1207                                 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1208                                 /*info->initack_dir=1;*/
1209                                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1210                         }
1211                         info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1212                         if (info->direction == 1)
1213                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1214                         else
1215                                 info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1216                         info = add_chunk_count(&tmp_info.src, info, info->direction, tvb_get_guint8(sctp_info->tvb[0],0));
1217                         for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1218                         {
1219                                 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1220                                         if (type == IPV4ADDRESS_PARAMETER_ID)
1221                                         {
1222                                                 store = g_malloc(sizeof (address));
1223                                                 store->type = AT_IPv4;;
1224                                                 store->len  = 4;
1225                                                 store->data = g_malloc(4);
1226                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1227                                                 info = add_address(store, info, info->direction);
1228                                         }
1229                                         else if (type == IPV6ADDRESS_PARAMETER_ID)
1230                                         {
1231                                                 store = g_malloc(sizeof (address));
1232                                                 store->type = AT_IPv6;;
1233                                                 store->len  = 16;
1234                                                 store->data = g_malloc(16);
1235                                                 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1236                                                 info = add_address(store, info, info->direction);
1237                                         }
1238                                         }
1239                         if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1240                         {
1241                                 info->initack = TRUE;
1242                                 info->initack_dir = info->direction;
1243                         }
1244                         else
1245                         if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1246                         {
1247                                 info->init = TRUE;
1248                         }
1249                 }
1250                 else
1251                 {
1252                         if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1253                             ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1254                             ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID))
1255                         {
1256                                 sack = g_malloc(sizeof(tsn_t));
1257                                 sack->tsns = NULL;
1258                                 tsn = g_malloc(sizeof(tsn_t));
1259                                 tsn->tsns = NULL;
1260                         }
1261                         for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1262                         {
1263                                 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
1264                                 {
1265                                         info->chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1266                                         if (info->direction == 1)
1267                                                 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1268                                         else
1269                                                 info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1270                                         info = add_chunk_count(&tmp_info.src, info,info->direction, tvb_get_guint8(sctp_info->tvb[chunk_number],0));
1271                                 }
1272                                 else
1273                                 {
1274                                         info->chunk_count[12]++;
1275                                         if (info->direction == 1)
1276                                                 info->ep1_chunk_count[12]++;
1277                                         else
1278                                                 info->ep2_chunk_count[12]++;
1279                                         info = add_chunk_count(&tmp_info.src, info, info->direction,12);
1280                                 }
1281                                 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1282                                 {
1283                                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1284                                         t_s_n = g_malloc(16);
1285                                         tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1286                                         tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1287                                         datachunk = TRUE;
1288                                         length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1289                                         info->n_data_chunks++;
1290                                         info->n_data_bytes+=length;
1291                                         tsn_s = g_malloc(sizeof(struct tsn_sort));
1292                                         tsn_s->tsnumber = tsnumber;
1293                                         tsn_s->secs  = tsn->secs;
1294                                         tsn_s->usecs = tsn->usecs;
1295                                         tsn_s->offset = 0;
1296                                         tsn_s->length = length;
1297         
1298                                         if (info->direction == 1)
1299                                         {
1300                                                 if(tsnumber < info->min_tsn1)
1301                                                         info->min_tsn1 = tsnumber;
1302                                                 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1303                                                 {
1304                                                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1305                                                         info->n_data_chunks_ep1++;
1306                                                         info->n_data_bytes_ep1 += length;
1307                                                 }
1308                                                 if(tsnumber > info->max_tsn1)
1309                                                 {
1310                                                         info->max_tsn1 = tsnumber;
1311                                                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1312                                                         info->n_data_chunks_ep1++;
1313                                                         info->n_data_bytes_ep1 += length;
1314                                                 }
1315                                                 if (info->init == FALSE)
1316                                                         info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1317                                                 if (info->initack == FALSE)
1318                                                         info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1319         
1320                                                 g_ptr_array_add(info->sort_tsn1, tsn_s);
1321                                                 info->n_array_tsn1++;
1322                                         }
1323                                         else if (info->direction == 2)
1324                                         {
1325         
1326                                                 if(tsnumber < info->min_tsn2)
1327                                                         info->min_tsn2 = tsnumber;
1328         
1329                                                 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1330                                                 {
1331                                                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1332                                                         info->n_data_chunks_ep2++;
1333                                                         info->n_data_bytes_ep2+=length;
1334                                                 }
1335                                                 if(tsnumber > info->max_tsn2)
1336                                                 {
1337                                                         info->max_tsn2 = tsnumber;
1338                                                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1339                                                         info->n_data_chunks_ep2++;
1340                                                         info->n_data_bytes_ep2+=length;
1341                                                 }
1342                                                 if (info->init == FALSE)
1343                                                         info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1344                                                 if (info->initack == FALSE)
1345                                                         info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1346         
1347                                                 g_ptr_array_add(info->sort_tsn2, tsn_s);
1348                                                 info->n_array_tsn2++;
1349                                         }
1350                                 }
1351                                 else if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID)
1352                                 {
1353                                         tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1354                                         length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1355                                         t_s_n = g_malloc(length);
1356                                         tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1357                                         sack->tsns = g_list_append(sack->tsns, t_s_n);
1358                                         sackchunk = TRUE;
1359                                         tsn_s = g_malloc(sizeof(struct tsn_sort));
1360                                         tsn_s->tsnumber = tsnumber;
1361                                         tsn_s->secs   = tsn->secs;
1362                                         tsn_s->usecs  = tsn->usecs;
1363                                         tsn_s->offset = 0;
1364                                         tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1365         
1366         
1367                                         if (info->direction == 2)
1368                                         {
1369                                                 if(tsnumber < info->min_tsn1)
1370                                                         info->min_tsn1 = tsnumber;
1371                                                 if(tsnumber > info->max_tsn1)
1372                                                         info->max_tsn1 = tsnumber;
1373                                                 if (tsn_s->length > info->max_window1)
1374                                                                 info->max_window1 = tsn_s->length;
1375                                                 g_ptr_array_add(info->sort_sack1, tsn_s);
1376                                                 info->n_sack_chunks_ep1++;
1377                                         }
1378                                         else if (info->direction == 1)
1379                                         {
1380         
1381                                                 if(tsnumber < info->min_tsn2)
1382                                                         info->min_tsn2 = tsnumber;
1383                                                 if(tsnumber > info->max_tsn2)
1384                                                         info->max_tsn2 = tsnumber;
1385                                                 if (tsn_s->length > info->max_window2)
1386                                                                 info->max_window2 = tsn_s->length;
1387                                                 g_ptr_array_add(info->sort_sack2, tsn_s);
1388                                                 info->n_sack_chunks_ep2++;
1389                                         }
1390                                         
1391                                 }
1392                         }
1393
1394                 }
1395                 if (datachunk == TRUE)
1396                 {
1397                         if (info->direction == 1)
1398                                 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1399                         else if (info->direction == 2)
1400                                 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1401                 }
1402                 if (sackchunk == TRUE)
1403                 {
1404                         if (info->direction == 1)
1405                                         info->sack2 = g_list_prepend(info->sack2, sack);
1406                                 else if(info->direction == 2)
1407                                         info->sack1 = g_list_prepend(info->sack1, sack);
1408                 }
1409                 info->n_tvbs += sctp_info->number_of_tvbs;
1410                 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1411                 info = calc_checksum(sctp_info, info);
1412                 info->n_packets++;
1413         }
1414         return(1);
1415 }
1416
1417
1418 /* XXX just copied from gtk/rpc_stat.c */
1419 void protect_thread_critical_region(void);
1420 void unprotect_thread_critical_region(void);
1421
1422 /****************************************************************************/
1423 void
1424 remove_tap_listener_sctp_stat(void)
1425 {
1426         if (sctp_tapinfo_struct.is_registered) {
1427                 protect_thread_critical_region();
1428                 remove_tap_listener(&sctp_tapinfo_struct);
1429                 unprotect_thread_critical_region();
1430                 sctp_tapinfo_struct.is_registered = FALSE;
1431         }
1432 }
1433
1434
1435 void sctp_stat_scan(void)
1436 {
1437         if (!sctp_tapinfo_struct.is_registered)
1438                 register_tap_listener_sctp_stat();
1439 }
1440
1441 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1442 {
1443         return &sctp_tapinfo_struct;
1444 }
1445
1446
1447 static void
1448 gtk_sctpstat_init(char *dummy _U_)
1449 {
1450
1451 }
1452
1453 static void sctp_update(void *dummy _U_)
1454 {
1455         if (get_stat_dlg()!=NULL)
1456                 sctp_stat_dlg_update();
1457 }
1458
1459 void
1460 register_tap_listener_sctp_stat(void)
1461 {
1462         GString *error_string;
1463
1464         if (!sctp_tapinfo_struct.is_registered)
1465         {
1466                 register_tap_listener_cmd_arg("sctp",gtk_sctpstat_init);
1467                 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, reset, packet, sctp_update))) {
1468                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
1469                         g_string_free(error_string, TRUE);
1470                         return;
1471                 }
1472                 sctp_tapinfo_struct.is_registered=TRUE;
1473         }
1474 }