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