2 * Copyright 2004, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
34 #include "epan/packet_info.h"
36 #include "epan/address.h"
37 #include <epan/strutil.h>
39 #include "../simple_dialog.h"
40 #include "../globals.h"
41 #include "../register.h"
43 #include "gtk/dlg_utils.h"
44 #include "gtk/sctp_stat.h"
48 #define SCTP_HEARTBEAT_CHUNK_ID 4
49 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
50 #define SCTP_ABORT_CHUNK_ID 6
51 #define SCTP_SHUTDOWN_CHUNK_ID 7
52 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
53 #define SCTP_ERROR_CHUNK_ID 9
54 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
55 #define SCTP_COOKIE_ACK_CHUNK_ID 11
56 #define SCTP_ECNE_CHUNK_ID 12
57 #define SCTP_CWR_CHUNK_ID 13
58 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
59 #define SCTP_AUTH_CHUNK_ID 15
60 #define SCTP_NR_SACK_CHUNK_ID 16
61 #define SCTP_FORWARD_TSN_CHUNK_ID 192
62 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
63 #define SCTP_PKTDROP_CHUNK_ID 0X81
64 #define SCTP_ASCONF_CHUNK_ID 0XC1
65 #define SCTP_IETF_EXT 255
67 #define SCTP_ABORT_CHUNK_T_BIT 0x01
69 #define PARAMETER_TYPE_LENGTH 2
70 #define PARAMETER_LENGTH_LENGTH 2
71 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
73 #define PARAMETER_HEADER_OFFSET 0
74 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
75 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
76 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
78 #define IPV6_ADDRESS_LENGTH 16
79 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
80 #define IPV4_ADDRESS_LENGTH 4
81 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
82 #define IPV4ADDRESS_PARAMETER_ID 0x0005
83 #define IPV6ADDRESS_PARAMETER_ID 0x0006
85 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
86 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
87 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
88 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
89 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
91 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
92 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
93 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
94 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
95 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
96 INIT_CHUNK_INITIAL_TSN_LENGTH)
97 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
98 CHUNK_FLAGS_LENGTH + \
100 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
101 INIT_CHUNK_INITIAL_TSN_LENGTH )
103 static const value_string chunk_type_values[] = {
104 { SCTP_DATA_CHUNK_ID, "DATA" },
105 { SCTP_INIT_CHUNK_ID, "INIT" },
106 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
107 { SCTP_SACK_CHUNK_ID, "SACK" },
108 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
109 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
110 { SCTP_ABORT_CHUNK_ID, "ABORT" },
111 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
112 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
113 { SCTP_ERROR_CHUNK_ID, "ERROR" },
114 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
115 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
116 { SCTP_ECNE_CHUNK_ID, "ECNE" },
117 { SCTP_CWR_CHUNK_ID, "CWR" },
118 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
119 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
120 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
121 { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
122 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
123 { SCTP_IETF_EXT, "IETF_EXTENSION" },
124 { SCTP_NR_SACK_CHUNK_ID, "NR_SACK" },
125 { SCTP_AUTH_CHUNK_ID, "AUTH" },
129 #define FORWARD_STREAM 0
130 #define BACKWARD_STREAM 1
131 #define FORWARD_ADD_FORWARD_VTAG 2
132 #define BACKWARD_ADD_FORWARD_VTAG 3
133 #define BACKWARD_ADD_BACKWARD_VTAG 4
134 #define ADDRESS_FORWARD_STREAM 5
135 #define ADDRESS_BACKWARD_STREAM 6
136 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
137 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
138 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
139 #define ASSOC_NOT_FOUND 10
141 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
144 void free_first(gpointer data, gpointer user_data _U_)
149 static void tsn_free(gpointer data, gpointer user_data _U_)
153 tsn = (tsn_t *) data;
154 if (tsn->tsns != NULL)
156 g_list_foreach(tsn->tsns, free_first, NULL);
157 g_list_free(tsn->tsns);
163 static void reset(void *arg)
165 sctp_allassocs_info_t *tapdata = arg;
167 sctp_assoc_info_t * info;
169 list = g_list_first(tapdata->assoc_info_list);
172 info = (sctp_assoc_info_t *) (list->data);
174 if (info->addr1 != NULL)
176 g_list_foreach(info->addr1, free_first, NULL);
177 g_list_free(info->addr1);
181 if (info->addr2 != NULL)
183 g_list_foreach(info->addr2,free_first, NULL);
184 g_list_free(info->addr2);
188 if (info->error_info_list != NULL)
190 g_list_foreach(info->error_info_list, free_first, NULL);
191 g_list_free(info->error_info_list);
192 info->error_info_list = NULL;
195 if (info->frame_numbers != NULL)
197 g_list_free(info->frame_numbers);
198 info->frame_numbers = NULL;
201 if (info->tsn1 != NULL)
203 g_list_foreach(info->tsn1, tsn_free, NULL);
204 g_list_free(info->tsn1);
208 if (info->tsn2 != NULL)
210 g_list_foreach(info->tsn2, tsn_free, NULL);
211 g_list_free(info->tsn2);
215 if (info->sack1 != NULL)
217 g_list_foreach(info->sack1, tsn_free, NULL);
218 g_list_free(info->sack1);
222 if (info->sack2 != NULL)
224 g_list_foreach(info->sack2, tsn_free, NULL);
225 g_list_free(info->sack2);
229 if (info->sort_tsn1 != NULL)
230 g_ptr_array_free(info->sort_tsn1, TRUE);
232 if (info->sort_tsn2 != NULL)
233 g_ptr_array_free(info->sort_tsn2, TRUE);
235 if (info->sort_sack1 != NULL)
236 g_ptr_array_free(info->sort_sack1, TRUE);
238 if (info->sort_sack2 != NULL)
239 g_ptr_array_free(info->sort_sack2, TRUE);
241 if (info->min_max != NULL)
243 g_slist_foreach(info->min_max, free_first, NULL);
244 info->min_max = NULL;
248 list = g_list_next(list);
250 g_list_free(tapdata->assoc_info_list);
251 tapdata->sum_tvbs = 0;
252 tapdata->assoc_info_list = NULL;
256 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
260 if (check_data->adler32_calculated)
262 data->n_adler32_calculated++;
263 if (check_data->adler32_correct)
264 data->n_adler32_correct++;
266 if (check_data->crc32c_calculated)
268 data->n_crc32c_calculated++;
269 if (check_data->crc32c_correct)
270 data->n_crc32c_correct++;
272 if (data->n_adler32_calculated > 0)
274 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
276 g_strlcpy(data->checksum_type,"ADLER32",8);
277 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
282 if (data->n_crc32c_calculated>0)
284 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
286 g_strlcpy(data->checksum_type,"CRC32C",8);
287 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
294 g_strlcpy(data->checksum_type,"UNKNOWN",8);
295 data->n_checksum_errors=0;
303 /* XXX: Some versions of gcc warn about "breaking strict aliasing rules"
304 for 'a' in the following (given the way this function is called).
305 As a workaround we'll define the function parameters to match
306 how this function is actually called. */
308 static gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
310 const struct _sctp_assoc_info* a = aa;
311 const struct _sctp_assoc_info* b = bb;
313 return(FORWARD_STREAM);
316 static gint sctp_assoc_vtag_cmp(const sctp_tmp_info_t *a, const sctp_assoc_info_t *b)
319 if (a == NULL || b == NULL)
320 return(ASSOC_NOT_FOUND);
322 if ((a->port1 == b->port1) &&
323 (a->port2 == b->port2) &&
324 (a->verification_tag1 == b->verification_tag1) && a->verification_tag1==0 && a->initiate_tag != 0 &&
325 (a->initiate_tag != b->initiate_tag ))
326 return(ASSOC_NOT_FOUND); /* two INITs that belong to different assocs */
329 if ((a->port1 == b->port1) &&
330 (a->port2 == b->port2) &&
331 (a->verification_tag1 == b->verification_tag1) &&
332 ((a->verification_tag1 != 0 ||
333 (b->verification_tag2 != 0))))
334 return(FORWARD_STREAM);
336 /* ABORT, vtag reflected */
337 if ((a->port1 == b->port1) &&
338 (a->port2 == b->port2) &&
339 (a->verification_tag2 == b->verification_tag2) &&
340 (a->verification_tag1 == 0 && b->verification_tag1 != 0))
341 return(FORWARD_STREAM);
343 if ((a->port1 == b->port2) &&
344 (a->port2 == b->port1) &&
345 (a->verification_tag1 == b->verification_tag2) &&
346 (a->verification_tag1 != 0))
347 return(BACKWARD_STREAM);
349 if ((a->port1 == b->port2) &&
350 (a->port2 == b->port1) &&
351 (a->verification_tag2 == b->verification_tag1) &&
352 (a->verification_tag2 != 0))
353 return(BACKWARD_STREAM);
355 /* ABORT, vtag reflected */
356 if ((a->port1 == b->port2) &&
357 (a->port2 == b->port1) &&
358 (a->verification_tag2 == b->verification_tag1) &&
359 (a->verification_tag1 == 0 && b->verification_tag2 != 0))
360 return(BACKWARD_STREAM);
362 /*forward stream verifivation tag can be added*/
363 if ((a->port1 == b->port1) &&
364 (a->port2 == b->port2) &&
365 (a->verification_tag1 != 0) &&
366 (b->verification_tag1 == 0) &&
367 (b->verification_tag2 !=0))
368 return (FORWARD_ADD_FORWARD_VTAG);
370 if ((a->port1 == b->port2) &&
371 (a->port2 == b->port1) &&
372 (a->verification_tag1 == b->verification_tag2) &&
373 (b->verification_tag1 == 0))
374 return (BACKWARD_ADD_FORWARD_VTAG);
376 /*backward stream verification tag can be added */
377 if ((a->port1 == b->port2) &&
378 (a->port2 == b->port1) &&
379 (a->verification_tag1 !=0) &&
380 (b->verification_tag1 != 0) &&
381 (b->verification_tag2 == 0))
382 return(BACKWARD_ADD_BACKWARD_VTAG);
384 return(ASSOC_NOT_FOUND);
387 static sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
389 sctp_allassocs_info_t *assoc_info;
390 sctp_assoc_info_t *info = NULL;
394 assoc_info = &sctp_tapinfo_struct;
395 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
399 cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
401 /*if (cmp==ASSOC_NOT_FOUND)
403 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
408 info = (sctp_assoc_info_t*)(list->data);
411 case BACKWARD_STREAM:
412 info = (sctp_assoc_info_t*)(list->data);
415 case FORWARD_ADD_FORWARD_VTAG:
416 info = (sctp_assoc_info_t*)(list->data);
417 info->verification_tag1=needle->verification_tag1;
420 case BACKWARD_ADD_FORWARD_VTAG:
421 info = (sctp_assoc_info_t*)(list->data);
422 info->verification_tag1=needle->verification_tag1;
425 case BACKWARD_ADD_BACKWARD_VTAG:
426 info = (sctp_assoc_info_t*)(list->data);
427 info->verification_tag2=needle->verification_tag1;
430 case ADDRESS_FORWARD_STREAM:
431 info = (sctp_assoc_info_t*)(list->data);
433 info->check_address=TRUE;
435 case ADDRESS_BACKWARD_STREAM:
436 info = (sctp_assoc_info_t*)(list->data);
438 info->check_address=TRUE;
440 case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
441 info = (sctp_assoc_info_t*)(list->data);
442 info->verification_tag1=needle->verification_tag1;
444 info->check_address=TRUE;
446 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
447 info = (sctp_assoc_info_t*)(list->data);
448 info->verification_tag1=needle->verification_tag1;
450 info->check_address=TRUE;
452 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
453 info = (sctp_assoc_info_t*)(list->data);
454 info->verification_tag2=needle->verification_tag1;
456 info->check_address=TRUE;
460 list = g_list_previous(list);
466 static sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
470 sctp_addr_chunk *ch=NULL;
474 list = g_list_first(info->addr_chunk_count);
478 ch = (sctp_addr_chunk *)(list->data);
479 if (ch->direction == direction)
481 v = (address *) (ch->addr);
482 if (ADDRESSES_EQUAL(vadd, v))
484 if (type <= UPPER_BOUND_CHUNK_TYPE)
485 ch->addr_count[type]++;
487 ch->addr_count[OTHER_CHUNKS_INDEX]++;
492 list = g_list_next(list);
496 list = g_list_next(list);
498 ch = g_malloc(sizeof(sctp_addr_chunk));
499 ch->direction = direction;
500 ch->addr = g_malloc(sizeof(address));
501 ch->addr->type = vadd->type;
502 ch->addr->len = vadd->len;
503 dat = g_malloc(vadd->len);
504 memcpy(dat, vadd->data, vadd->len);
505 ch->addr->data = dat;
506 for (i=0; i < NUM_CHUNKS; i++)
507 ch->addr_count[i] = 0;
509 if (type <= UPPER_BOUND_CHUNK_TYPE)
510 ch->addr_count[type]++;
512 ch->addr_count[OTHER_CHUNKS_INDEX]++;
514 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
518 static sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
524 list = g_list_first(info->addr1);
526 list = g_list_first(info->addr2);
530 v = (address *) (list->data);
531 if (ADDRESSES_EQUAL(vadd, v)) {
535 list = g_list_next(list);
539 info->addr1 = g_list_append(info->addr1, vadd);
540 else if (direction==2)
541 info->addr2 = g_list_append(info->addr2, vadd);
547 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
549 struct _sctp_info *sctp_info;
550 guint32 chunk_number = 0, tsnumber,framenumber;
551 sctp_tmp_info_t tmp_info;
552 sctp_assoc_info_t *info = NULL;
553 sctp_error_info_t *error = NULL;
555 guint16 type, length;
556 address *store = NULL;
559 guint8 *t_s_n = NULL;
560 gboolean sackchunk = FALSE;
561 gboolean datachunk = FALSE;
563 struct tsn_sort *tsn_s;
568 sctp_allassocs_info_t *assoc_info=NULL;
569 assoc_info = &sctp_tapinfo_struct;
571 sctp_info = (struct _sctp_info *) data;
574 framenumber=pinfo->fd->num;
576 type = sctp_info->ip_src.type;
580 tmp_info.src.type = AT_IPv4;
581 tmp_info.src.len = 4;
583 else if (type == AT_IPv6)
585 tmp_info.src.type = AT_IPv6;
586 tmp_info.src.len = 16;
589 addr = g_malloc(tmp_info.src.len);
590 memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
591 tmp_info.src.data = addr;
593 type = sctp_info->ip_dst.type;
597 tmp_info.dst.type = AT_IPv4;
598 tmp_info.dst.len = 4;
600 else if (type == AT_IPv6)
602 tmp_info.dst.type = AT_IPv6;
603 tmp_info.dst.len = 16;
606 addr = g_malloc(tmp_info.dst.len);
607 memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
608 tmp_info.dst.data = addr;
610 tmp_info.port1 = sctp_info->sport;
611 tmp_info.port2 = sctp_info->dport;
613 if (sctp_info->vtag_reflected)
615 tmp_info.verification_tag2 = sctp_info->verification_tag;
616 tmp_info.verification_tag1 = 0;
620 tmp_info.verification_tag1 = sctp_info->verification_tag;
621 tmp_info.verification_tag2 = 0;
624 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
626 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
630 tmp_info.initiate_tag = 0;
633 info = find_assoc(&tmp_info);
636 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
637 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
639 if (sctp_info->number_of_tvbs > 0)
641 info = g_malloc(sizeof(sctp_assoc_info_t));
642 memset(info, 0, sizeof(sctp_assoc_info_t));
643 info->src.type = tmp_info.src.type;
644 info->src.len = tmp_info.src.len;
645 addr = g_malloc(tmp_info.dst.len);
646 memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
647 info->src.data = addr;
648 info->dst.type = tmp_info.dst.type;
649 info->dst.len = tmp_info.dst.len;
650 addr = g_malloc(tmp_info.dst.len);
651 memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
652 info->dst.data = addr;
653 info->port1 = tmp_info.port1;
654 info->port2 = tmp_info.port2;
655 info->verification_tag1 = tmp_info.verification_tag1;
656 info->verification_tag2 = tmp_info.verification_tag2;
657 info->initiate_tag = tmp_info.initiate_tag;
658 info->n_tvbs = tmp_info.n_tvbs;
660 info->initack = FALSE;
661 info->check_address = FALSE;
663 info = calc_checksum(sctp_info, info);
665 info->error_info_list = NULL;
666 info->min_secs = 0xffffffff;
667 info->min_usecs = 0xffffffff;
670 info->min_tsn2 = 0xFFFFFFFF;
671 info->min_tsn1 = 0xffffffff;
674 info->max_bytes1 = 0;
675 info->max_bytes2 = 0;
676 info->n_data_chunks = 0;
677 info->n_data_bytes = 0;
678 info->n_data_chunks_ep1 = 0;
679 info->n_data_bytes_ep1 = 0;
680 info->n_data_chunks_ep2 = 0;
681 info->n_data_bytes_ep2 = 0;
682 info->n_sack_chunks_ep1 = 0;
683 info->n_sack_chunks_ep2 = 0;
684 info->n_array_tsn1 = 0;
685 info->n_array_tsn2 = 0;
686 info->max_window1 = 0;
687 info->max_window2 = 0;
688 info->min_max = NULL;
689 info->sort_tsn1 = g_ptr_array_new();
690 info->sort_tsn2 = g_ptr_array_new();
691 info->sort_sack1 = g_ptr_array_new();
692 info->sort_sack2 = g_ptr_array_new();
693 for (i=0; i < NUM_CHUNKS; i++)
695 info->chunk_count[i] = 0;
696 info->ep1_chunk_count[i] = 0;
697 info->ep2_chunk_count[i] = 0;
699 info->addr_chunk_count = NULL;
701 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
702 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
703 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
704 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
705 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
707 tsn = g_malloc(sizeof(tsn_t));
708 sack = g_malloc(sizeof(tsn_t));
713 sack->src.type=tsn->src.type = tmp_info.src.type;
714 sack->src.len=tsn->src.len = tmp_info.src.len;
715 addr = g_malloc(tmp_info.src.len);
716 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
717 tsn->src.data = addr;
718 addr = g_malloc(tmp_info.src.len);
719 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
720 sack->src.data = addr;
721 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
722 sack->dst.len =tsn->dst.len = tmp_info.dst.len;
723 addr = g_malloc(tmp_info.dst.len);
724 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
725 tsn->dst.data = addr;
726 addr = g_malloc(tmp_info.dst.len);
727 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
728 sack->dst.data = addr;
729 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
730 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
731 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
732 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
733 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
735 if (tsn->secs < info->min_secs)
737 info->min_secs = tsn->secs;
738 info->min_usecs = tsn->usecs;
740 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
741 info->min_usecs = tsn->usecs;
743 if (tsn->secs > info->max_secs)
745 info->max_secs = tsn->secs;
746 info->max_usecs = tsn->usecs;
748 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
749 info->max_usecs = tsn->usecs;
752 sack->frame_number = tsn->frame_number = pinfo->fd->num;
754 if ((tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) || (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID))
756 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
757 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
758 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
759 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
760 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
762 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
763 if (type == IPV4ADDRESS_PARAMETER_ID)
765 store = g_malloc(sizeof (address));
766 store->type = AT_IPv4;;
768 store->data = g_malloc(4);
769 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
770 info = add_address(store, info, 1);
772 else if (type == IPV6ADDRESS_PARAMETER_ID)
774 store = g_malloc(sizeof (address));
775 store->type = AT_IPv6;;
777 store->data = g_malloc(16);
778 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
779 info = add_address(store, info, 1);
783 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
789 info->initack_dir = 1;
790 info->initack = TRUE;
793 idx = tvb_get_guint8(sctp_info->tvb[0],0);
794 if (idx > UPPER_BOUND_CHUNK_TYPE)
795 idx = OTHER_CHUNKS_INDEX;
797 info->chunk_count[idx]++;
798 info->ep1_chunk_count[idx]++;
799 info = add_chunk_count(&tmp_info.src, info, 1, idx);
803 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
804 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
805 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
806 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
807 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
809 tsn = g_malloc(sizeof(tsn_t));
810 sack = g_malloc(sizeof(tsn_t));
816 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
818 idx = tvb_get_guint8(sctp_info->tvb[0],0);
819 if ( idx > UPPER_BOUND_CHUNK_TYPE )
820 idx = OTHER_CHUNKS_INDEX;
822 info->chunk_count[idx]++;
823 info->ep1_chunk_count[idx]++;
824 info = add_chunk_count(&tmp_info.src, info, 1, idx);
826 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID)
828 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
829 info->n_data_chunks++;
830 info->n_data_bytes+=length;
831 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
832 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
833 if (tsnumber < info->min_tsn1)
834 info->min_tsn1 = tsnumber;
835 if (tsnumber > info->max_tsn1)
837 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
838 info->n_data_chunks_ep1++;
839 info->n_data_bytes_ep1+=length;
840 info->max_tsn1 = tsnumber;
842 if (tsn->first_tsn == 0)
843 tsn->first_tsn = tsnumber;
844 t_s_n = g_malloc(16);
845 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
846 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
848 tsn_s = g_malloc(sizeof(struct tsn_sort));
849 tsn_s->tsnumber = tsnumber;
850 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
851 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
853 tsn_s->framenumber = framenumber;
854 tsn_s->length = length-DATA_CHUNK_HEADER_LENGTH;
855 if (tsn->secs < info->min_secs)
857 info->min_secs = tsn->secs;
858 info->min_usecs = tsn->usecs;
860 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
861 info->min_usecs = tsn->usecs;
863 if (tsn->secs > info->max_secs)
865 info->max_secs = tsn->secs;
866 info->max_usecs = tsn->usecs;
868 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
869 info->max_usecs = tsn->usecs;
870 g_ptr_array_add(info->sort_tsn1, tsn_s);
871 info->n_array_tsn1++;
873 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
874 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
876 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
877 if (tsnumber < info->min_tsn2)
878 info->min_tsn2 = tsnumber;
879 if (tsnumber > info->max_tsn2)
880 info->max_tsn2 = tsnumber;
881 info->n_sack_chunks_ep2++;
882 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
883 if (sack->first_tsn == 0)
884 sack->first_tsn = tsnumber;
885 t_s_n = g_malloc(length);
886 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
887 sack->tsns = g_list_append(sack->tsns, t_s_n);
889 tsn_s = g_malloc(sizeof(struct tsn_sort));
890 tsn_s->tsnumber = tsnumber;
891 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
892 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
894 tsn_s->framenumber = framenumber;
895 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
896 if (tsn_s->length > info->max_window1)
897 info->max_window1 = tsn_s->length;
898 if (tsn->secs < info->min_secs)
900 info->min_secs = tsn->secs;
901 info->min_usecs = tsn->usecs;
903 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
904 info->min_usecs = tsn->usecs;
906 if (tsn->secs > info->max_secs)
908 info->max_secs = tsn->secs;
909 info->max_usecs = tsn->usecs;
911 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
912 info->max_usecs = tsn->usecs;
913 g_ptr_array_add(info->sort_sack2, tsn_s);
914 info->n_sack_chunks_ep2++;
918 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
920 store = g_malloc(sizeof (address));
921 store->type = tmp_info.src.type;
922 store->len = tmp_info.src.len;
923 addr = g_malloc(tmp_info.src.len);
924 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
926 info = add_address(store, info, 1);
927 store = g_malloc(sizeof (address));
928 store->type = tmp_info.dst.type;
929 store->len = tmp_info.dst.len;
930 addr = g_malloc(tmp_info.dst.len);
931 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
933 info = add_address(store, info, 2);
934 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
935 if (datachunk == TRUE)
936 info->tsn1 = g_list_prepend(info->tsn1, tsn);
937 if (sackchunk == TRUE)
938 info->sack2 = g_list_prepend(info->sack2, sack);
939 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
943 error = g_malloc(sizeof(sctp_error_info_t));
944 error->frame_number = pinfo->fd->num;
946 error->chunk_info[0] = '\0';
947 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
948 g_strlcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"), 200);
950 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
951 g_strlcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"), 200);
952 error->info_text = "INFOS";
953 info->error_info_list = g_list_append(info->error_info_list, error);
956 } /* endif (!info) */
959 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
960 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
961 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
962 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
963 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
966 tsn = g_malloc(sizeof(tsn_t));
967 sack = g_malloc(sizeof(tsn_t));
972 sack->src.type = tsn->src.type = tmp_info.src.type;
973 sack->src.len = tsn->src.len = tmp_info.src.len;
974 addr = g_malloc(tmp_info.src.len);
975 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
976 tsn->src.data = addr;
977 addr = g_malloc(tmp_info.src.len);
978 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
979 sack->src.data = addr;
980 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
981 sack->dst.len = tsn->dst.len = tmp_info.dst.len;
982 addr = g_malloc(tmp_info.dst.len);
983 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
984 tsn->dst.data = addr;
985 addr = g_malloc(tmp_info.dst.len);
986 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
987 sack->dst.data = addr;
988 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
989 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
990 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
991 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
992 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
994 if (tsn->secs < info->min_secs)
996 info->min_secs = tsn->secs;
997 info->min_usecs = tsn->usecs;
999 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1000 info->min_usecs = tsn->usecs;
1002 if (tsn->secs > info->max_secs)
1004 info->max_secs = tsn->secs;
1005 info->max_usecs = tsn->usecs;
1007 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1008 info->max_usecs = tsn->usecs;
1010 sack->frame_number = tsn->frame_number = pinfo->fd->num;
1012 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1014 store = g_malloc(sizeof (address));
1015 store->type = tmp_info.src.type;
1016 store->len = tmp_info.src.len;
1017 addr = g_malloc(tmp_info.src.len);
1018 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1021 if (info->direction == 1)
1022 info = add_address(store, info, 1);
1023 else if (info->direction == 2)
1024 info = add_address(store, info, 2);
1026 store = g_malloc(sizeof (address));
1027 store->type = tmp_info.dst.type;
1028 store->len = tmp_info.dst.len;
1029 addr = g_malloc(tmp_info.dst.len);
1030 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1033 if (info->direction == 1)
1034 info = add_address(store, info, 2);
1035 else if (info->direction == 2)
1036 info = add_address(store, info, 1);
1038 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1039 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1041 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1043 if (info->direction == 2)
1045 if (tsnumber < info->min_tsn2)
1046 info->min_tsn2 = tsnumber;
1047 if (tsnumber > info->max_tsn2)
1048 info->max_tsn2 = tsnumber;
1049 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1050 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1051 /*info->initack_dir=2;*/
1052 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1054 else if (info->direction == 1)
1056 if (tsnumber < info->min_tsn1)
1057 info->min_tsn1 = tsnumber;
1058 if (tsnumber > info->max_tsn1)
1059 info->max_tsn1 = tsnumber;
1060 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1061 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1062 /*info->initack_dir=1;*/
1063 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1066 idx = tvb_get_guint8(sctp_info->tvb[0],0);
1067 if (idx > UPPER_BOUND_CHUNK_TYPE)
1068 idx = OTHER_CHUNKS_INDEX;
1069 info->chunk_count[idx]++;
1070 if (info->direction == 1)
1071 info->ep1_chunk_count[idx]++;
1073 info->ep2_chunk_count[idx]++;
1074 info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
1075 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1077 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1078 if (type == IPV4ADDRESS_PARAMETER_ID)
1080 store = g_malloc(sizeof (address));
1081 store->type = AT_IPv4;;
1083 store->data = g_malloc(4);
1084 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1085 info = add_address(store, info, info->direction);
1087 else if (type == IPV6ADDRESS_PARAMETER_ID)
1089 store = g_malloc(sizeof (address));
1090 store->type = AT_IPv6;;
1092 store->data = g_malloc(16);
1093 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1094 info = add_address(store, info, info->direction);
1097 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1099 info->initack = TRUE;
1100 info->initack_dir = info->direction;
1103 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1110 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1111 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1112 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
1113 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
1115 sack = g_malloc(sizeof(tsn_t));
1117 sack->first_tsn = 0;
1118 tsn = g_malloc(sizeof(tsn_t));
1122 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1124 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
1125 if (idx > UPPER_BOUND_CHUNK_TYPE)
1126 idx = OTHER_CHUNKS_INDEX;
1128 info->chunk_count[idx]++;
1129 if (info->direction == 1)
1130 info->ep1_chunk_count[idx]++;
1132 info->ep2_chunk_count[idx]++;
1133 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
1135 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1137 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1138 if (tsn->first_tsn == 0)
1139 tsn->first_tsn = tsnumber;
1140 t_s_n = g_malloc(16);
1141 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1142 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1144 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1145 info->n_data_chunks++;
1146 info->n_data_bytes+=length;
1147 tsn_s = g_malloc(sizeof(struct tsn_sort));
1148 tsn_s->tsnumber = tsnumber;
1149 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1150 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1152 tsn_s->framenumber = framenumber;
1153 tsn_s->length = length;
1155 if (tsn->secs < info->min_secs)
1157 info->min_secs = tsn->secs;
1158 info->min_usecs = tsn->usecs;
1160 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1161 info->min_usecs = tsn->usecs;
1163 if (tsn->secs > info->max_secs)
1165 info->max_secs = tsn->secs;
1166 info->max_usecs = tsn->usecs;
1168 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1169 info->max_usecs = tsn->usecs;
1171 if (info->direction == 1)
1173 if(tsnumber < info->min_tsn1)
1174 info->min_tsn1 = tsnumber;
1175 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1177 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1178 info->n_data_chunks_ep1++;
1179 info->n_data_bytes_ep1 += length;
1181 if(tsnumber > info->max_tsn1)
1183 info->max_tsn1 = tsnumber;
1184 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1185 info->n_data_chunks_ep1++;
1186 info->n_data_bytes_ep1 += length;
1188 if (info->init == FALSE)
1189 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1190 if (info->initack == FALSE)
1191 info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1193 g_ptr_array_add(info->sort_tsn1, tsn_s);
1194 info->n_array_tsn1++;
1196 else if (info->direction == 2)
1199 if(tsnumber < info->min_tsn2)
1200 info->min_tsn2 = tsnumber;
1202 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1204 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1205 info->n_data_chunks_ep2++;
1206 info->n_data_bytes_ep2+=length;
1208 if(tsnumber > info->max_tsn2)
1210 info->max_tsn2 = tsnumber;
1211 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1212 info->n_data_chunks_ep2++;
1213 info->n_data_bytes_ep2+=length;
1215 if (info->init == FALSE)
1216 info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1217 if (info->initack == FALSE)
1218 info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1220 g_ptr_array_add(info->sort_tsn2, tsn_s);
1221 info->n_array_tsn2++;
1224 else if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1225 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID))
1227 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1228 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1229 if (sack->first_tsn == 0)
1230 sack->first_tsn = tsnumber;
1231 t_s_n = g_malloc(length);
1232 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1233 sack->tsns = g_list_append(sack->tsns, t_s_n);
1235 tsn_s = g_malloc(sizeof(struct tsn_sort));
1236 tsn_s->tsnumber = tsnumber;
1237 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1238 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1240 tsn_s->framenumber = framenumber;
1241 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1243 if (tsn->secs < info->min_secs)
1245 info->min_secs = tsn->secs;
1246 info->min_usecs = tsn->usecs;
1248 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1249 info->min_usecs = tsn->usecs;
1251 if (tsn->secs > info->max_secs)
1253 info->max_secs = tsn->secs;
1254 info->max_usecs = tsn->usecs;
1256 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1257 info->max_usecs = tsn->usecs;
1260 if (info->direction == 2)
1262 if(tsnumber < info->min_tsn1)
1263 info->min_tsn1 = tsnumber;
1264 if(tsnumber > info->max_tsn1)
1265 info->max_tsn1 = tsnumber;
1266 if (tsn_s->length > info->max_window1)
1267 info->max_window1 = tsn_s->length;
1268 g_ptr_array_add(info->sort_sack1, tsn_s);
1269 info->n_sack_chunks_ep1++;
1271 else if (info->direction == 1)
1274 if(tsnumber < info->min_tsn2)
1275 info->min_tsn2 = tsnumber;
1276 if(tsnumber > info->max_tsn2)
1277 info->max_tsn2 = tsnumber;
1278 if (tsn_s->length > info->max_window2)
1279 info->max_window2 = tsn_s->length;
1280 g_ptr_array_add(info->sort_sack2, tsn_s);
1281 info->n_sack_chunks_ep2++;
1288 if (datachunk == TRUE)
1290 if (info->direction == 1)
1291 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1292 else if (info->direction == 2)
1293 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1295 if (sackchunk == TRUE)
1297 if (info->direction == 1)
1298 info->sack2 = g_list_prepend(info->sack2, sack);
1299 else if(info->direction == 2)
1300 info->sack1 = g_list_prepend(info->sack1, sack);
1302 info->n_tvbs += sctp_info->number_of_tvbs;
1303 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1304 info = calc_checksum(sctp_info, info);
1311 /****************************************************************************/
1313 remove_tap_listener_sctp_stat(void)
1315 if (sctp_tapinfo_struct.is_registered) {
1316 protect_thread_critical_region();
1317 remove_tap_listener(&sctp_tapinfo_struct);
1318 unprotect_thread_critical_region();
1319 sctp_tapinfo_struct.is_registered = FALSE;
1324 void sctp_stat_scan(void)
1326 if (!sctp_tapinfo_struct.is_registered)
1327 register_tap_listener_sctp_stat();
1330 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1332 return &sctp_tapinfo_struct;
1336 static void sctp_update(void *dummy _U_)
1338 if (get_stat_dlg()!=NULL)
1339 sctp_stat_dlg_update();
1343 register_tap_listener_sctp_stat(void)
1345 GString *error_string;
1347 if (!sctp_tapinfo_struct.is_registered)
1349 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, sctp_update))) {
1350 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
1351 g_string_free(error_string, TRUE);
1354 sctp_tapinfo_struct.is_registered=TRUE;