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