HACK: 1. try to match RowsetProperties
[wireshark-wip.git] / ui / tap-sctp-analysis.c
blob77a64e615ed447d92db757285425337d917bd2d6
1 /*
2 * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
4 * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
26 #include <stdio.h>
27 #include <string.h>
28 #include <math.h>
30 #include "epan/packet_info.h"
31 #include "epan/tap.h"
32 #include "epan/address.h"
33 #include "epan/strutil.h"
34 #include "epan/value_string.h"
35 #include "ui/tap-sctp-analysis.h"
37 #include "ui/simple_dialog.h"
39 #define SCTP_ABORT_CHUNK_T_BIT 0x01
41 #define PARAMETER_TYPE_LENGTH 2
42 #define PARAMETER_LENGTH_LENGTH 2
43 #define PARAMETER_HEADER_LENGTH (PARAMETER_TYPE_LENGTH + PARAMETER_LENGTH_LENGTH)
45 #define PARAMETER_HEADER_OFFSET 0
46 #define PARAMETER_TYPE_OFFSET PARAMETER_HEADER_OFFSET
47 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TYPE_OFFSET + PARAMETER_TYPE_LENGTH)
48 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
50 #define IPV6_ADDRESS_LENGTH 16
51 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
52 #define IPV4_ADDRESS_LENGTH 4
53 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
54 #define IPV4ADDRESS_PARAMETER_ID 0x0005
55 #define IPV6ADDRESS_PARAMETER_ID 0x0006
57 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH 4
58 #define SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET (CHUNK_VALUE_OFFSET + 0)
59 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH 4
60 #define SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET (SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET + \
61 SACK_CHUNK_CUMULATIVE_TSN_ACK_LENGTH)
63 #define INIT_CHUNK_INITIAL_TSN_LENGTH 4
64 #define INIT_CHUNK_FIXED_PARAMTERS_LENGTH (INIT_CHUNK_INITIATE_TAG_LENGTH + \
65 INIT_CHUNK_ADV_REC_WINDOW_CREDIT_LENGTH + \
66 INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_LENGTH + \
67 INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_LENGTH + \
68 INIT_CHUNK_INITIAL_TSN_LENGTH)
69 #define CHUNK_HEADER_LENGTH (CHUNK_TYPE_LENGTH + \
70 CHUNK_FLAGS_LENGTH + \
71 CHUNK_LENGTH_LENGTH)
72 #define INIT_CHUNK_VARIABLE_LENGTH_PARAMETER_OFFSET (INIT_CHUNK_INITIAL_TSN_OFFSET + \
73 INIT_CHUNK_INITIAL_TSN_LENGTH )
75 static const value_string chunk_type_values[] = {
76 { SCTP_DATA_CHUNK_ID, "DATA" },
77 { SCTP_INIT_CHUNK_ID, "INIT" },
78 { SCTP_INIT_ACK_CHUNK_ID, "INIT_ACK" },
79 { SCTP_SACK_CHUNK_ID, "SACK" },
80 { SCTP_HEARTBEAT_CHUNK_ID, "HEARTBEAT" },
81 { SCTP_HEARTBEAT_ACK_CHUNK_ID, "HEARTBEAT_ACK" },
82 { SCTP_ABORT_CHUNK_ID, "ABORT" },
83 { SCTP_SHUTDOWN_CHUNK_ID, "SHUTDOWN" },
84 { SCTP_SHUTDOWN_ACK_CHUNK_ID, "SHUTDOWN_ACK" },
85 { SCTP_ERROR_CHUNK_ID, "ERROR" },
86 { SCTP_COOKIE_ECHO_CHUNK_ID, "COOKIE_ECHO" },
87 { SCTP_COOKIE_ACK_CHUNK_ID, "COOKIE_ACK" },
88 { SCTP_ECNE_CHUNK_ID, "ECNE" },
89 { SCTP_CWR_CHUNK_ID, "CWR" },
90 { SCTP_SHUTDOWN_COMPLETE_CHUNK_ID, "SHUTDOWN_COMPLETE" },
91 { SCTP_FORWARD_TSN_CHUNK_ID, "FORWARD TSN" },
92 { SCTP_ASCONF_ACK_CHUNK_ID, "ASCONF_ACK" },
93 { SCTP_PKTDROP_CHUNK_ID, "PKTDROP" },
94 { SCTP_ASCONF_CHUNK_ID, "ASCONF" },
95 { SCTP_IETF_EXT, "IETF_EXTENSION" },
96 { SCTP_NR_SACK_CHUNK_ID, "NR_SACK" },
97 { SCTP_AUTH_CHUNK_ID, "AUTH" },
98 { 0, NULL } };
101 #define FORWARD_STREAM 0
102 #define BACKWARD_STREAM 1
103 #define FORWARD_ADD_FORWARD_VTAG 2
104 #define BACKWARD_ADD_FORWARD_VTAG 3
105 #define BACKWARD_ADD_BACKWARD_VTAG 4
106 #define ADDRESS_FORWARD_STREAM 5
107 #define ADDRESS_BACKWARD_STREAM 6
108 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
109 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
110 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
111 #define ASSOC_NOT_FOUND 10
113 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
115 static
116 void free_first(gpointer data, gpointer user_data _U_)
118 g_free(data);
121 static void tsn_free(gpointer data, gpointer user_data _U_)
123 tsn_t *tsn;
125 tsn = (tsn_t *) data;
126 if (tsn->tsns != NULL)
128 g_list_foreach(tsn->tsns, free_first, NULL);
129 g_list_free(tsn->tsns);
130 tsn->tsns=NULL;
135 static void reset(void *arg)
137 sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg;
138 GList* list;
139 sctp_assoc_info_t * info;
141 list = g_list_first(tapdata->assoc_info_list);
142 while (list)
144 info = (sctp_assoc_info_t *) (list->data);
146 if (info->addr1 != NULL)
148 g_list_foreach(info->addr1, free_first, NULL);
149 g_list_free(info->addr1);
150 info->addr1 = NULL;
153 if (info->addr2 != NULL)
155 g_list_foreach(info->addr2,free_first, NULL);
156 g_list_free(info->addr2);
157 info->addr2 = NULL;
160 if (info->error_info_list != NULL)
162 g_list_foreach(info->error_info_list, free_first, NULL);
163 g_list_free(info->error_info_list);
164 info->error_info_list = NULL;
167 if (info->frame_numbers != NULL)
169 g_list_free(info->frame_numbers);
170 info->frame_numbers = NULL;
173 if (info->tsn1 != NULL)
175 g_list_foreach(info->tsn1, tsn_free, NULL);
176 g_list_free(info->tsn1);
177 info->tsn1 = NULL;
180 if (info->tsn2 != NULL)
182 g_list_foreach(info->tsn2, tsn_free, NULL);
183 g_list_free(info->tsn2);
184 info->tsn2 = NULL;
187 if (info->sack1 != NULL)
189 g_list_foreach(info->sack1, tsn_free, NULL);
190 g_list_free(info->sack1);
191 info->sack1 = NULL;
194 if (info->sack2 != NULL)
196 g_list_foreach(info->sack2, tsn_free, NULL);
197 g_list_free(info->sack2);
198 info->sack2 = NULL;
201 if (info->sort_tsn1 != NULL)
202 g_ptr_array_free(info->sort_tsn1, TRUE);
204 if (info->sort_tsn2 != NULL)
205 g_ptr_array_free(info->sort_tsn2, TRUE);
207 if (info->sort_sack1 != NULL)
208 g_ptr_array_free(info->sort_sack1, TRUE);
210 if (info->sort_sack2 != NULL)
211 g_ptr_array_free(info->sort_sack2, TRUE);
213 if (info->min_max != NULL)
215 g_slist_foreach(info->min_max, free_first, NULL);
216 info->min_max = NULL;
219 g_free(list->data);
220 list = g_list_next(list);
222 g_list_free(tapdata->assoc_info_list);
223 tapdata->sum_tvbs = 0;
224 tapdata->assoc_info_list = NULL;
228 static sctp_assoc_info_t *calc_checksum(struct _sctp_info *check_data, sctp_assoc_info_t *data)
230 gboolean ok = FALSE;
232 if (check_data->adler32_calculated)
234 data->n_adler32_calculated++;
235 if (check_data->adler32_correct)
236 data->n_adler32_correct++;
238 if (check_data->crc32c_calculated)
240 data->n_crc32c_calculated++;
241 if (check_data->crc32c_correct)
242 data->n_crc32c_correct++;
244 if (data->n_adler32_calculated > 0)
246 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
248 g_strlcpy(data->checksum_type,"ADLER32",8);
249 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
250 ok = TRUE;
254 if (data->n_crc32c_calculated>0)
256 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
258 g_strlcpy(data->checksum_type,"CRC32C",8);
259 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
260 ok = TRUE;
264 if (!ok)
266 g_strlcpy(data->checksum_type,"UNKNOWN",8);
267 data->n_checksum_errors=0;
270 return(data);
275 static gint sctp_assoc_vtag_cmp(const sctp_tmp_info_t *a, const sctp_assoc_info_t *b)
278 if (a == NULL || b == NULL)
279 return(ASSOC_NOT_FOUND);
281 if ((a->port1 == b->port1) &&
282 (a->port2 == b->port2) &&
283 (a->verification_tag1 == b->verification_tag1) && a->verification_tag1==0 && a->initiate_tag != 0 &&
284 (a->initiate_tag != b->initiate_tag ))
285 return(ASSOC_NOT_FOUND); /* two INITs that belong to different assocs */
287 /* assoc known*/
288 if ((a->port1 == b->port1) &&
289 (a->port2 == b->port2) &&
290 (a->verification_tag1 == b->verification_tag1) &&
291 ((a->verification_tag1 != 0 ||
292 (b->verification_tag2 != 0))))
293 return(FORWARD_STREAM);
295 /* ABORT, vtag reflected */
296 if ((a->port1 == b->port1) &&
297 (a->port2 == b->port2) &&
298 (a->verification_tag2 == b->verification_tag2) &&
299 (a->verification_tag1 == 0 && b->verification_tag1 != 0))
300 return(FORWARD_STREAM);
302 if ((a->port1 == b->port2) &&
303 (a->port2 == b->port1) &&
304 (a->verification_tag1 == b->verification_tag2) &&
305 (a->verification_tag1 != 0))
306 return(BACKWARD_STREAM);
308 if ((a->port1 == b->port2) &&
309 (a->port2 == b->port1) &&
310 (a->verification_tag2 == b->verification_tag1) &&
311 (a->verification_tag2 != 0))
312 return(BACKWARD_STREAM);
314 /* ABORT, vtag reflected */
315 if ((a->port1 == b->port2) &&
316 (a->port2 == b->port1) &&
317 (a->verification_tag2 == b->verification_tag1) &&
318 (a->verification_tag1 == 0 && b->verification_tag2 != 0))
319 return(BACKWARD_STREAM);
321 /*forward stream verifivation tag can be added*/
322 if ((a->port1 == b->port1) &&
323 (a->port2 == b->port2) &&
324 (a->verification_tag1 != 0) &&
325 (b->verification_tag1 == 0) &&
326 (b->verification_tag2 !=0))
327 return (FORWARD_ADD_FORWARD_VTAG);
329 if ((a->port1 == b->port2) &&
330 (a->port2 == b->port1) &&
331 (a->verification_tag1 == b->verification_tag2) &&
332 (b->verification_tag1 == 0))
333 return (BACKWARD_ADD_FORWARD_VTAG);
335 /*backward stream verification tag can be added */
336 if ((a->port1 == b->port2) &&
337 (a->port2 == b->port1) &&
338 (a->verification_tag1 !=0) &&
339 (b->verification_tag1 != 0) &&
340 (b->verification_tag2 == 0))
341 return(BACKWARD_ADD_BACKWARD_VTAG);
343 return(ASSOC_NOT_FOUND);
346 static sctp_assoc_info_t * find_assoc(sctp_tmp_info_t * needle)
348 sctp_allassocs_info_t *assoc_info;
349 sctp_assoc_info_t *info = NULL;
350 GList* list;
351 guint8 cmp;
353 assoc_info = &sctp_tapinfo_struct;
354 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
356 while (list)
358 cmp=sctp_assoc_vtag_cmp(needle, (sctp_assoc_info_t*)(list->data));
360 switch (cmp)
362 case FORWARD_STREAM:
363 info = (sctp_assoc_info_t*)(list->data);
364 info->direction = 1;
365 return info;
366 case BACKWARD_STREAM:
367 info = (sctp_assoc_info_t*)(list->data);
368 info->direction = 2;
369 return info;
370 case FORWARD_ADD_FORWARD_VTAG:
371 info = (sctp_assoc_info_t*)(list->data);
372 info->verification_tag1=needle->verification_tag1;
373 info->direction = 1;
374 return info;
375 case BACKWARD_ADD_FORWARD_VTAG:
376 info = (sctp_assoc_info_t*)(list->data);
377 info->verification_tag1=needle->verification_tag1;
378 info->direction = 2;
379 return info;
380 case BACKWARD_ADD_BACKWARD_VTAG:
381 info = (sctp_assoc_info_t*)(list->data);
382 info->verification_tag2=needle->verification_tag1;
383 info->direction = 2;
384 return info;
385 case ADDRESS_FORWARD_STREAM:
386 info = (sctp_assoc_info_t*)(list->data);
387 info->direction = 1;
388 info->check_address=TRUE;
389 return info;
390 case ADDRESS_BACKWARD_STREAM:
391 info = (sctp_assoc_info_t*)(list->data);
392 info->direction = 2;
393 info->check_address=TRUE;
394 return info;
395 case ADDRESS_FORWARD_ADD_FORWARD_VTAG:
396 info = (sctp_assoc_info_t*)(list->data);
397 info->verification_tag1=needle->verification_tag1;
398 info->direction = 1;
399 info->check_address=TRUE;
400 return info;
401 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG:
402 info = (sctp_assoc_info_t*)(list->data);
403 info->verification_tag1=needle->verification_tag1;
404 info->direction = 2;
405 info->check_address=TRUE;
406 return info;
407 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG:
408 info = (sctp_assoc_info_t*)(list->data);
409 info->verification_tag2=needle->verification_tag1;
410 info->direction = 2;
411 info->check_address=TRUE;
412 return info;
415 list = g_list_previous(list);
418 return NULL;
421 static sctp_assoc_info_t * add_chunk_count(address * vadd, sctp_assoc_info_t * info, guint32 direction, guint32 type)
423 GList *list;
424 address *v=NULL;
425 sctp_addr_chunk *ch=NULL;
426 guint8 * dat;
427 int i;
429 list = g_list_first(info->addr_chunk_count);
431 while (list)
433 ch = (sctp_addr_chunk *)(list->data);
434 if (ch->direction == direction)
436 v = (address *) (ch->addr);
437 if (ADDRESSES_EQUAL(vadd, v))
439 if (IS_SCTP_CHUNK_TYPE(type))
440 ch->addr_count[type]++;
441 else
442 ch->addr_count[OTHER_CHUNKS_INDEX]++;
443 return info;
445 else
447 list = g_list_next(list);
450 else
451 list = g_list_next(list);
453 ch = (sctp_addr_chunk *)g_malloc(sizeof(sctp_addr_chunk));
454 ch->direction = direction;
455 ch->addr = (address *)g_malloc(sizeof(address));
456 ch->addr->type = vadd->type;
457 ch->addr->len = vadd->len;
458 dat = (guint8 *)g_malloc(vadd->len);
459 memcpy(dat, vadd->data, vadd->len);
460 ch->addr->data = dat;
461 for (i=0; i < NUM_CHUNKS; i++)
462 ch->addr_count[i] = 0;
464 if (IS_SCTP_CHUNK_TYPE(type))
465 ch->addr_count[type]++;
466 else
467 ch->addr_count[OTHER_CHUNKS_INDEX]++;
469 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
470 return info;
473 static sctp_assoc_info_t * add_address(address * vadd, sctp_assoc_info_t *info, guint8 direction)
475 GList *list;
476 address *v=NULL;
478 if (direction == 1)
479 list = g_list_first(info->addr1);
480 else
481 list = g_list_first(info->addr2);
483 while (list)
485 v = (address *) (list->data);
486 if (ADDRESSES_EQUAL(vadd, v)) {
487 g_free(vadd);
488 return info;
490 list = g_list_next(list);
493 if (direction == 1)
494 info->addr1 = g_list_append(info->addr1, vadd);
495 else if (direction==2)
496 info->addr2 = g_list_append(info->addr2, vadd);
498 return info;
501 static int
502 packet(void *tapdata _U_, packet_info *pinfo , epan_dissect_t *edt _U_ , const void *data)
504 struct _sctp_info *sctp_info;
505 guint32 chunk_number = 0, tsnumber,framenumber;
506 sctp_tmp_info_t tmp_info;
507 sctp_assoc_info_t *info = NULL;
508 sctp_error_info_t *error = NULL;
509 guint16 type, length = 0;
510 address *store = NULL;
511 tsn_t *tsn = NULL;
512 tsn_t *sack = NULL;
513 guint8 *t_s_n = NULL;
514 gboolean sackchunk = FALSE;
515 gboolean datachunk = FALSE;
516 gboolean forwardchunk = FALSE;
517 struct tsn_sort *tsn_s;
518 guint8* addr = NULL;
519 int i;
520 guint8 idx = 0;
522 sctp_info = (struct _sctp_info *) data;
524 framenumber=pinfo->fd->num;
526 type = sctp_info->ip_src.type;
528 if (type == AT_IPv4)
530 tmp_info.src.type = AT_IPv4;
531 tmp_info.src.len = 4;
533 else if (type == AT_IPv6)
535 tmp_info.src.type = AT_IPv6;
536 tmp_info.src.len = 16;
538 else
540 tmp_info.src.type = AT_NONE;
541 tmp_info.src.len = 0;
544 addr = (guint8 *)g_malloc(tmp_info.src.len);
545 memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len);
546 tmp_info.src.data = addr;
548 type = sctp_info->ip_dst.type;
550 if (type == AT_IPv4)
552 tmp_info.dst.type = AT_IPv4;
553 tmp_info.dst.len = 4;
555 else if (type == AT_IPv6)
557 tmp_info.dst.type = AT_IPv6;
558 tmp_info.dst.len = 16;
560 else
562 tmp_info.dst.type = AT_NONE;
563 tmp_info.dst.len = 0;
566 addr = (guint8 *)g_malloc(tmp_info.dst.len);
567 memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len);
568 tmp_info.dst.data = addr;
570 tmp_info.port1 = sctp_info->sport;
571 tmp_info.port2 = sctp_info->dport;
573 if (sctp_info->vtag_reflected)
575 tmp_info.verification_tag2 = sctp_info->verification_tag;
576 tmp_info.verification_tag1 = 0;
578 else
580 tmp_info.verification_tag1 = sctp_info->verification_tag;
581 tmp_info.verification_tag2 = 0;
583 tmp_info.n_tvbs = 0;
584 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
586 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
588 else
590 tmp_info.initiate_tag = 0;
593 info = find_assoc(&tmp_info);
594 if (!info)
596 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
597 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
599 if (sctp_info->number_of_tvbs > 0)
601 info = (sctp_assoc_info_t *)g_malloc(sizeof(sctp_assoc_info_t));
602 memset(info, 0, sizeof(sctp_assoc_info_t));
603 info->src.type = tmp_info.src.type;
604 info->src.len = tmp_info.src.len;
605 addr = (guint8 *)g_malloc(tmp_info.dst.len);
606 memcpy(addr,(tmp_info.src.data), tmp_info.src.len);
607 info->src.data = addr;
608 info->dst.type = tmp_info.dst.type;
609 info->dst.len = tmp_info.dst.len;
610 addr = (guint8 *)g_malloc(tmp_info.dst.len);
611 memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len);
612 info->dst.data = addr;
613 info->port1 = tmp_info.port1;
614 info->port2 = tmp_info.port2;
615 info->verification_tag1 = tmp_info.verification_tag1;
616 info->verification_tag2 = tmp_info.verification_tag2;
617 info->initiate_tag = tmp_info.initiate_tag;
618 info->n_tvbs = tmp_info.n_tvbs;
619 info->init = FALSE;
620 info->initack = FALSE;
621 info->check_address = FALSE;
622 info->direction = 0;
623 info = calc_checksum(sctp_info, info);
624 info->n_packets = 1;
625 info->error_info_list = NULL;
626 info->min_secs = 0xffffffff;
627 info->min_usecs = 0xffffffff;
628 info->max_secs = 0;
629 info->max_usecs = 0;
630 info->min_tsn2 = 0xFFFFFFFF;
631 info->min_tsn1 = 0xffffffff;
632 info->max_tsn1 = 0;
633 info->max_tsn2 = 0;
634 info->max_bytes1 = 0;
635 info->max_bytes2 = 0;
636 info->n_data_chunks = 0;
637 info->n_data_bytes = 0;
638 info->n_data_chunks_ep1 = 0;
639 info->n_data_bytes_ep1 = 0;
640 info->n_data_chunks_ep2 = 0;
641 info->n_data_bytes_ep2 = 0;
642 info->n_sack_chunks_ep1 = 0;
643 info->n_sack_chunks_ep2 = 0;
644 info->n_array_tsn1 = 0;
645 info->n_array_tsn2 = 0;
646 info->n_forward_chunks = 0;
647 info->max_window1 = 0;
648 info->max_window2 = 0;
649 info->min_max = NULL;
650 info->sort_tsn1 = g_ptr_array_new();
651 info->sort_tsn2 = g_ptr_array_new();
652 info->sort_sack1 = g_ptr_array_new();
653 info->sort_sack2 = g_ptr_array_new();
654 for (i=0; i < NUM_CHUNKS; i++)
656 info->chunk_count[i] = 0;
657 info->ep1_chunk_count[i] = 0;
658 info->ep2_chunk_count[i] = 0;
660 info->addr_chunk_count = NULL;
662 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
663 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
664 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
665 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
666 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
667 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
669 tsn = (tsn_t *)g_malloc(sizeof(tsn_t));
670 sack = (tsn_t *)g_malloc(sizeof(tsn_t));
671 tsn->tsns = NULL;
672 tsn->first_tsn = 0;
673 sack->tsns = NULL;
674 sack->first_tsn = 0;
675 sack->src.type=tsn->src.type = tmp_info.src.type;
676 sack->src.len=tsn->src.len = tmp_info.src.len;
677 addr = (guint8 *)g_malloc(tmp_info.src.len);
678 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
679 tsn->src.data = addr;
680 addr = (guint8 *)g_malloc(tmp_info.src.len);
681 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
682 sack->src.data = addr;
683 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
684 sack->dst.len =tsn->dst.len = tmp_info.dst.len;
685 addr = (guint8 *)g_malloc(tmp_info.dst.len);
686 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
687 tsn->dst.data = addr;
688 addr = (guint8 *)g_malloc(tmp_info.dst.len);
689 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
690 sack->dst.data = addr;
691 sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs;
692 sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
693 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
694 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
695 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
696 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
698 if (tsn->secs < info->min_secs)
700 info->min_secs = tsn->secs;
701 info->min_usecs = tsn->usecs;
703 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
704 info->min_usecs = tsn->usecs;
706 if (tsn->secs > info->max_secs)
708 info->max_secs = tsn->secs;
709 info->max_usecs = tsn->usecs;
711 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
712 info->max_usecs = tsn->usecs;
715 sack->frame_number = tsn->frame_number = pinfo->fd->num;
717 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))
719 info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET);
720 info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET);
721 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
722 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
723 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
725 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
726 if (type == IPV4ADDRESS_PARAMETER_ID)
728 store = (address *)g_malloc(sizeof (address));
729 store->type = AT_IPv4;
730 store->len = 4;
731 store->data = g_malloc(4);
732 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
733 info = add_address(store, info, 1);
735 else if (type == IPV6ADDRESS_PARAMETER_ID)
737 store = (address *)g_malloc(sizeof (address));
738 store->type = AT_IPv6;
739 store->len = 16;
740 store->data = g_malloc(16);
741 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
742 info = add_address(store, info, 1);
746 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
748 info->init = TRUE;
750 else
752 info->initack_dir = 1;
753 info->initack = TRUE;
756 idx = tvb_get_guint8(sctp_info->tvb[0],0);
757 if (!IS_SCTP_CHUNK_TYPE(idx))
758 idx = OTHER_CHUNKS_INDEX;
760 info->chunk_count[idx]++;
761 info->ep1_chunk_count[idx]++;
762 info = add_chunk_count(&tmp_info.src, info, 1, idx);
764 else
766 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
767 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
768 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
769 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
770 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
771 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
773 tsn = (tsn_t *)g_malloc(sizeof(tsn_t));
774 sack = (tsn_t *)g_malloc(sizeof(tsn_t));
775 tsn->tsns = NULL;
776 sack->tsns = NULL;
777 tsn->first_tsn = 0;
778 sack->first_tsn = 0;
780 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
782 idx = tvb_get_guint8(sctp_info->tvb[0],0);
783 if (!IS_SCTP_CHUNK_TYPE(idx))
784 idx = OTHER_CHUNKS_INDEX;
786 info->chunk_count[idx]++;
787 info->ep1_chunk_count[idx]++;
788 info = add_chunk_count(&tmp_info.src, info, 1, idx);
790 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID))
792 datachunk = TRUE;
793 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
794 info->n_data_chunks++;
795 info->n_data_bytes+=length;
796 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
798 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID))
800 forwardchunk = TRUE;
801 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
802 info->n_forward_chunks++;
804 if (datachunk || forwardchunk)
807 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
808 if (tsnumber < info->min_tsn1)
809 info->min_tsn1 = tsnumber;
810 if (tsnumber > info->max_tsn1)
812 if (datachunk)
814 info->n_data_chunks_ep1++;
815 info->n_data_bytes_ep1+=length;
817 else
818 info->n_forward_chunks_ep1++;
819 info->max_tsn1 = tsnumber;
821 if (tsn->first_tsn == 0)
822 tsn->first_tsn = tsnumber;
823 if (datachunk)
825 t_s_n = (guint8 *)g_malloc(16);
826 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
828 else
830 t_s_n = (guint8 *)g_malloc(length);
831 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
833 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
834 tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort));
835 tsn_s->tsnumber = tsnumber;
836 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
837 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
838 tsn_s->offset = 0;
839 tsn_s->framenumber = framenumber;
840 if (datachunk)
841 tsn_s->length = length-DATA_CHUNK_HEADER_LENGTH;
842 else
843 tsn_s->length = length;
844 if (tsn->secs < info->min_secs)
846 info->min_secs = tsn->secs;
847 info->min_usecs = tsn->usecs;
849 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
850 info->min_usecs = tsn->usecs;
852 if (tsn->secs > info->max_secs)
854 info->max_secs = tsn->secs;
855 info->max_usecs = tsn->usecs;
857 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
858 info->max_usecs = tsn->usecs;
859 g_ptr_array_add(info->sort_tsn1, tsn_s);
860 info->n_array_tsn1++;
862 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
863 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
865 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
866 if (tsnumber < info->min_tsn2)
867 info->min_tsn2 = tsnumber;
868 if (tsnumber > info->max_tsn2)
869 info->max_tsn2 = tsnumber;
870 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
871 if (sack->first_tsn == 0)
872 sack->first_tsn = tsnumber;
873 t_s_n = (guint8 *)g_malloc(length);
874 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
875 sack->tsns = g_list_append(sack->tsns, t_s_n);
876 sackchunk = TRUE;
877 tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort));
878 tsn_s->tsnumber = tsnumber;
879 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
880 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
881 tsn_s->offset = 0;
882 tsn_s->framenumber = framenumber;
883 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
884 if (tsn_s->length > info->max_window1)
885 info->max_window1 = tsn_s->length;
886 if (tsn->secs < info->min_secs)
888 info->min_secs = tsn->secs;
889 info->min_usecs = tsn->usecs;
891 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
892 info->min_usecs = tsn->usecs;
894 if (tsn->secs > info->max_secs)
896 info->max_secs = tsn->secs;
897 info->max_usecs = tsn->usecs;
899 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
900 info->max_usecs = tsn->usecs;
901 g_ptr_array_add(info->sort_sack2, tsn_s);
902 info->n_sack_chunks_ep2++;
906 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
908 store = (address *)g_malloc(sizeof (address));
909 store->type = tmp_info.src.type;
910 store->len = tmp_info.src.len;
911 addr = (guint8 *)g_malloc(tmp_info.src.len);
912 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
913 store->data = addr;
914 info = add_address(store, info, 1);
915 store = (address *)g_malloc(sizeof (address));
916 store->type = tmp_info.dst.type;
917 store->len = tmp_info.dst.len;
918 addr = (guint8 *)g_malloc(tmp_info.dst.len);
919 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
920 store->data = addr;
921 info = add_address(store, info, 2);
922 info->frame_numbers=g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
923 if (datachunk || forwardchunk)
924 info->tsn1 = g_list_prepend(info->tsn1, tsn);
925 if (sackchunk == TRUE)
926 info->sack2 = g_list_prepend(info->sack2, sack);
927 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
929 else
931 error = (sctp_error_info_t *)g_malloc(sizeof(sctp_error_info_t));
932 error->frame_number = pinfo->fd->num;
933 error->chunk_info[0] = '\0';
934 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
935 g_strlcpy(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved"), 200);
936 else
937 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
938 g_strlcat(error->chunk_info, val_to_str(tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved"), 200);
939 error->info_text = "INFOS";
940 info->error_info_list = g_list_append(info->error_info_list, error);
943 } /* endif (!info) */
944 else
946 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
947 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
948 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
949 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
950 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
951 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
954 tsn = (tsn_t *)g_malloc(sizeof(tsn_t));
955 sack = (tsn_t *)g_malloc(sizeof(tsn_t));
956 tsn->tsns = NULL;
957 tsn->first_tsn = 0;
958 sack->tsns = NULL;
959 sack->first_tsn = 0;
960 sack->src.type = tsn->src.type = tmp_info.src.type;
961 sack->src.len = tsn->src.len = tmp_info.src.len;
962 addr = (guint8 *)g_malloc(tmp_info.src.len);
963 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
964 tsn->src.data = addr;
965 addr = (guint8 *)g_malloc(tmp_info.src.len);
966 memcpy(addr, tmp_info.src.data, tmp_info.src.len);
967 sack->src.data = addr;
968 sack->dst.type = tsn->dst.type = tmp_info.dst.type;
969 sack->dst.len = tsn->dst.len = tmp_info.dst.len;
970 addr = (guint8 *)g_malloc(tmp_info.dst.len);
971 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
972 tsn->dst.data = addr;
973 addr = (guint8 *)g_malloc(tmp_info.dst.len);
974 memcpy(addr, tmp_info.dst.data, tmp_info.dst.len);
975 sack->dst.data = addr;
976 sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs;
977 sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
978 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
979 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
980 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
981 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
983 if (tsn->secs < info->min_secs)
985 info->min_secs = tsn->secs;
986 info->min_usecs = tsn->usecs;
988 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
989 info->min_usecs = tsn->usecs;
991 if (tsn->secs > info->max_secs)
993 info->max_secs = tsn->secs;
994 info->max_usecs = tsn->usecs;
996 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
997 info->max_usecs = tsn->usecs;
999 sack->frame_number = tsn->frame_number = pinfo->fd->num;
1001 info->frame_numbers = g_list_prepend(info->frame_numbers,&(pinfo->fd->num));
1003 store = (address *)g_malloc(sizeof (address));
1004 store->type = tmp_info.src.type;
1005 store->len = tmp_info.src.len;
1006 addr = (guint8 *)g_malloc(tmp_info.src.len);
1007 memcpy(addr,(tmp_info.src.data),tmp_info.src.len);
1008 store->data = addr;
1010 if (info->direction == 1)
1011 info = add_address(store, info, 1);
1012 else if (info->direction == 2)
1013 info = add_address(store, info, 2);
1015 store = (address *)g_malloc(sizeof (address));
1016 store->type = tmp_info.dst.type;
1017 store->len = tmp_info.dst.len;
1018 addr = (guint8 *)g_malloc(tmp_info.dst.len);
1019 memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len);
1020 store->data = addr;
1022 if (info->direction == 1)
1023 info = add_address(store, info, 2);
1024 else if (info->direction == 2)
1025 info = add_address(store, info, 1);
1027 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
1028 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
1030 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
1032 if (info->direction == 2)
1034 if (tsnumber < info->min_tsn2)
1035 info->min_tsn2 = tsnumber;
1036 if (tsnumber > info->max_tsn2)
1037 info->max_tsn2 = tsnumber;
1038 info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1039 info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1040 /*info->initack_dir=2;*/
1041 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1043 else if (info->direction == 1)
1045 if (tsnumber < info->min_tsn1)
1046 info->min_tsn1 = tsnumber;
1047 if (tsnumber > info->max_tsn1)
1048 info->max_tsn1 = tsnumber;
1049 info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET);
1050 info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET);
1051 /*info->initack_dir=1;*/
1052 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1055 idx = tvb_get_guint8(sctp_info->tvb[0],0);
1056 if (!IS_SCTP_CHUNK_TYPE(idx))
1057 idx = OTHER_CHUNKS_INDEX;
1058 info->chunk_count[idx]++;
1059 if (info->direction == 1)
1060 info->ep1_chunk_count[idx]++;
1061 else
1062 info->ep2_chunk_count[idx]++;
1063 info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
1064 for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1066 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
1067 if (type == IPV4ADDRESS_PARAMETER_ID)
1069 store = (address *)g_malloc(sizeof (address));
1070 store->type = AT_IPv4;
1071 store->len = 4;
1072 store->data = g_malloc(4);
1073 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV4_ADDRESS_OFFSET, 4);
1074 info = add_address(store, info, info->direction);
1076 else if (type == IPV6ADDRESS_PARAMETER_ID)
1078 store = (address *)g_malloc(sizeof (address));
1079 store->type = AT_IPv6;
1080 store->len = 16;
1081 store->data = g_malloc(16);
1082 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(store->data),IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH);
1083 info = add_address(store, info, info->direction);
1086 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
1088 info->initack = TRUE;
1089 info->initack_dir = info->direction;
1091 else
1092 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
1094 info->init = TRUE;
1097 else
1099 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
1100 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
1101 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
1102 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
1103 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
1105 sack = (tsn_t *)g_malloc(sizeof(tsn_t));
1106 sack->tsns = NULL;
1107 sack->first_tsn = 0;
1108 tsn = (tsn_t *)g_malloc(sizeof(tsn_t));
1109 tsn->tsns = NULL;
1110 tsn->first_tsn = 0;
1112 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
1114 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
1115 if (!IS_SCTP_CHUNK_TYPE(idx))
1116 idx = OTHER_CHUNKS_INDEX;
1118 info->chunk_count[idx]++;
1119 if (info->direction == 1)
1120 info->ep1_chunk_count[idx]++;
1121 else
1122 info->ep2_chunk_count[idx]++;
1123 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
1125 if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_DATA_CHUNK_ID))
1126 datachunk = TRUE;
1127 if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
1128 forwardchunk = TRUE;
1129 if (datachunk || forwardchunk)
1131 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET);
1132 if (tsn->first_tsn == 0)
1133 tsn->first_tsn = tsnumber;
1134 if (datachunk)
1136 t_s_n = (guint8 *)g_malloc(16);
1137 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
1138 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1139 info->n_data_chunks++;
1140 info->n_data_bytes+=length;
1142 else
1144 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1145 t_s_n = (guint8 *)g_malloc(length);
1146 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1147 info->n_forward_chunks++;
1149 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1151 tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort));
1152 tsn_s->tsnumber = tsnumber;
1153 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
1154 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1155 tsn_s->offset = 0;
1156 tsn_s->framenumber = framenumber;
1157 tsn_s->length = length;
1159 if (tsn->secs < info->min_secs)
1161 info->min_secs = tsn->secs;
1162 info->min_usecs = tsn->usecs;
1164 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1165 info->min_usecs = tsn->usecs;
1167 if (tsn->secs > info->max_secs)
1169 info->max_secs = tsn->secs;
1170 info->max_usecs = tsn->usecs;
1172 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1173 info->max_usecs = tsn->usecs;
1175 if (info->direction == 1)
1177 if(tsnumber < info->min_tsn1)
1178 info->min_tsn1 = tsnumber;
1179 if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1181 if (datachunk)
1183 info->n_data_chunks_ep1++;
1184 info->n_data_bytes_ep1 += length;
1186 else if (forwardchunk)
1188 info->n_forward_chunks_ep1++;
1191 if(tsnumber > info->max_tsn1)
1193 info->max_tsn1 = tsnumber;
1194 if (datachunk)
1196 info->n_data_chunks_ep1++;
1197 info->n_data_bytes_ep1 += length;
1199 else if (forwardchunk)
1201 info->n_forward_chunks_ep1++;
1204 if (datachunk)
1206 if (info->init == FALSE)
1207 info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1208 if (info->initack == FALSE)
1209 info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1212 g_ptr_array_add(info->sort_tsn1, tsn_s);
1213 info->n_array_tsn1++;
1215 else if (info->direction == 2)
1218 if(tsnumber < info->min_tsn2)
1219 info->min_tsn2 = tsnumber;
1221 if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1223 if (datachunk)
1225 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1226 info->n_data_chunks_ep2++;
1227 info->n_data_bytes_ep2+=length;
1229 else if (forwardchunk)
1231 info->n_forward_chunks_ep2++;
1234 if(tsnumber > info->max_tsn2)
1236 info->max_tsn2 = tsnumber;
1237 if (datachunk)
1239 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH;
1240 info->n_data_chunks_ep2++;
1241 info->n_data_bytes_ep2+=length;
1243 else if (forwardchunk)
1245 info->n_forward_chunks_ep2++;
1248 if (datachunk)
1250 if (info->init == FALSE)
1251 info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1252 if (info->initack == FALSE)
1253 info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1256 g_ptr_array_add(info->sort_tsn2, tsn_s);
1257 info->n_array_tsn2++;
1260 else if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1261 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID))
1263 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET);
1264 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1265 if (sack->first_tsn == 0)
1266 sack->first_tsn = tsnumber;
1267 t_s_n = (guint8 *)g_malloc(length);
1268 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1269 sack->tsns = g_list_append(sack->tsns, t_s_n);
1270 sackchunk = TRUE;
1271 tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort));
1272 tsn_s->tsnumber = tsnumber;
1273 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
1274 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1275 tsn_s->offset = 0;
1276 tsn_s->framenumber = framenumber;
1277 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1279 if (tsn->secs < info->min_secs)
1281 info->min_secs = tsn->secs;
1282 info->min_usecs = tsn->usecs;
1284 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1285 info->min_usecs = tsn->usecs;
1287 if (tsn->secs > info->max_secs)
1289 info->max_secs = tsn->secs;
1290 info->max_usecs = tsn->usecs;
1292 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1293 info->max_usecs = tsn->usecs;
1296 if (info->direction == 2)
1298 if(tsnumber < info->min_tsn1)
1299 info->min_tsn1 = tsnumber;
1300 if(tsnumber > info->max_tsn1)
1301 info->max_tsn1 = tsnumber;
1302 if (tsn_s->length > info->max_window1)
1303 info->max_window1 = tsn_s->length;
1304 g_ptr_array_add(info->sort_sack1, tsn_s);
1305 info->n_sack_chunks_ep1++;
1307 else if (info->direction == 1)
1310 if(tsnumber < info->min_tsn2)
1311 info->min_tsn2 = tsnumber;
1312 if(tsnumber > info->max_tsn2)
1313 info->max_tsn2 = tsnumber;
1314 if (tsn_s->length > info->max_window2)
1315 info->max_window2 = tsn_s->length;
1316 g_ptr_array_add(info->sort_sack2, tsn_s);
1317 info->n_sack_chunks_ep2++;
1324 if (datachunk || forwardchunk)
1326 if (info->direction == 1)
1327 info->tsn1 = g_list_prepend(info->tsn1, tsn);
1328 else if (info->direction == 2)
1329 info->tsn2 = g_list_prepend(info->tsn2, tsn);
1331 if (sackchunk == TRUE)
1333 if (info->direction == 1)
1334 info->sack2 = g_list_prepend(info->sack2, sack);
1335 else if(info->direction == 2)
1336 info->sack1 = g_list_prepend(info->sack1, sack);
1338 info->n_tvbs += sctp_info->number_of_tvbs;
1339 sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1340 info = calc_checksum(sctp_info, info);
1341 info->n_packets++;
1343 return(1);
1347 /****************************************************************************/
1348 void
1349 remove_tap_listener_sctp_stat(void)
1351 if (sctp_tapinfo_struct.is_registered) {
1352 remove_tap_listener(&sctp_tapinfo_struct);
1353 sctp_tapinfo_struct.is_registered = FALSE;
1358 void sctp_stat_scan(void)
1360 if (!sctp_tapinfo_struct.is_registered)
1361 register_tap_listener_sctp_stat();
1364 const sctp_allassocs_info_t* sctp_stat_get_info(void)
1366 return &sctp_tapinfo_struct;
1370 /*static void
1371 sctp_update(void *dummy _U_)
1373 if (get_stat_dlg()!=NULL)
1374 sctp_stat_dlg_update();
1377 void
1378 register_tap_listener_sctp_stat(void)
1380 GString *error_string;
1382 if (!sctp_tapinfo_struct.is_registered)
1384 if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, NULL))) {
1385 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
1386 g_string_free(error_string, TRUE);
1387 return;
1389 sctp_tapinfo_struct.is_registered=TRUE;