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 "ui/simple_dialog.h"
41 #include "ui/gtk/dlg_utils.h"
42 #include "ui/gtk/sctp_stat.h"
43 #include "ui/gtk/main.h"
45 #define SCTP_ABORT_CHUNK_T_BIT 0x01
47 #define PARAMETER_TYPE_LENGTH 2
48 #define PARAMETER_LENGTH_LENGTH 2
49 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
51 #define PARAMETER_HEADER_OFFSET 0
52 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
53 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
54 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
56 #define IPV6_ADDRESS_LENGTH 16
57 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
58 #define IPV4_ADDRESS_LENGTH 4
59 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
60 #define IPV4ADDRESS_PARAMETER_ID 0x0005
61 #define IPV6ADDRESS_PARAMETER_ID 0x0006
63 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
64 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
65 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
66 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
67 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
69 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
70 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
71 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
72 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
73 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
74 INIT_CHUNK_INITIAL_TSN_LENGTH)
75 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
76 CHUNK_FLAGS_LENGTH + \
78 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
79 INIT_CHUNK_INITIAL_TSN_LENGTH )
81 static const value_string chunk_type_values[] = {
82 { SCTP_DATA_CHUNK_ID, "DATA" },
83 { SCTP_INIT_CHUNK_ID, "INIT" },
84 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
85 { SCTP_SACK_CHUNK_ID, "SACK" },
86 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
87 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
88 { SCTP_ABORT_CHUNK_ID, "ABORT" },
89 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
90 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
91 { SCTP_ERROR_CHUNK_ID, "ERROR" },
92 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
93 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
94 { SCTP_ECNE_CHUNK_ID, "ECNE" },
95 { SCTP_CWR_CHUNK_ID, "CWR" },
96 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
97 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
98 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
99 { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
100 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
101 { SCTP_IETF_EXT, "IETF_EXTENSION" },
102 { SCTP_NR_SACK_CHUNK_ID, "NR_SACK" },
103 { SCTP_AUTH_CHUNK_ID, "AUTH" },
107 #define FORWARD_STREAM 0
108 #define BACKWARD_STREAM 1
109 #define FORWARD_ADD_FORWARD_VTAG 2
110 #define BACKWARD_ADD_FORWARD_VTAG 3
111 #define BACKWARD_ADD_BACKWARD_VTAG 4
112 #define ADDRESS_FORWARD_STREAM 5
113 #define ADDRESS_BACKWARD_STREAM 6
114 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
115 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
116 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
117 #define ASSOC_NOT_FOUND 10
119 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
122 void free_first(gpointer data, gpointer user_data _U_)
127 static void tsn_free(gpointer data, gpointer user_data _U_)
131 tsn = (tsn_t *) data;
132 if (tsn->tsns != NULL)
134 g_list_foreach(tsn->tsns, free_first, NULL);
135 g_list_free(tsn->tsns);
141 static void reset(void *arg)
143 sctp_allassocs_info_t *tapdata = arg;
145 sctp_assoc_info_t * info;
147 list = g_list_first(tapdata->assoc_info_list);
150 info = (sctp_assoc_info_t *) (list->data);
152 if (info->addr1 != NULL)
154 g_list_foreach(info->addr1, free_first, NULL);
155 g_list_free(info->addr1);
159 if (info->addr2 != NULL)
161 g_list_foreach(info->addr2,free_first, NULL);
162 g_list_free(info->addr2);
166 if (info->error_info_list != NULL)
168 g_list_foreach(info->error_info_list, free_first, NULL);
169 g_list_free(info->error_info_list);
170 info->error_info_list = NULL;
173 if (info->frame_numbers != NULL)
175 g_list_free(info->frame_numbers);
176 info->frame_numbers = NULL;
179 if (info->tsn1 != NULL)
181 g_list_foreach(info->tsn1, tsn_free, NULL);
182 g_list_free(info->tsn1);
186 if (info->tsn2 != NULL)
188 g_list_foreach(info->tsn2, tsn_free, NULL);
189 g_list_free(info->tsn2);
193 if (info->sack1 != NULL)
195 g_list_foreach(info->sack1, tsn_free, NULL);
196 g_list_free(info->sack1);
200 if (info->sack2 != NULL)
202 g_list_foreach(info->sack2, tsn_free, NULL);
203 g_list_free(info->sack2);
207 if (info->sort_tsn1 != NULL)
208 g_ptr_array_free(info->sort_tsn1, TRUE);
210 if (info->sort_tsn2 != NULL)
211 g_ptr_array_free(info->sort_tsn2, TRUE);
213 if (info->sort_sack1 != NULL)
214 g_ptr_array_free(info->sort_sack1, TRUE);
216 if (info->sort_sack2 != NULL)
217 g_ptr_array_free(info->sort_sack2, TRUE);
219 if (info->min_max != NULL)
221 g_slist_foreach(info->min_max, free_first, NULL);
222 info->min_max = NULL;
226 list = g_list_next(list);
228 g_list_free(tapdata->assoc_info_list);
229 tapdata->sum_tvbs = 0;
230 tapdata->assoc_info_list = NULL;
234 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
238 if (check_data->adler32_calculated)
240 data->n_adler32_calculated++;
241 if (check_data->adler32_correct)
242 data->n_adler32_correct++;
244 if (check_data->crc32c_calculated)
246 data->n_crc32c_calculated++;
247 if (check_data->crc32c_correct)
248 data->n_crc32c_correct++;
250 if (data->n_adler32_calculated > 0)
252 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
254 g_strlcpy(data->checksum_type,"ADLER32",8);
255 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
260 if (data->n_crc32c_calculated>0)
262 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
264 g_strlcpy(data->checksum_type,"CRC32C",8);
265 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
272 g_strlcpy(data->checksum_type,"UNKNOWN",8);
273 data->n_checksum_errors=0;
281 /* XXX: Some versions of gcc warn about "breaking strict aliasing rules"
282 for 'a' in the following (given the way this function is called).
283 As a workaround we'll define the function parameters to match
284 how this function is actually called. */
286 static gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
288 const struct _sctp_assoc_info* a = aa;
289 const struct _sctp_assoc_info* b = bb;
291 return(FORWARD_STREAM);
294 static gint sctp_assoc_vtag_cmp(const sctp_tmp_info_t *a, const sctp_assoc_info_t *b)
297 if (a == NULL || b == NULL)
298 return(ASSOC_NOT_FOUND);
300 if ((a->port1 == b->port1) &&
301 (a->port2 == b->port2) &&
302 (a->verification_tag1 == b->verification_tag1) && a->verification_tag1==0 && a->initiate_tag != 0 &&
303 (a->initiate_tag != b->initiate_tag ))
304 return(ASSOC_NOT_FOUND); /* two INITs that belong to different assocs */
307 if ((a->port1 == b->port1) &&
308 (a->port2 == b->port2) &&
309 (a->verification_tag1 == b->verification_tag1) &&
310 ((a->verification_tag1 != 0 ||
311 (b->verification_tag2 != 0))))
312 return(FORWARD_STREAM);
314 /* ABORT, vtag reflected */
315 if ((a->port1 == b->port1) &&
316 (a->port2 == b->port2) &&
317 (a->verification_tag2 == b->verification_tag2) &&
318 (a->verification_tag1 == 0 && b->verification_tag1 != 0))
319 return(FORWARD_STREAM);
321 if ((a->port1 == b->port2) &&
322 (a->port2 == b->port1) &&
323 (a->verification_tag1 == b->verification_tag2) &&
324 (a->verification_tag1 != 0))
325 return(BACKWARD_STREAM);
327 if ((a->port1 == b->port2) &&
328 (a->port2 == b->port1) &&
329 (a->verification_tag2 == b->verification_tag1) &&
330 (a->verification_tag2 != 0))
331 return(BACKWARD_STREAM);
333 /* ABORT, vtag reflected */
334 if ((a->port1 == b->port2) &&
335 (a->port2 == b->port1) &&
336 (a->verification_tag2 == b->verification_tag1) &&
337 (a->verification_tag1 == 0 && b->verification_tag2 != 0))
338 return(BACKWARD_STREAM);
340 /*forward stream verifivation tag can be added*/
341 if ((a->port1 == b->port1) &&
342 (a->port2 == b->port2) &&
343 (a->verification_tag1 != 0) &&
344 (b->verification_tag1 == 0) &&
345 (b->verification_tag2 !=0))
346 return (FORWARD_ADD_FORWARD_VTAG);
348 if ((a->port1 == b->port2) &&
349 (a->port2 == b->port1) &&
350 (a->verification_tag1 == b->verification_tag2) &&
351 (b->verification_tag1 == 0))
352 return (BACKWARD_ADD_FORWARD_VTAG);
354 /*backward stream verification tag can be added */
355 if ((a->port1 == b->port2) &&
356 (a->port2 == b->port1) &&
357 (a->verification_tag1 !=0) &&
358 (b->verification_tag1 != 0) &&
359 (b->verification_tag2 == 0))
360 return(BACKWARD_ADD_BACKWARD_VTAG);
362 return(ASSOC_NOT_FOUND);
365 static sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
367 sctp_allassocs_info_t *assoc_info;
368 sctp_assoc_info_t *info = NULL;
372 assoc_info = &sctp_tapinfo_struct;
373 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
377 cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
379 /*if (cmp==ASSOC_NOT_FOUND)
381 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
386 info = (sctp_assoc_info_t*)(list->data);
389 case BACKWARD_STREAM:
390 info = (sctp_assoc_info_t*)(list->data);
393 case FORWARD_ADD_FORWARD_VTAG:
394 info = (sctp_assoc_info_t*)(list->data);
395 info->verification_tag1=needle->verification_tag1;
398 case BACKWARD_ADD_FORWARD_VTAG:
399 info = (sctp_assoc_info_t*)(list->data);
400 info->verification_tag1=needle->verification_tag1;
403 case BACKWARD_ADD_BACKWARD_VTAG:
404 info = (sctp_assoc_info_t*)(list->data);
405 info->verification_tag2=needle->verification_tag1;
408 case ADDRESS_FORWARD_STREAM:
409 info = (sctp_assoc_info_t*)(list->data);
411 info->check_address=TRUE;
413 case ADDRESS_BACKWARD_STREAM:
414 info = (sctp_assoc_info_t*)(list->data);
416 info->check_address=TRUE;
418 case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
419 info = (sctp_assoc_info_t*)(list->data);
420 info->verification_tag1=needle->verification_tag1;
422 info->check_address=TRUE;
424 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
425 info = (sctp_assoc_info_t*)(list->data);
426 info->verification_tag1=needle->verification_tag1;
428 info->check_address=TRUE;
430 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
431 info = (sctp_assoc_info_t*)(list->data);
432 info->verification_tag2=needle->verification_tag1;
434 info->check_address=TRUE;
438 list = g_list_previous(list);
444 static sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
448 sctp_addr_chunk *ch=NULL;
452 list = g_list_first(info->addr_chunk_count);
456 ch = (sctp_addr_chunk *)(list->data);
457 if (ch->direction == direction)
459 v = (address *) (ch->addr);
460 if (ADDRESSES_EQUAL(vadd, v))
462 if (IS_SCTP_CHUNK_TYPE(type))
463 ch->addr_count[type]++;
465 ch->addr_count[OTHER_CHUNKS_INDEX]++;
470 list = g_list_next(list);
474 list = g_list_next(list);
476 ch = g_malloc(sizeof(sctp_addr_chunk));
477 ch->direction = direction;
478 ch->addr = g_malloc(sizeof(address));
479 ch->addr->type = vadd->type;
480 ch->addr->len = vadd->len;
481 dat = g_malloc(vadd->len);
482 memcpy(dat, vadd->data, vadd->len);
483 ch->addr->data = dat;
484 for (i=0; i < NUM_CHUNKS; i++)
485 ch->addr_count[i] = 0;
487 if (IS_SCTP_CHUNK_TYPE(type))
488 ch->addr_count[type]++;
490 ch->addr_count[OTHER_CHUNKS_INDEX]++;
492 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
496 static sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
502 list = g_list_first(info->addr1);
504 list = g_list_first(info->addr2);
508 v = (address *) (list->data);
509 if (ADDRESSES_EQUAL(vadd, v)) {
513 list = g_list_next(list);
517 info->addr1 = g_list_append(info->addr1, vadd);
518 else if (direction==2)
519 info->addr2 = g_list_append(info->addr2, vadd);
525 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
527 struct _sctp_info *sctp_info;
528 guint32 chunk_number = 0, tsnumber,framenumber;
529 sctp_tmp_info_t tmp_info;
530 sctp_assoc_info_t *info = NULL;
531 sctp_error_info_t *error = NULL;
532 guint16 type, length;
533 address *store = NULL;
536 guint8 *t_s_n = NULL;
537 gboolean sackchunk = FALSE;
538 gboolean datachunk = FALSE;
539 struct tsn_sort *tsn_s;
544 sctp_info = (struct _sctp_info *) data;
546 framenumber=pinfo->fd->num;
548 type = sctp_info->ip_src.type;
552 tmp_info.src.type = AT_IPv4;
553 tmp_info.src.len = 4;
555 else if (type == AT_IPv6)
557 tmp_info.src.type = AT_IPv6;
558 tmp_info.src.len = 16;
562 tmp_info.src.type = AT_NONE;
563 tmp_info.src.len = 0;
566 addr = g_malloc(tmp_info.src.len);
567 memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
568 tmp_info.src.data = addr;
570 type = sctp_info->ip_dst.type;
574 tmp_info.dst.type = AT_IPv4;
575 tmp_info.dst.len = 4;
577 else if (type == AT_IPv6)
579 tmp_info.dst.type = AT_IPv6;
580 tmp_info.dst.len = 16;
584 tmp_info.dst.type = AT_NONE;
585 tmp_info.dst.len = 0;
588 addr = g_malloc(tmp_info.dst.len);
589 memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
590 tmp_info.dst.data = addr;
592 tmp_info.port1 = sctp_info->sport;
593 tmp_info.port2 = sctp_info->dport;
595 if (sctp_info->vtag_reflected)
597 tmp_info.verification_tag2 = sctp_info->verification_tag;
598 tmp_info.verification_tag1 = 0;
602 tmp_info.verification_tag1 = sctp_info->verification_tag;
603 tmp_info.verification_tag2 = 0;
606 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
608 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
612 tmp_info.initiate_tag = 0;
615 info = find_assoc(&tmp_info);
618 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
619 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
621 if (sctp_info->number_of_tvbs > 0)
623 info = g_malloc(sizeof(sctp_assoc_info_t));
624 memset(info, 0, sizeof(sctp_assoc_info_t));
625 info->src.type = tmp_info.src.type;
626 info->src.len = tmp_info.src.len;
627 addr = g_malloc(tmp_info.dst.len);
628 memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
629 info->src.data = addr;
630 info->dst.type = tmp_info.dst.type;
631 info->dst.len = tmp_info.dst.len;
632 addr = g_malloc(tmp_info.dst.len);
633 memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
634 info->dst.data = addr;
635 info->port1 = tmp_info.port1;
636 info->port2 = tmp_info.port2;
637 info->verification_tag1 = tmp_info.verification_tag1;
638 info->verification_tag2 = tmp_info.verification_tag2;
639 info->initiate_tag = tmp_info.initiate_tag;
640 info->n_tvbs = tmp_info.n_tvbs;
642 info->initack = FALSE;
643 info->check_address = FALSE;
645 info = calc_checksum(sctp_info, info);
647 info->error_info_list = NULL;
648 info->min_secs = 0xffffffff;
649 info->min_usecs = 0xffffffff;
652 info->min_tsn2 = 0xFFFFFFFF;
653 info->min_tsn1 = 0xffffffff;
656 info->max_bytes1 = 0;
657 info->max_bytes2 = 0;
658 info->n_data_chunks = 0;
659 info->n_data_bytes = 0;
660 info->n_data_chunks_ep1 = 0;
661 info->n_data_bytes_ep1 = 0;
662 info->n_data_chunks_ep2 = 0;
663 info->n_data_bytes_ep2 = 0;
664 info->n_sack_chunks_ep1 = 0;
665 info->n_sack_chunks_ep2 = 0;
666 info->n_array_tsn1 = 0;
667 info->n_array_tsn2 = 0;
668 info->max_window1 = 0;
669 info->max_window2 = 0;
670 info->min_max = NULL;
671 info->sort_tsn1 = g_ptr_array_new();
672 info->sort_tsn2 = g_ptr_array_new();
673 info->sort_sack1 = g_ptr_array_new();
674 info->sort_sack2 = g_ptr_array_new();
675 for (i=0; i < NUM_CHUNKS; i++)
677 info->chunk_count[i] = 0;
678 info->ep1_chunk_count[i] = 0;
679 info->ep2_chunk_count[i] = 0;
681 info->addr_chunk_count = NULL;
683 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
684 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
685 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
686 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
687 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
689 tsn = g_malloc(sizeof(tsn_t));
690 sack = g_malloc(sizeof(tsn_t));
695 sack->src.type=tsn->src.type = tmp_info.src.type;
696 sack->src.len=tsn->src.len = tmp_info.src.len;
697 addr = g_malloc(tmp_info.src.len);
698 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
699 tsn->src.data = addr;
700 addr = g_malloc(tmp_info.src.len);
701 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
702 sack->src.data = addr;
703 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
704 sack->dst.len =tsn->dst.len = tmp_info.dst.len;
705 addr = g_malloc(tmp_info.dst.len);
706 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
707 tsn->dst.data = addr;
708 addr = g_malloc(tmp_info.dst.len);
709 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
710 sack->dst.data = addr;
711 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
712 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
713 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
714 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
715 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
717 if (tsn->secs < info->min_secs)
719 info->min_secs = tsn->secs;
720 info->min_usecs = tsn->usecs;
722 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
723 info->min_usecs = tsn->usecs;
725 if (tsn->secs > info->max_secs)
727 info->max_secs = tsn->secs;
728 info->max_usecs = tsn->usecs;
730 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
731 info->max_usecs = tsn->usecs;
734 sack->frame_number = tsn->frame_number = pinfo->fd->num;
736 if ((tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) || (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID))
738 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
739 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
740 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
741 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
742 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
744 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
745 if (type == IPV4ADDRESS_PARAMETER_ID)
747 store = g_malloc(sizeof (address));
748 store->type = AT_IPv4;;
750 store->data = g_malloc(4);
751 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
752 info = add_address(store, info, 1);
754 else if (type == IPV6ADDRESS_PARAMETER_ID)
756 store = g_malloc(sizeof (address));
757 store->type = AT_IPv6;;
759 store->data = g_malloc(16);
760 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
761 info = add_address(store, info, 1);
765 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
771 info->initack_dir = 1;
772 info->initack = TRUE;
775 idx = tvb_get_guint8(sctp_info->tvb[0],0);
776 if (!IS_SCTP_CHUNK_TYPE(idx))
777 idx = OTHER_CHUNKS_INDEX;
779 info->chunk_count[idx]++;
780 info->ep1_chunk_count[idx]++;
781 info = add_chunk_count(&tmp_info.src, info, 1, idx);
785 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
786 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
787 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
788 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
789 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
791 tsn = g_malloc(sizeof(tsn_t));
792 sack = g_malloc(sizeof(tsn_t));
798 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
800 idx = tvb_get_guint8(sctp_info->tvb[0],0);
801 if (!IS_SCTP_CHUNK_TYPE(idx))
802 idx = OTHER_CHUNKS_INDEX;
804 info->chunk_count[idx]++;
805 info->ep1_chunk_count[idx]++;
806 info = add_chunk_count(&tmp_info.src, info, 1, idx);
808 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID)
810 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
811 info->n_data_chunks++;
812 info->n_data_bytes+=length;
813 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
814 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
815 if (tsnumber < info->min_tsn1)
816 info->min_tsn1 = tsnumber;
817 if (tsnumber > info->max_tsn1)
819 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
820 info->n_data_chunks_ep1++;
821 info->n_data_bytes_ep1+=length;
822 info->max_tsn1 = tsnumber;
824 if (tsn->first_tsn == 0)
825 tsn->first_tsn = tsnumber;
826 t_s_n = g_malloc(16);
827 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
828 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
830 tsn_s = g_malloc(sizeof(struct tsn_sort));
831 tsn_s->tsnumber = tsnumber;
832 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
833 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
835 tsn_s->framenumber = framenumber;
836 tsn_s->length = length-DATA_CHUNK_HEADER_LENGTH;
837 if (tsn->secs < info->min_secs)
839 info->min_secs = tsn->secs;
840 info->min_usecs = tsn->usecs;
842 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
843 info->min_usecs = tsn->usecs;
845 if (tsn->secs > info->max_secs)
847 info->max_secs = tsn->secs;
848 info->max_usecs = tsn->usecs;
850 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
851 info->max_usecs = tsn->usecs;
852 g_ptr_array_add(info->sort_tsn1, tsn_s);
853 info->n_array_tsn1++;
855 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
856 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
858 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
859 if (tsnumber < info->min_tsn2)
860 info->min_tsn2 = tsnumber;
861 if (tsnumber > info->max_tsn2)
862 info->max_tsn2 = tsnumber;
863 info->n_sack_chunks_ep2++;
864 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
865 if (sack->first_tsn == 0)
866 sack->first_tsn = tsnumber;
867 t_s_n = g_malloc(length);
868 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
869 sack->tsns = g_list_append(sack->tsns, t_s_n);
871 tsn_s = g_malloc(sizeof(struct tsn_sort));
872 tsn_s->tsnumber = tsnumber;
873 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
874 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
876 tsn_s->framenumber = framenumber;
877 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
878 if (tsn_s->length > info->max_window1)
879 info->max_window1 = tsn_s->length;
880 if (tsn->secs < info->min_secs)
882 info->min_secs = tsn->secs;
883 info->min_usecs = tsn->usecs;
885 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
886 info->min_usecs = tsn->usecs;
888 if (tsn->secs > info->max_secs)
890 info->max_secs = tsn->secs;
891 info->max_usecs = tsn->usecs;
893 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
894 info->max_usecs = tsn->usecs;
895 g_ptr_array_add(info->sort_sack2, tsn_s);
896 info->n_sack_chunks_ep2++;
900 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
902 store = g_malloc(sizeof (address));
903 store->type = tmp_info.src.type;
904 store->len = tmp_info.src.len;
905 addr = g_malloc(tmp_info.src.len);
906 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
908 info = add_address(store, info, 1);
909 store = g_malloc(sizeof (address));
910 store->type = tmp_info.dst.type;
911 store->len = tmp_info.dst.len;
912 addr = g_malloc(tmp_info.dst.len);
913 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
915 info = add_address(store, info, 2);
916 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
917 if (datachunk == TRUE)
918 info->tsn1 = g_list_prepend(info->tsn1, tsn);
919 if (sackchunk == TRUE)
920 info->sack2 = g_list_prepend(info->sack2, sack);
921 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
925 error = g_malloc(sizeof(sctp_error_info_t));
926 error->frame_number = pinfo->fd->num;
927 error->chunk_info[0] = '\0';
928 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
929 g_strlcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"), 200);
931 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
932 g_strlcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"), 200);
933 error->info_text = "INFOS";
934 info->error_info_list = g_list_append(info->error_info_list, error);
937 } /* endif (!info) */
940 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
941 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
942 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
943 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
944 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
947 tsn = g_malloc(sizeof(tsn_t));
948 sack = g_malloc(sizeof(tsn_t));
953 sack->src.type = tsn->src.type = tmp_info.src.type;
954 sack->src.len = tsn->src.len = tmp_info.src.len;
955 addr = g_malloc(tmp_info.src.len);
956 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
957 tsn->src.data = addr;
958 addr = g_malloc(tmp_info.src.len);
959 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
960 sack->src.data = addr;
961 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
962 sack->dst.len = tsn->dst.len = tmp_info.dst.len;
963 addr = g_malloc(tmp_info.dst.len);
964 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
965 tsn->dst.data = addr;
966 addr = g_malloc(tmp_info.dst.len);
967 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
968 sack->dst.data = addr;
969 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
970 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
971 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
972 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
973 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID))
975 if (tsn->secs < info->min_secs)
977 info->min_secs = tsn->secs;
978 info->min_usecs = tsn->usecs;
980 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
981 info->min_usecs = tsn->usecs;
983 if (tsn->secs > info->max_secs)
985 info->max_secs = tsn->secs;
986 info->max_usecs = tsn->usecs;
988 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
989 info->max_usecs = tsn->usecs;
991 sack->frame_number = tsn->frame_number = pinfo->fd->num;
993 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
995 store = g_malloc(sizeof (address));
996 store->type = tmp_info.src.type;
997 store->len = tmp_info.src.len;
998 addr = g_malloc(tmp_info.src.len);
999 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1002 if (info->direction == 1)
1003 info = add_address(store, info, 1);
1004 else if (info->direction == 2)
1005 info = add_address(store, info, 2);
1007 store = g_malloc(sizeof (address));
1008 store->type = tmp_info.dst.type;
1009 store->len = tmp_info.dst.len;
1010 addr = g_malloc(tmp_info.dst.len);
1011 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1014 if (info->direction == 1)
1015 info = add_address(store, info, 2);
1016 else if (info->direction == 2)
1017 info = add_address(store, info, 1);
1019 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1020 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1022 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1024 if (info->direction == 2)
1026 if (tsnumber < info->min_tsn2)
1027 info->min_tsn2 = tsnumber;
1028 if (tsnumber > info->max_tsn2)
1029 info->max_tsn2 = tsnumber;
1030 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1031 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1032 /*info->initack_dir=2;*/
1033 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1035 else if (info->direction == 1)
1037 if (tsnumber < info->min_tsn1)
1038 info->min_tsn1 = tsnumber;
1039 if (tsnumber > info->max_tsn1)
1040 info->max_tsn1 = tsnumber;
1041 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1042 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1043 /*info->initack_dir=1;*/
1044 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1047 idx = tvb_get_guint8(sctp_info->tvb[0],0);
1048 if (!IS_SCTP_CHUNK_TYPE(idx))
1049 idx = OTHER_CHUNKS_INDEX;
1050 info->chunk_count[idx]++;
1051 if (info->direction == 1)
1052 info->ep1_chunk_count[idx]++;
1054 info->ep2_chunk_count[idx]++;
1055 info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
1056 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1058 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1059 if (type == IPV4ADDRESS_PARAMETER_ID)
1061 store = g_malloc(sizeof (address));
1062 store->type = AT_IPv4;;
1064 store->data = g_malloc(4);
1065 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1066 info = add_address(store, info, info->direction);
1068 else if (type == IPV6ADDRESS_PARAMETER_ID)
1070 store = g_malloc(sizeof (address));
1071 store->type = AT_IPv6;;
1073 store->data = g_malloc(16);
1074 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1075 info = add_address(store, info, info->direction);
1078 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1080 info->initack = TRUE;
1081 info->initack_dir = info->direction;
1084 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1091 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1092 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1093 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
1094 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID))
1096 sack = g_malloc(sizeof(tsn_t));
1098 sack->first_tsn = 0;
1099 tsn = g_malloc(sizeof(tsn_t));
1103 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1105 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
1106 if (!IS_SCTP_CHUNK_TYPE(idx))
1107 idx = OTHER_CHUNKS_INDEX;
1109 info->chunk_count[idx]++;
1110 if (info->direction == 1)
1111 info->ep1_chunk_count[idx]++;
1113 info->ep2_chunk_count[idx]++;
1114 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
1116 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1118 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1119 if (tsn->first_tsn == 0)
1120 tsn->first_tsn = tsnumber;
1121 t_s_n = g_malloc(16);
1122 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1123 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1125 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1126 info->n_data_chunks++;
1127 info->n_data_bytes+=length;
1128 tsn_s = g_malloc(sizeof(struct tsn_sort));
1129 tsn_s->tsnumber = tsnumber;
1130 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1131 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1133 tsn_s->framenumber = framenumber;
1134 tsn_s->length = length;
1136 if (tsn->secs < info->min_secs)
1138 info->min_secs = tsn->secs;
1139 info->min_usecs = tsn->usecs;
1141 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1142 info->min_usecs = tsn->usecs;
1144 if (tsn->secs > info->max_secs)
1146 info->max_secs = tsn->secs;
1147 info->max_usecs = tsn->usecs;
1149 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1150 info->max_usecs = tsn->usecs;
1152 if (info->direction == 1)
1154 if(tsnumber < info->min_tsn1)
1155 info->min_tsn1 = tsnumber;
1156 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1158 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1159 info->n_data_chunks_ep1++;
1160 info->n_data_bytes_ep1 += length;
1162 if(tsnumber > info->max_tsn1)
1164 info->max_tsn1 = tsnumber;
1165 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1166 info->n_data_chunks_ep1++;
1167 info->n_data_bytes_ep1 += length;
1169 if (info->init == FALSE)
1170 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1171 if (info->initack == FALSE)
1172 info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1174 g_ptr_array_add(info->sort_tsn1, tsn_s);
1175 info->n_array_tsn1++;
1177 else if (info->direction == 2)
1180 if(tsnumber < info->min_tsn2)
1181 info->min_tsn2 = tsnumber;
1183 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1185 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1186 info->n_data_chunks_ep2++;
1187 info->n_data_bytes_ep2+=length;
1189 if(tsnumber > info->max_tsn2)
1191 info->max_tsn2 = tsnumber;
1192 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1193 info->n_data_chunks_ep2++;
1194 info->n_data_bytes_ep2+=length;
1196 if (info->init == FALSE)
1197 info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1198 if (info->initack == FALSE)
1199 info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1201 g_ptr_array_add(info->sort_tsn2, tsn_s);
1202 info->n_array_tsn2++;
1205 else if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1206 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID))
1208 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1209 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1210 if (sack->first_tsn == 0)
1211 sack->first_tsn = tsnumber;
1212 t_s_n = g_malloc(length);
1213 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1214 sack->tsns = g_list_append(sack->tsns, t_s_n);
1216 tsn_s = g_malloc(sizeof(struct tsn_sort));
1217 tsn_s->tsnumber = tsnumber;
1218 tsn_s->secs = tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1219 tsn_s->usecs = tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1221 tsn_s->framenumber = framenumber;
1222 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1224 if (tsn->secs < info->min_secs)
1226 info->min_secs = tsn->secs;
1227 info->min_usecs = tsn->usecs;
1229 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1230 info->min_usecs = tsn->usecs;
1232 if (tsn->secs > info->max_secs)
1234 info->max_secs = tsn->secs;
1235 info->max_usecs = tsn->usecs;
1237 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1238 info->max_usecs = tsn->usecs;
1241 if (info->direction == 2)
1243 if(tsnumber < info->min_tsn1)
1244 info->min_tsn1 = tsnumber;
1245 if(tsnumber > info->max_tsn1)
1246 info->max_tsn1 = tsnumber;
1247 if (tsn_s->length > info->max_window1)
1248 info->max_window1 = tsn_s->length;
1249 g_ptr_array_add(info->sort_sack1, tsn_s);
1250 info->n_sack_chunks_ep1++;
1252 else if (info->direction == 1)
1255 if(tsnumber < info->min_tsn2)
1256 info->min_tsn2 = tsnumber;
1257 if(tsnumber > info->max_tsn2)
1258 info->max_tsn2 = tsnumber;
1259 if (tsn_s->length > info->max_window2)
1260 info->max_window2 = tsn_s->length;
1261 g_ptr_array_add(info->sort_sack2, tsn_s);
1262 info->n_sack_chunks_ep2++;
1269 if (datachunk == TRUE)
1271 if (info->direction == 1)
1272 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1273 else if (info->direction == 2)
1274 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1276 if (sackchunk == TRUE)
1278 if (info->direction == 1)
1279 info->sack2 = g_list_prepend(info->sack2, sack);
1280 else if(info->direction == 2)
1281 info->sack1 = g_list_prepend(info->sack1, sack);
1283 info->n_tvbs += sctp_info->number_of_tvbs;
1284 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1285 info = calc_checksum(sctp_info, info);
1292 /****************************************************************************/
1294 remove_tap_listener_sctp_stat(void)
1296 if (sctp_tapinfo_struct.is_registered) {
1297 protect_thread_critical_region();
1298 remove_tap_listener(&sctp_tapinfo_struct);
1299 unprotect_thread_critical_region();
1300 sctp_tapinfo_struct.is_registered = FALSE;
1305 void sctp_stat_scan(void)
1307 if (!sctp_tapinfo_struct.is_registered)
1308 register_tap_listener_sctp_stat();
1311 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1313 return &sctp_tapinfo_struct;
1317 static void sctp_update(void *dummy _U_)
1319 if (get_stat_dlg()!=NULL)
1320 sctp_stat_dlg_update();
1324 register_tap_listener_sctp_stat(void)
1326 GString *error_string;
1328 if (!sctp_tapinfo_struct.is_registered)
1330 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, sctp_update))) {
1331 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
1332 g_string_free(error_string, TRUE);
1335 sctp_tapinfo_struct.is_registered=TRUE;