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