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