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.
31 #include "simple_dialog.h" /* Both is used for error handling */
33 #include "epan/packet_info.h" /* Needed for packet_info */
34 #include <epan/tap.h> /* Needed for register_tap_listener */
35 #include "dlg_utils.h"
36 #include "compat_macros.h"
39 #include "sctp_stat.h"
41 #include "epan/address.h"
43 #define SCTP_HEARTBEAT_CHUNK_ID 4
44 #define SCTP_HEARTBEAT_ACK_CHUNK_ID 5
45 #define SCTP_ABORT_CHUNK_ID 6
46 #define SCTP_SHUTDOWN_CHUNK_ID 7
47 #define SCTP_SHUTDOWN_ACK_CHUNK_ID 8
48 #define SCTP_ERROR_CHUNK_ID 9
49 #define SCTP_COOKIE_ECHO_CHUNK_ID 10
50 #define SCTP_COOKIE_ACK_CHUNK_ID 11
51 #define SCTP_ECNE_CHUNK_ID 12
52 #define SCTP_CWR_CHUNK_ID 13
53 #define SCTP_SHUTDOWN_COMPLETE_CHUNK_ID 14
54 #define SCTP_FORWARD_TSN_CHUNK_ID 192
55 #define SCTP_ASCONF_ACK_CHUNK_ID 0x80
56 #define SCTP_PKTDROP_CHUNK_ID 0X81
57 #define SCTP_ASCONF_CHUNK_ID 0XC1
58 #define SCTP_IETF_EXT 255
60 #define SCTP_ABORT_CHUNK_T_BIT 0x01
62 #define PARAMETER_TYPE_LENGTH 2
63 #define PARAMETER_LENGTH_LENGTH 2
64 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
66 #define PARAMETER_HEADER_OFFSET 0
67 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
68 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
69 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
71 #define IPV6_ADDRESS_LENGTH 16
72 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
73 #define IPV4_ADDRESS_LENGTH 4
74 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
75 #define IPV4ADDRESS_PARAMETER_ID 0x0005
76 #define IPV6ADDRESS_PARAMETER_ID 0x0006
78 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
79 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
80 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
81 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
82 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
84 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
85 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
86 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
87 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
88 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
89 INIT_CHUNK_INITIAL_TSN_LENGTH)
90 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
91 CHUNK_FLAGS_LENGTH + \
93 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
94 INIT_CHUNK_INITIAL_TSN_LENGTH )
96 static const value_string chunk_type_values[] = {
97 { SCTP_DATA_CHUNK_ID, "DATA" },
98 { SCTP_INIT_CHUNK_ID, "INIT" },
99 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
100 { SCTP_SACK_CHUNK_ID, "SACK" },
101 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
102 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
103 { SCTP_ABORT_CHUNK_ID, "ABORT" },
104 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
105 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
106 { SCTP_ERROR_CHUNK_ID, "ERROR" },
107 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
108 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
109 { SCTP_ECNE_CHUNK_ID, "ECNE" },
110 { SCTP_CWR_CHUNK_ID, "CWR" },
111 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
112 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
113 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
114 { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
115 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
116 { SCTP_IETF_EXT, "IETF_EXTENSION" },
120 #define FORWARD_STREAM 0
121 #define BACKWARD_STREAM 1
122 #define FORWARD_ADD_FORWARD_VTAG 2
123 #define BACKWARD_ADD_FORWARD_VTAG 3
124 #define BACKWARD_ADD_BACKWARD_VTAG 4
125 #define ADDRESS_FORWARD_STREAM 5
126 #define ADDRESS_BACKWARD_STREAM 6
127 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
128 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
129 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
130 #define ASSOC_NOT_FOUND 10
132 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
135 void free_first(gpointer data, gpointer user_data _U_)
140 static void tsn_free(gpointer data, gpointer user_data _U_)
144 tsn = (tsn_t *) data;
145 if (tsn->tsns != NULL)
147 g_list_foreach(tsn->tsns, free_first, NULL);
148 g_list_free(tsn->tsns);
156 sctp_allassocs_info_t *tapdata = arg;
158 sctp_assoc_info_t * info;
160 list = g_list_first(tapdata->assoc_info_list);
163 info = (sctp_assoc_info_t *) (list->data);
165 if (info->addr1 != NULL)
167 g_list_foreach(info->addr1, free_first, NULL);
168 g_list_free(info->addr1);
172 if (info->addr2 != NULL)
174 g_list_foreach(info->addr2,free_first, NULL);
175 g_list_free(info->addr2);
179 if (info->error_info_list != NULL)
181 g_list_foreach(info->error_info_list, free_first, NULL);
182 g_list_free(info->error_info_list);
183 info->error_info_list = NULL;
186 if (info->frame_numbers != NULL)
188 g_list_free(info->frame_numbers);
189 info->frame_numbers = NULL;
192 if (info->tsn1 != NULL)
194 g_list_foreach(info->tsn1, tsn_free, NULL);
195 g_list_free(info->tsn1);
199 if (info->tsn2 != NULL)
201 g_list_foreach(info->tsn2, tsn_free, NULL);
202 g_list_free(info->tsn2);
206 if (info->sack1 != NULL)
208 g_list_foreach(info->sack1, tsn_free, NULL);
209 g_list_free(info->sack1);
213 if (info->sack2 != NULL)
215 g_list_foreach(info->sack2, tsn_free, NULL);
216 g_list_free(info->sack2);
220 if (info->sort_tsn1 != NULL)
221 g_ptr_array_free(info->sort_tsn1, TRUE);
223 if (info->sort_tsn2 != NULL)
224 g_ptr_array_free(info->sort_tsn2, TRUE);
226 if (info->sort_sack1 != NULL)
227 g_ptr_array_free(info->sort_sack1, TRUE);
229 if (info->sort_sack2 != NULL)
230 g_ptr_array_free(info->sort_sack2, TRUE);
232 if (info->min_max != NULL)
234 g_slist_foreach(info->min_max, free_first, NULL);
235 info->min_max = NULL;
239 list = g_list_next(list);
241 g_list_free(tapdata->assoc_info_list);
242 tapdata->sum_tvbs = 0;
243 tapdata->assoc_info_list = NULL;
247 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
251 if (check_data->adler32_calculated)
253 data->n_adler32_calculated++;
254 if (check_data->adler32_correct)
255 data->n_adler32_correct++;
257 if (check_data->crc32c_calculated)
259 data->n_crc32c_calculated++;
260 if (check_data->crc32c_correct)
261 data->n_crc32c_correct++;
263 if (data->n_adler32_calculated > 0)
265 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
267 strcpy(data->checksum_type,"ADLER32");
268 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
273 if (data->n_crc32c_calculated>0)
275 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
277 strcpy(data->checksum_type,"CRC32C");
278 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
285 strcpy(data->checksum_type,"UNKNOWN");
286 data->n_checksum_errors=0;
294 static gint sctp_assoc_vtag_cmp(gconstpointer aa, gconstpointer bb)
297 const struct _sctp_assoc_info* a = aa;
298 const struct _sctp_assoc_info* b = bb;
301 return(FORWARD_STREAM);
303 if (a == NULL || b == NULL)
304 return(ASSOC_NOT_FOUND);
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 if ((a->port1 == b->port2) &&
315 (a->port2 == b->port1) &&
316 (a->verification_tag1 == b->verification_tag2) &&
317 (a->verification_tag1 != 0))
318 return(BACKWARD_STREAM);
320 if ((a->port1 == b->port2) &&
321 (a->port2 == b->port1) &&
322 (a->verification_tag2 == b->verification_tag1) &&
323 (a->verification_tag2 != 0))
324 return(BACKWARD_STREAM);
326 /*forward stream verifivation tag can be added*/
327 if ((a->port1 == b->port1) &&
328 (a->port2 == b->port2) &&
329 (a->verification_tag1 != 0) &&
330 (b->verification_tag1 == 0) &&
331 (b->verification_tag2 !=0))
332 return (FORWARD_ADD_FORWARD_VTAG);
334 if ((a->port1 == b->port2) &&
335 (a->port2 == b->port1) &&
336 (a->verification_tag1 == b->verification_tag2) &&
337 (b->verification_tag1 == 0))
338 return (BACKWARD_ADD_FORWARD_VTAG);
340 /*backward stream verification tag can be added */
341 if ((a->port1 == b->port2) &&
342 (a->port2 == b->port1) &&
343 (a->verification_tag1 !=0) &&
344 (b->verification_tag1 != 0) &&
345 (b->verification_tag2 == 0))
346 return(BACKWARD_ADD_BACKWARD_VTAG);
348 return(ASSOC_NOT_FOUND);
352 static gint sctp_assoc_address_cmp(gconstpointer aa, gconstpointer bb)
354 GList *srclist, *dstlist;
355 const struct _sctp_tmp_info* a = aa;
356 const struct _sctp_assoc_info* b = bb;
357 address *srcstore=NULL;
358 address *dststore=NULL;
361 gboolean src_v4=FALSE;
362 gboolean src_v6=FALSE;
363 gboolean dst_v4=FALSE;
364 gboolean dst_v6=FALSE;
367 src = g_malloc(sizeof(address));
368 if (a->src.type == AT_IPv4)
374 else if (a->src.type==AT_IPv6)
380 addr = g_malloc(src->len);
381 memcpy(addr, a->src.data, src->len);
384 dst = g_malloc(sizeof(address));
385 if (a->dst.type == AT_IPv4)
391 else if (a->dst.type==AT_IPv6)
397 addr = g_malloc(dst->len);
398 memcpy(addr, a->dst.data, dst->len);
401 srclist = g_list_first(b->addr1);
404 srcstore = (address *) (srclist->data);
405 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
407 if (*src->data==*srcstore->data && a->port1 == b->port1)
409 dstlist = g_list_first(b->addr2);
412 dststore = (address *) (dstlist->data);
413 if ((dststore->type==AT_IPv4 && dst_v4==TRUE) ||(dststore->type==AT_IPv6 && dst_v6==TRUE) )
415 if (*dst->data==*dststore->data && a->port2 == b->port2)
417 if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
418 return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
420 return ADDRESS_FORWARD_STREAM;
423 dstlist=g_list_next(dstlist);
426 dstlist=g_list_next(dstlist);
428 srclist=g_list_next(srclist);
431 srclist=g_list_next(srclist);
433 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
435 if (*src->data == *srcstore->data && a->port1 == b->port1)
437 dstlist = g_list_first(b->addr2);
440 dststore = (address *) (dstlist->data);
441 if ((dststore->type==AT_IPv4 && dst_v4==TRUE) || (dststore->type==AT_IPv6 && dst_v6==TRUE))
443 if (*dst->data==*dststore->data && a->port2 == b->port2)
445 if ((a->verification_tag1 !=0)&& (b->verification_tag1 == 0)&& (b->verification_tag2 !=0))
446 return ADDRESS_FORWARD_ADD_FORWARD_VTAG;
448 return ADDRESS_FORWARD_STREAM;
451 dstlist=g_list_next(dstlist);
454 dstlist=g_list_next(dstlist);
456 srclist=g_list_next(srclist);
459 srclist=g_list_next(srclist);
462 srclist=g_list_next(srclist);
468 src = g_malloc(sizeof(address));
469 if (a->dst.type == AT_IPv4)
475 else if (a->dst.type==AT_IPv6)
481 addr = g_malloc(src->len);
482 memcpy(addr, a->dst.data, src->len);
485 dst = g_malloc(sizeof(address));
486 if (a->src.type == AT_IPv4)
492 else if (a->src.type==AT_IPv6)
498 addr = g_malloc(dst->len);
499 memcpy(addr, a->src.data, dst->len);
502 srclist = g_list_first(b->addr1);
505 srcstore = (address *) (srclist->data);
506 if (srcstore->type==AT_IPv4 && src_v4==TRUE)
508 if (*src->data==*srcstore->data && a->port2 == b->port1)
510 dstlist = g_list_first(b->addr2);
513 dststore = (address *) (dstlist->data);
514 if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
516 if (*dst->data==*dststore->data && a->port1 == b->port2)
518 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
519 return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
520 else if ((a->verification_tag1 !=0) && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
521 return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
523 return ADDRESS_BACKWARD_STREAM;
526 dstlist=g_list_next(dstlist);
529 dstlist=g_list_next(dstlist);
531 srclist=g_list_next(srclist);
534 srclist=g_list_next(srclist);
536 else if (srcstore->type==AT_IPv6 && src_v6==TRUE)
538 if (*src->data == *srcstore->data && a->port2 == b->port1)
540 dstlist = g_list_first(b->addr2);
543 dststore = (address *) (dstlist->data);
544 if ((dststore->type==AT_IPv4 && src_v4==TRUE) || (dststore->type==AT_IPv6 && src_v6==TRUE))
546 if (*dst->data==*dststore->data && a->port1 == b->port2)
548 if ((a->verification_tag1 ==b->verification_tag2)&& (b->verification_tag1 == 0))
549 return ADDRESS_BACKWARD_ADD_FORWARD_VTAG;
550 else if ((a->verification_tag1 !=0) && (b->verification_tag1 != 0)&& (b->verification_tag2 == 0))
551 return ADDRESS_BACKWARD_ADD_BACKWARD_VTAG;
553 return ADDRESS_BACKWARD_STREAM;
556 dstlist=g_list_next(dstlist);
559 dstlist=g_list_next(dstlist);
561 srclist=g_list_next(srclist);
564 srclist=g_list_next(srclist);
567 srclist=g_list_next(srclist);
573 return ASSOC_NOT_FOUND;
581 static sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
583 sctp_allassocs_info_t *assoc_info;
584 sctp_assoc_info_t *info = NULL;
588 assoc_info = &sctp_tapinfo_struct;
589 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
593 cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
594 /*if (cmp==ASSOC_NOT_FOUND)
596 cmp=sctp_assoc_address_cmp(needle, (sctp_assoc_info_t*)(list->data));
601 info = (sctp_assoc_info_t*)(list->data);
604 case BACKWARD_STREAM:
605 info = (sctp_assoc_info_t*)(list->data);
608 case FORWARD_ADD_FORWARD_VTAG:
609 info = (sctp_assoc_info_t*)(list->data);
610 info->verification_tag1=needle->verification_tag1;
613 case BACKWARD_ADD_FORWARD_VTAG:
614 info = (sctp_assoc_info_t*)(list->data);
615 info->verification_tag1=needle->verification_tag1;
618 case BACKWARD_ADD_BACKWARD_VTAG:
619 info = (sctp_assoc_info_t*)(list->data);
620 info->verification_tag2=needle->verification_tag1;
623 case ADDRESS_FORWARD_STREAM:
624 info = (sctp_assoc_info_t*)(list->data);
626 info->check_address=TRUE;
628 case ADDRESS_BACKWARD_STREAM:
629 info = (sctp_assoc_info_t*)(list->data);
631 info->check_address=TRUE;
633 case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
634 info = (sctp_assoc_info_t*)(list->data);
635 info->verification_tag1=needle->verification_tag1;
637 info->check_address=TRUE;
639 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
640 info = (sctp_assoc_info_t*)(list->data);
641 info->verification_tag1=needle->verification_tag1;
643 info->check_address=TRUE;
645 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
646 info = (sctp_assoc_info_t*)(list->data);
647 info->verification_tag2=needle->verification_tag1;
649 info->check_address=TRUE;
653 list = g_list_previous(list);
659 static sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
663 sctp_addr_chunk *ch=NULL;
667 list = g_list_first(info->addr_chunk_count);
671 ch = (sctp_addr_chunk *)(list->data);
672 if (ch->direction == direction)
674 v = (address *) (ch->addr);
675 if (*(vadd->data)==*(v->data))
677 ch->addr_count[type]++;
682 list = g_list_next(list);
686 list = g_list_next(list);
688 ch = g_malloc(sizeof(sctp_addr_chunk));
689 ch->direction = direction;
690 ch->addr = g_malloc(sizeof(address));
691 ch->addr->type = vadd->type;
692 ch->addr->len = vadd->len;
693 dat = g_malloc(vadd->len);
694 memcpy(dat, vadd->data, vadd->len);
695 ch->addr->data = dat;
697 ch->addr_count[i] = 0;
698 ch->addr_count[type]++;
699 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
704 static sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
710 list = g_list_first(info->addr1);
712 list = g_list_first(info->addr2);
716 v = (address *) (list->data);
717 if (v->type == AT_IPv4 && vadd->type == AT_IPv4)
719 if (*vadd->data!=*v->data)
721 list = g_list_next(list);
729 else if (v->type == AT_IPv6 && vadd->type == AT_IPv6)
731 if (strcmp(ip6_to_str((const struct e_in6_addr *)(vadd->data)), ip6_to_str((const struct e_in6_addr *)v->data)))
733 list = g_list_next(list);
743 list = g_list_next(list);
748 info->addr1 = g_list_append(info->addr1, vadd);
749 else if (direction==2)
750 info->addr2 = g_list_append(info->addr2, vadd);
756 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
758 struct _sctp_info *sctp_info;
759 guint32 chunk_number = 0, tsnumber;
760 sctp_tmp_info_t tmp_info;
761 sctp_assoc_info_t *info = NULL;
762 sctp_error_info_t *error = NULL;
764 guint16 type, length;
765 address *store = NULL;
768 guint8 *t_s_n = NULL;
769 gboolean sackchunk = FALSE;
770 gboolean datachunk = FALSE;
772 struct tsn_sort *tsn_s;
776 sctp_allassocs_info_t *assoc_info=NULL;
777 assoc_info = &sctp_tapinfo_struct;
779 sctp_info = (struct _sctp_info *) data;
782 type = sctp_info->ip_src.type;
786 tmp_info.src.type = AT_IPv4;
787 tmp_info.src.len = 4;
789 else if (type == AT_IPv6)
791 tmp_info.src.type = AT_IPv6;
792 tmp_info.src.len = 16;
795 addr = g_malloc(tmp_info.src.len);
796 memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
797 tmp_info.src.data = addr;
799 type = sctp_info->ip_dst.type;
803 tmp_info.dst.type = AT_IPv4;
804 tmp_info.dst.len = 4;
806 else if (type == AT_IPv6)
808 tmp_info.dst.type = AT_IPv6;
809 tmp_info.dst.len = 16;
812 addr = g_malloc(tmp_info.dst.len);
813 memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
814 tmp_info.dst.data = addr;
816 tmp_info.port1 = sctp_info->sport;
817 tmp_info.port2 = sctp_info->dport;
819 if (sctp_info->vtag_reflected)
821 tmp_info.verification_tag2 = sctp_info->verification_tag;
822 tmp_info.verification_tag1 = 0;
826 tmp_info.verification_tag1 = sctp_info->verification_tag;
827 tmp_info.verification_tag2 = 0;
831 info = find_assoc(&tmp_info);
834 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
835 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
837 if (sctp_info->number_of_tvbs > 0)
839 info = g_malloc(sizeof(sctp_assoc_info_t));
840 memset(info, 0, sizeof(sctp_assoc_info_t));
841 info->src.type = tmp_info.src.type;
842 info->src.len = tmp_info.src.len;
843 addr = g_malloc(tmp_info.dst.len);
844 memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
845 info->src.data = addr;
846 info->dst.type = tmp_info.dst.type;
847 info->dst.len = tmp_info.dst.len;
848 addr = g_malloc(tmp_info.dst.len);
849 memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
850 info->dst.data = addr;
851 info->port1 = tmp_info.port1;
852 info->port2 = tmp_info.port2;
853 info->verification_tag1 = tmp_info.verification_tag1;
854 info->verification_tag2 = tmp_info.verification_tag2;
855 info->n_tvbs = tmp_info.n_tvbs;
857 info->initack = FALSE;
859 info = calc_checksum(sctp_info, info);
861 info->error_info_list = NULL;
862 info->min_secs = 0xffffffff;
863 info->min_usecs = 0xffffffff;
866 info->min_tsn2 = 0xFFFFFFFF;
867 info->min_tsn1 = 0xffffffff;
870 info->max_bytes1 = 0;
871 info->max_bytes2 = 0;
872 info->n_data_chunks = 0;
873 info->n_data_bytes = 0;
874 info->n_data_chunks_ep1 = 0;
875 info->n_data_bytes_ep1 = 0;
876 info->n_data_chunks_ep2 = 0;
877 info->n_data_bytes_ep2 = 0;
878 info->n_sack_chunks_ep1 = 0;
879 info->n_sack_chunks_ep2 = 0;
880 info->n_array_tsn1 = 0;
881 info->n_array_tsn2 = 0;
882 info->max_window1 = 0;
883 info->max_window2 = 0;
884 info->min_max = NULL;
885 info->sort_tsn1 = g_ptr_array_new();
886 info->sort_tsn2 = g_ptr_array_new();
887 info->sort_sack1 = g_ptr_array_new();
888 info->sort_sack2 = g_ptr_array_new();
889 for (i=0; i < NUM_CHUNKS; i++)
891 info->chunk_count[i] = 0;
892 info->ep1_chunk_count[i] = 0;
893 info->ep2_chunk_count[i] = 0;
895 info->addr_chunk_count = NULL;
897 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
898 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
899 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
900 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
902 tsn = g_malloc(sizeof(tsn_t));
903 sack = g_malloc(sizeof(tsn_t));
906 sack->src.type=tsn->src.type = tmp_info.src.type;
907 sack->src.len=tsn->src.len = tmp_info.src.len;
908 addr = g_malloc(tmp_info.src.len);
909 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
910 tsn->src.data = addr;
911 addr = g_malloc(tmp_info.src.len);
912 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
913 sack->src.data = addr;
914 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
915 sack->dst.len =tsn->dst.len = tmp_info.dst.len;
916 addr = g_malloc(tmp_info.dst.len);
917 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
918 tsn->dst.data = addr;
919 addr = g_malloc(tmp_info.dst.len);
920 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
921 sack->dst.data = addr;
922 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
923 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
924 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
925 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
927 if (tsn->secs < info->min_secs)
929 info->min_secs = tsn->secs;
930 info->min_usecs = tsn->usecs;
932 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
933 info->min_usecs = tsn->usecs;
935 if (tsn->secs > info->max_secs)
937 info->max_secs = tsn->secs;
938 info->max_usecs = tsn->usecs;
940 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
941 info->max_usecs = tsn->usecs;
944 sack->frame_number = tsn->frame_number = pinfo->fd->num;
946 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))
948 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
949 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
950 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
951 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
952 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
954 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
955 if (type == IPV4ADDRESS_PARAMETER_ID)
957 store = g_malloc(sizeof (address));
958 store->type = AT_IPv4;;
960 store->data = g_malloc(4);
961 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
962 info = add_address(store, info, 1);
964 else if (type == IPV6ADDRESS_PARAMETER_ID)
966 store = g_malloc(sizeof (address));
967 store->type = AT_IPv6;;
969 store->data = g_malloc(16);
970 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
971 info = add_address(store, info, 1);
975 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
981 info->initack_dir = 1;
982 info->initack = TRUE;
984 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
985 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
986 info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
990 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
991 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
992 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
993 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID))
995 tsn = g_malloc(sizeof(tsn_t));
996 sack = g_malloc(sizeof(tsn_t));
1000 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1002 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
1004 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1005 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1006 info = add_chunk_count(&tmp_info.src, info, 1, tvb_get_guint8(sctp_info->tvb[0],0));
1010 info->chunk_count[12]++;
1011 info->ep1_chunk_count[12]++;
1012 info = add_chunk_count(&tmp_info.src, info, 1, 12);
1014 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID)
1016 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1017 info->n_data_chunks++;
1018 info->n_data_bytes+=length;
1019 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1020 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1021 if (tsnumber < info->min_tsn1)
1022 info->min_tsn1 = tsnumber;
1023 if (tsnumber > info->max_tsn1)
1025 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1026 info->n_data_chunks_ep1++;
1027 info->n_data_bytes_ep1+=length;
1028 info->max_tsn1 = tsnumber;
1030 t_s_n = g_malloc(16);
1031 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1032 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1034 tsn_s = g_malloc(sizeof(struct tsn_sort));
1035 tsn_s->tsnumber = tsnumber;
1036 tsn_s->secs = tsn->secs;
1037 tsn_s->usecs = tsn->usecs;
1039 tsn_s->length = length-DATA_CHUNK_HEADER_LENGTH;
1040 g_ptr_array_add(info->sort_tsn1, tsn_s);
1041 info->n_array_tsn1++;
1043 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID)
1045 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1046 if (tsnumber < info->min_tsn2)
1047 info->min_tsn2 = tsnumber;
1048 if (tsnumber > info->max_tsn2)
1049 info->max_tsn2 = tsnumber;
1050 info->n_sack_chunks_ep2++;
1051 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1052 t_s_n = g_malloc(length);
1053 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1054 sack->tsns = g_list_append(sack->tsns, t_s_n);
1056 tsn_s = g_malloc(sizeof(struct tsn_sort));
1057 tsn_s->tsnumber = tsnumber;
1058 tsn_s->secs = tsn->secs;
1059 tsn_s->usecs = tsn->usecs;
1061 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1062 if (tsn_s->length > info->max_window1)
1063 info->max_window1 = tsn_s->length;
1064 g_ptr_array_add(info->sort_sack2, tsn_s);
1065 info->n_sack_chunks_ep2++;
1069 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
1071 store = g_malloc(sizeof (address));
1072 store->type = tmp_info.src.type;
1073 store->len = tmp_info.src.len;
1074 addr = g_malloc(tmp_info.src.len);
1075 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1077 info = add_address(store, info, 1);
1078 store = g_malloc(sizeof (address));
1079 store->type = tmp_info.dst.type;
1080 store->len = tmp_info.dst.len;
1081 addr = g_malloc(tmp_info.dst.len);
1082 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1084 info = add_address(store, info, 2);
1085 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1086 if (datachunk == TRUE)
1087 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1088 if (sackchunk == TRUE)
1089 info->sack2 = g_list_prepend(info->sack2, sack);
1090 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
1094 error = g_malloc(sizeof(sctp_error_info_t));
1095 error->frame_number = pinfo->fd->num;
1097 strcpy(error->chunk_info,"");
1098 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1099 strcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"));
1101 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1102 strcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"));
1103 error->info_text = "INFOS";
1104 info->error_info_list = g_list_append(info->error_info_list, error);
1107 } /* endif (!info) */
1110 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
1111 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1112 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
1113 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
1116 tsn = g_malloc(sizeof(tsn_t));
1117 sack = g_malloc(sizeof(tsn_t));
1120 sack->src.type = tsn->src.type = tmp_info.src.type;
1121 sack->src.len = tsn->src.len = tmp_info.src.len;
1122 addr = g_malloc(tmp_info.src.len);
1123 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1124 tsn->src.data = addr;
1125 addr = g_malloc(tmp_info.src.len);
1126 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
1127 sack->src.data = addr;
1128 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
1129 sack->dst.len = tsn->dst.len = tmp_info.dst.len;
1130 addr = g_malloc(tmp_info.dst.len);
1131 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1132 tsn->dst.data = addr;
1133 addr = g_malloc(tmp_info.dst.len);
1134 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
1135 sack->dst.data = addr;
1136 sack->secs=tsn->secs = (guint32)pinfo->fd->rel_ts.secs;
1137 sack->usecs=tsn->usecs = (guint32)pinfo->fd->rel_ts.nsecs/1000;
1138 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
1139 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID))
1141 if (tsn->secs < info->min_secs)
1143 info->min_secs = tsn->secs;
1144 info->min_usecs = tsn->usecs;
1146 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1147 info->min_usecs = tsn->usecs;
1149 if (tsn->secs > info->max_secs)
1151 info->max_secs = tsn->secs;
1152 info->max_usecs = tsn->usecs;
1154 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1155 info->max_usecs = tsn->usecs;
1157 sack->frame_number = tsn->frame_number = pinfo->fd->num;
1159 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1161 store = g_malloc(sizeof (address));
1162 store->type = tmp_info.src.type;
1163 store->len = tmp_info.src.len;
1164 addr = g_malloc(tmp_info.src.len);
1165 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1168 if (info->direction == 1)
1169 info = add_address(store, info, 1);
1170 else if (info->direction == 2)
1171 info = add_address(store, info, 2);
1173 store = g_malloc(sizeof (address));
1174 store->type = tmp_info.dst.type;
1175 store->len = tmp_info.dst.len;
1176 addr = g_malloc(tmp_info.dst.len);
1177 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1180 if (info->direction == 1)
1181 info = add_address(store, info, 2);
1182 else if (info->direction == 2)
1183 info = add_address(store, info, 1);
1185 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1186 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1188 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1190 if (info->direction == 2)
1192 if (tsnumber < info->min_tsn2)
1193 info->min_tsn2 = tsnumber;
1194 if (tsnumber > info->max_tsn2)
1195 info->max_tsn2 = tsnumber;
1196 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1197 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1198 /*info->initack_dir=2;*/
1199 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1201 else if (info->direction == 1)
1203 if (tsnumber < info->min_tsn1)
1204 info->min_tsn1 = tsnumber;
1205 if (tsnumber > info->max_tsn1)
1206 info->max_tsn1 = tsnumber;
1207 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1208 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1209 /*info->initack_dir=1;*/
1210 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1212 info->chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1213 if (info->direction == 1)
1214 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1216 info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[0],0)]++;
1217 info = add_chunk_count(&tmp_info.src, info, info->direction, tvb_get_guint8(sctp_info->tvb[0],0));
1218 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1220 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1221 if (type == IPV4ADDRESS_PARAMETER_ID)
1223 store = g_malloc(sizeof (address));
1224 store->type = AT_IPv4;;
1226 store->data = g_malloc(4);
1227 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1228 info = add_address(store, info, info->direction);
1230 else if (type == IPV6ADDRESS_PARAMETER_ID)
1232 store = g_malloc(sizeof (address));
1233 store->type = AT_IPv6;;
1235 store->data = g_malloc(16);
1236 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1237 info = add_address(store, info, info->direction);
1240 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1242 info->initack = TRUE;
1243 info->initack_dir = info->direction;
1246 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1253 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1254 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1255 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID))
1257 sack = g_malloc(sizeof(tsn_t));
1259 tsn = g_malloc(sizeof(tsn_t));
1262 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1264 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) < 12)
1266 info->chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1267 if (info->direction == 1)
1268 info->ep1_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1270 info->ep2_chunk_count[tvb_get_guint8(sctp_info->tvb[chunk_number],0)]++;
1271 info = add_chunk_count(&tmp_info.src, info,info->direction, tvb_get_guint8(sctp_info->tvb[chunk_number],0));
1275 info->chunk_count[12]++;
1276 if (info->direction == 1)
1277 info->ep1_chunk_count[12]++;
1279 info->ep2_chunk_count[12]++;
1280 info = add_chunk_count(&tmp_info.src, info, info->direction,12);
1282 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID)
1284 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1285 t_s_n = g_malloc(16);
1286 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1287 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1289 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1290 info->n_data_chunks++;
1291 info->n_data_bytes+=length;
1292 tsn_s = g_malloc(sizeof(struct tsn_sort));
1293 tsn_s->tsnumber = tsnumber;
1294 tsn_s->secs = tsn->secs;
1295 tsn_s->usecs = tsn->usecs;
1297 tsn_s->length = length;
1299 if (info->direction == 1)
1301 if(tsnumber < info->min_tsn1)
1302 info->min_tsn1 = tsnumber;
1303 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1305 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1306 info->n_data_chunks_ep1++;
1307 info->n_data_bytes_ep1 += length;
1309 if(tsnumber > info->max_tsn1)
1311 info->max_tsn1 = tsnumber;
1312 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1313 info->n_data_chunks_ep1++;
1314 info->n_data_bytes_ep1 += length;
1316 if (info->init == FALSE)
1317 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1318 if (info->initack == FALSE)
1319 info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1321 g_ptr_array_add(info->sort_tsn1, tsn_s);
1322 info->n_array_tsn1++;
1324 else if (info->direction == 2)
1327 if(tsnumber < info->min_tsn2)
1328 info->min_tsn2 = tsnumber;
1330 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1332 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1333 info->n_data_chunks_ep2++;
1334 info->n_data_bytes_ep2+=length;
1336 if(tsnumber > info->max_tsn2)
1338 info->max_tsn2 = tsnumber;
1339 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1340 info->n_data_chunks_ep2++;
1341 info->n_data_bytes_ep2+=length;
1343 if (info->init == FALSE)
1344 info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1345 if (info->initack == FALSE)
1346 info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1348 g_ptr_array_add(info->sort_tsn2, tsn_s);
1349 info->n_array_tsn2++;
1352 else if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID)
1354 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1355 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1356 t_s_n = g_malloc(length);
1357 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1358 sack->tsns = g_list_append(sack->tsns, t_s_n);
1360 tsn_s = g_malloc(sizeof(struct tsn_sort));
1361 tsn_s->tsnumber = tsnumber;
1362 tsn_s->secs = tsn->secs;
1363 tsn_s->usecs = tsn->usecs;
1365 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1368 if (info->direction == 2)
1370 if(tsnumber < info->min_tsn1)
1371 info->min_tsn1 = tsnumber;
1372 if(tsnumber > info->max_tsn1)
1373 info->max_tsn1 = tsnumber;
1374 if (tsn_s->length > info->max_window1)
1375 info->max_window1 = tsn_s->length;
1376 g_ptr_array_add(info->sort_sack1, tsn_s);
1377 info->n_sack_chunks_ep1++;
1379 else if (info->direction == 1)
1382 if(tsnumber < info->min_tsn2)
1383 info->min_tsn2 = tsnumber;
1384 if(tsnumber > info->max_tsn2)
1385 info->max_tsn2 = tsnumber;
1386 if (tsn_s->length > info->max_window2)
1387 info->max_window2 = tsn_s->length;
1388 g_ptr_array_add(info->sort_sack2, tsn_s);
1389 info->n_sack_chunks_ep2++;
1396 if (datachunk == TRUE)
1398 if (info->direction == 1)
1399 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1400 else if (info->direction == 2)
1401 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1403 if (sackchunk == TRUE)
1405 if (info->direction == 1)
1406 info->sack2 = g_list_prepend(info->sack2, sack);
1407 else if(info->direction == 2)
1408 info->sack1 = g_list_prepend(info->sack1, sack);
1410 info->n_tvbs += sctp_info->number_of_tvbs;
1411 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1412 info = calc_checksum(sctp_info, info);
1419 /* XXX just copied from gtk/rpc_stat.c */
1420 void protect_thread_critical_region(void);
1421 void unprotect_thread_critical_region(void);
1423 /****************************************************************************/
1425 remove_tap_listener_sctp_stat(void)
1427 if (sctp_tapinfo_struct.is_registered) {
1428 protect_thread_critical_region();
1429 remove_tap_listener(&sctp_tapinfo_struct);
1430 unprotect_thread_critical_region();
1431 sctp_tapinfo_struct.is_registered = FALSE;
1436 void sctp_stat_scan(void)
1438 if (!sctp_tapinfo_struct.is_registered)
1439 register_tap_listener_sctp_stat();
1442 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1444 return &sctp_tapinfo_struct;
1448 static void sctp_update(void *dummy _U_)
1450 if (get_stat_dlg()!=NULL)
1451 sctp_stat_dlg_update();
1455 register_tap_listener_sctp_stat(void)
1457 GString *error_string;
1459 if (!sctp_tapinfo_struct.is_registered)
1461 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, reset, packet, sctp_update))) {
1462 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
1463 g_string_free(error_string, TRUE);
1466 sctp_tapinfo_struct.is_registered=TRUE;