2 * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "epan/packet_info.h"
20 #include "epan/value_string.h"
22 #include "ui/tap-sctp-analysis.h"
24 #include "ui/simple_dialog.h"
26 #define FORWARD_STREAM 0
27 #define BACKWARD_STREAM 1
28 #define FORWARD_ADD_FORWARD_VTAG 2
29 #define BACKWARD_ADD_FORWARD_VTAG 3
30 #define BACKWARD_ADD_BACKWARD_VTAG 4
31 #define ADDRESS_FORWARD_STREAM 5
32 #define ADDRESS_BACKWARD_STREAM 6
33 #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7
34 #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8
35 #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9
36 #define ASSOC_NOT_FOUND 10
38 static sctp_allassocs_info_t sctp_tapinfo_struct
;
41 free_first(void *data
, void *user_data _U_
)
52 if (tsn
->tsns
!= NULL
)
54 g_list_free_full(tsn
->tsns
, g_free
);
56 free_address(&tsn
->src
);
57 free_address(&tsn
->dst
);
62 chunk_free(void *data
)
64 sctp_addr_chunk
*chunk
= (sctp_addr_chunk
*) data
;
66 free_address(&chunk
->addr
);
71 store_free(void *data
)
73 address
*addr
= (address
*) data
;
82 sctp_allassocs_info_t
*tapdata
= (sctp_allassocs_info_t
*)arg
;
84 sctp_assoc_info_t
* info
;
86 list
= g_list_first(tapdata
->assoc_info_list
);
89 info
= (sctp_assoc_info_t
*) (list
->data
);
91 if (info
->addr1
!= NULL
)
93 g_list_free_full(info
->addr1
, store_free
);
97 if (info
->addr2
!= NULL
)
99 g_list_free_full(info
->addr2
, store_free
);
103 if (info
->error_info_list
!= NULL
)
105 g_list_free_full(info
->error_info_list
, g_free
);
106 info
->error_info_list
= NULL
;
109 if (info
->frame_numbers
!= NULL
)
111 g_list_free(info
->frame_numbers
);
112 info
->frame_numbers
= NULL
;
115 if (info
->tsn1
!= NULL
)
117 g_list_free_full(info
->tsn1
, tsn_free
);
121 if (info
->tsn2
!= NULL
)
123 g_list_free_full(info
->tsn2
, tsn_free
);
127 if (info
->sack1
!= NULL
)
129 g_list_free_full(info
->sack1
, tsn_free
);
133 if (info
->sack2
!= NULL
)
135 g_list_free_full(info
->sack2
, tsn_free
);
139 if (info
->sort_tsn1
!= NULL
)
140 g_ptr_array_free(info
->sort_tsn1
, true);
142 if (info
->sort_tsn2
!= NULL
)
143 g_ptr_array_free(info
->sort_tsn2
, true);
145 if (info
->sort_sack1
!= NULL
)
146 g_ptr_array_free(info
->sort_sack1
, true);
148 if (info
->sort_sack2
!= NULL
)
149 g_ptr_array_free(info
->sort_sack2
, true);
151 if (info
->min_max
!= NULL
)
153 g_slist_foreach(info
->min_max
, free_first
, NULL
);
154 info
->min_max
= NULL
;
157 if (info
->addr_chunk_count
) {
158 g_list_free_full(info
->addr_chunk_count
, chunk_free
);
163 free_address(&info
->src
);
164 free_address(&info
->dst
);
167 list
= g_list_next(list
);
169 g_list_free(tapdata
->assoc_info_list
);
170 tapdata
->sum_tvbs
= 0;
171 tapdata
->assoc_info_list
= NULL
;
175 static sctp_assoc_info_t
*
176 calc_checksum(const struct _sctp_info
*check_data
, sctp_assoc_info_t
*data
)
180 if (check_data
->adler32_calculated
)
182 data
->n_adler32_calculated
++;
183 if (check_data
->adler32_correct
)
184 data
->n_adler32_correct
++;
186 if (check_data
->crc32c_calculated
)
188 data
->n_crc32c_calculated
++;
189 if (check_data
->crc32c_correct
)
190 data
->n_crc32c_correct
++;
192 if (data
->n_adler32_calculated
> 0)
194 if ((float)(data
->n_adler32_correct
*1.0/data
->n_adler32_calculated
) > 0.5)
196 char str
[] = "ADLER32";
197 (void) g_strlcpy(data
->checksum_type
, str
, 8);
198 data
->n_checksum_errors
=(data
->n_adler32_calculated
-data
->n_adler32_correct
);
203 if (data
->n_crc32c_calculated
>0)
205 if ((float)(data
->n_crc32c_correct
*1.0/data
->n_crc32c_calculated
) > 0.5)
207 char str
[] = "CRC32C";
208 (void) g_strlcpy(data
->checksum_type
, str
, 8);
209 data
->n_checksum_errors
=data
->n_crc32c_calculated
-data
->n_crc32c_correct
;
216 char str
[] = "UNKNOWN";
217 (void) g_strlcpy(data
->checksum_type
, str
, 8);
218 data
->n_checksum_errors
=0;
226 static sctp_assoc_info_t
*
227 find_assoc(sctp_tmp_info_t
*needle
)
229 sctp_allassocs_info_t
*assoc_info
;
230 sctp_assoc_info_t
*info
= NULL
;
233 assoc_info
= &sctp_tapinfo_struct
;
234 if ((list
= g_list_last(assoc_info
->assoc_info_list
))!=NULL
)
238 info
= (sctp_assoc_info_t
*)(list
->data
);
239 if (needle
->assoc_id
== info
->assoc_id
)
242 list
= g_list_previous(list
);
248 static sctp_assoc_info_t
*
249 add_chunk_count(address
*vadd
, sctp_assoc_info_t
*info
, uint32_t direction
, uint32_t type
)
252 sctp_addr_chunk
*ch
=NULL
;
255 list
= g_list_first(info
->addr_chunk_count
);
259 ch
= (sctp_addr_chunk
*)(list
->data
);
260 if (ch
->direction
== direction
)
262 if (addresses_equal(vadd
, &ch
->addr
))
264 if (IS_SCTP_CHUNK_TYPE(type
))
265 ch
->addr_count
[type
]++;
267 ch
->addr_count
[OTHER_CHUNKS_INDEX
]++;
272 list
= g_list_next(list
);
276 list
= g_list_next(list
);
278 ch
= g_new(sctp_addr_chunk
, 1);
279 ch
->direction
= direction
;
280 copy_address(&ch
->addr
, vadd
);
281 for (i
=0; i
< NUM_CHUNKS
; i
++)
282 ch
->addr_count
[i
] = 0;
284 if (IS_SCTP_CHUNK_TYPE(type
))
285 ch
->addr_count
[type
]++;
287 ch
->addr_count
[OTHER_CHUNKS_INDEX
]++;
289 info
->addr_chunk_count
= g_list_append(info
->addr_chunk_count
, ch
);
293 static sctp_assoc_info_t
*
294 add_address(address
*vadd
, sctp_assoc_info_t
*info
, uint16_t direction
)
300 list
= g_list_first(info
->addr1
);
302 list
= g_list_first(info
->addr2
);
306 v
= (address
*) (list
->data
);
307 if (addresses_equal(vadd
, v
)) {
312 list
= g_list_next(list
);
316 info
->addr1
= g_list_append(info
->addr1
, vadd
);
317 else if (direction
==2)
318 info
->addr2
= g_list_append(info
->addr2
, vadd
);
323 static tap_packet_status
324 packet(void *tapdata _U_
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *data
, tap_flags_t flags _U_
)
326 const struct _sctp_info
*sctp_info
= (const struct _sctp_info
*)data
;
327 uint32_t chunk_number
= 0, tsnumber
, framenumber
;
328 sctp_tmp_info_t tmp_info
;
329 sctp_assoc_info_t
*info
= NULL
;
330 sctp_error_info_t
*error
= NULL
;
331 uint16_t type
, length
= 0;
332 address
*store
= NULL
;
335 uint8_t *t_s_n
= NULL
;
336 bool sackchunk
= false;
337 bool datachunk
= false;
338 bool forwardchunk
= false;
339 struct tsn_sort
*tsn_s
;
342 bool tsn_used
= false;
343 bool sack_used
= false;
345 framenumber
= pinfo
->num
;
347 type
= sctp_info
->ip_src
.type
;
349 if (type
== AT_IPv4
|| type
== AT_IPv6
)
350 copy_address(&tmp_info
.src
, &sctp_info
->ip_src
);
352 set_address(&tmp_info
.src
, AT_NONE
, 0, NULL
);
354 type
= sctp_info
->ip_dst
.type
;
356 if (type
== AT_IPv4
|| type
== AT_IPv6
)
357 copy_address(&tmp_info
.dst
, &sctp_info
->ip_dst
);
359 set_address(&tmp_info
.dst
, AT_NONE
, 0, NULL
);
361 tmp_info
.port1
= sctp_info
->sport
;
362 tmp_info
.port2
= sctp_info
->dport
;
364 if (sctp_info
->vtag_reflected
)
366 tmp_info
.verification_tag2
= sctp_info
->verification_tag
;
367 tmp_info
.verification_tag1
= 0;
371 tmp_info
.verification_tag1
= sctp_info
->verification_tag
;
372 tmp_info
.verification_tag2
= 0;
375 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
)
377 tmp_info
.initiate_tag
= tvb_get_ntohl(sctp_info
->tvb
[0], 4);
381 tmp_info
.initiate_tag
= 0;
384 tmp_info
.direction
= sctp_info
->direction
;
385 tmp_info
.assoc_id
= sctp_info
->assoc_index
;
386 info
= find_assoc(&tmp_info
);
389 tmp_info
.n_tvbs
= sctp_info
->number_of_tvbs
;
390 sctp_tapinfo_struct
.sum_tvbs
+=sctp_info
->number_of_tvbs
;
392 if (sctp_info
->number_of_tvbs
> 0)
394 info
= g_new0(sctp_assoc_info_t
, 1);
395 info
->assoc_id
= sctp_info
->assoc_index
;
396 copy_address(&info
->src
, &tmp_info
.src
);
397 copy_address(&info
->dst
, &tmp_info
.dst
);
398 info
->port1
= tmp_info
.port1
;
399 info
->port2
= tmp_info
.port2
;
400 info
->verification_tag1
= tmp_info
.verification_tag1
;
401 info
->verification_tag2
= tmp_info
.verification_tag2
;
402 info
->initiate_tag
= tmp_info
.initiate_tag
;
403 info
->n_tvbs
= tmp_info
.n_tvbs
;
405 info
->initack
= false;
406 info
->check_address
= false;
407 info
->firstdata
= true;
408 info
->direction
= sctp_info
->direction
;
410 info
->outstream1
= 0;
412 info
->outstream2
= 0;
413 info
= calc_checksum(sctp_info
, info
);
415 info
->error_info_list
= NULL
;
416 info
->min_secs
= 0xffffffff;
417 info
->min_usecs
= 0xffffffff;
420 info
->min_tsn2
= 0xFFFFFFFF;
421 info
->min_tsn1
= 0xffffffff;
424 info
->max_bytes1
= 0;
425 info
->max_bytes2
= 0;
426 info
->n_data_chunks
= 0;
427 info
->n_data_bytes
= 0;
428 info
->n_data_chunks_ep1
= 0;
429 info
->n_data_bytes_ep1
= 0;
430 info
->n_data_chunks_ep2
= 0;
431 info
->n_data_bytes_ep2
= 0;
432 info
->n_sack_chunks_ep1
= 0;
433 info
->n_sack_chunks_ep2
= 0;
434 info
->n_array_tsn1
= 0;
435 info
->n_array_tsn2
= 0;
436 info
->n_forward_chunks
= 0;
437 info
->max_window1
= 0;
438 info
->max_window2
= 0;
439 info
->min_max
= NULL
;
440 info
->sort_tsn1
= g_ptr_array_new_with_free_func(g_free
);
441 info
->sort_tsn2
= g_ptr_array_new_with_free_func(g_free
);
442 info
->sort_sack1
= g_ptr_array_new_with_free_func(g_free
);
443 info
->sort_sack2
= g_ptr_array_new_with_free_func(g_free
);
444 info
->dir1
= g_new0(sctp_init_collision_t
, 1);
445 info
->dir1
->init_min_tsn
= 0xffffffff;
446 info
->dir1
->initack_min_tsn
= 0xffffffff;
447 info
->dir2
= g_new0(sctp_init_collision_t
, 1);
448 info
->dir2
->init_min_tsn
= 0xffffffff;
449 info
->dir2
->initack_min_tsn
= 0xffffffff;
451 for (i
=0; i
< NUM_CHUNKS
; i
++)
453 info
->chunk_count
[i
] = 0;
454 info
->ep1_chunk_count
[i
] = 0;
455 info
->ep2_chunk_count
[i
] = 0;
457 info
->addr_chunk_count
= NULL
;
459 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
) ||
460 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_ACK_CHUNK_ID
) ||
461 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_DATA_CHUNK_ID
) ||
462 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_I_DATA_CHUNK_ID
) ||
463 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_SACK_CHUNK_ID
) ||
464 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_NR_SACK_CHUNK_ID
) ||
465 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID
))
467 tsn
= g_new0(tsn_t
, 1);
468 copy_address(&tsn
->src
, &tmp_info
.src
);
469 copy_address(&tsn
->dst
, &tmp_info
.dst
);
471 sack
= g_new0(tsn_t
, 1);
472 copy_address(&sack
->src
, &tmp_info
.src
);
473 copy_address(&sack
->dst
, &tmp_info
.dst
);
474 sack
->secs
=tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
475 sack
->usecs
=tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
477 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_DATA_CHUNK_ID
) ||
478 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_I_DATA_CHUNK_ID
) ||
479 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_SACK_CHUNK_ID
) ||
480 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_NR_SACK_CHUNK_ID
) ||
481 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID
))
483 if (tsn
->secs
< info
->min_secs
)
485 info
->min_secs
= tsn
->secs
;
486 info
->min_usecs
= tsn
->usecs
;
488 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
489 info
->min_usecs
= tsn
->usecs
;
491 if (tsn
->secs
> info
->max_secs
)
493 info
->max_secs
= tsn
->secs
;
494 info
->max_usecs
= tsn
->usecs
;
496 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
497 info
->max_usecs
= tsn
->usecs
;
500 sack
->frame_number
= tsn
->frame_number
= pinfo
->num
;
502 if ((tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
) || (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_ACK_CHUNK_ID
))
504 info
->min_tsn1
= tvb_get_ntohl(sctp_info
->tvb
[0],INIT_CHUNK_INITIAL_TSN_OFFSET
);
505 info
->verification_tag2
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_INITIATE_TAG_OFFSET
);
506 info
->instream1
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET
);
507 info
->outstream1
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET
);
508 info
->arwnd1
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET
);
509 for (chunk_number
= 1; chunk_number
< sctp_info
->number_of_tvbs
; chunk_number
++)
511 type
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
],0);
512 if (type
== IPV4ADDRESS_PARAMETER_ID
)
514 store
= g_new(address
, 1);
515 alloc_address_tvb(NULL
, store
, AT_IPv4
, 4, sctp_info
->tvb
[chunk_number
], IPV4_ADDRESS_OFFSET
);
516 info
= add_address(store
, info
, info
->direction
);
518 else if (type
== IPV6ADDRESS_PARAMETER_ID
)
520 store
= g_new(address
, 1);
521 alloc_address_tvb(NULL
, store
, AT_IPv6
, 16, sctp_info
->tvb
[chunk_number
], IPV6_ADDRESS_OFFSET
);
522 info
= add_address(store
, info
, info
->direction
);
526 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
)
532 info
->initack_dir
= 1;
533 info
->initack
= true;
536 idx
= tvb_get_uint8(sctp_info
->tvb
[0],0);
537 if (!IS_SCTP_CHUNK_TYPE(idx
))
538 idx
= OTHER_CHUNKS_INDEX
;
540 info
->chunk_count
[idx
]++;
541 info
->ep1_chunk_count
[idx
]++;
542 info
= add_chunk_count(&tmp_info
.src
, info
, 1, idx
);
543 if (info
->direction
== 1) {
544 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
) {
545 info
->dir1
->init
= true;
546 info
->dir1
->init_min_tsn
= info
->min_tsn1
;
547 info
->dir1
->init_vtag
= info
->verification_tag2
;
548 } else if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_ACK_CHUNK_ID
) {
549 info
->dir1
->initack
= true;
550 info
->dir1
->initack_min_tsn
= info
->min_tsn1
;
551 info
->dir1
->initack_vtag
= info
->verification_tag2
;
554 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
) {
555 info
->dir2
->init
= true;
556 info
->dir2
->init_min_tsn
= info
->min_tsn1
;
557 info
->dir2
->init_vtag
= info
->verification_tag2
;
558 } else if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_ACK_CHUNK_ID
) {
559 info
->dir2
->initack
= true;
560 info
->dir2
->initack_min_tsn
= info
->min_tsn1
;
561 info
->dir2
->initack_vtag
= info
->verification_tag2
;
567 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_INIT_CHUNK_ID
) &&
568 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_INIT_ACK_CHUNK_ID
) &&
569 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_DATA_CHUNK_ID
) &&
570 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_I_DATA_CHUNK_ID
) &&
571 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_SACK_CHUNK_ID
) &&
572 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_NR_SACK_CHUNK_ID
) &&
573 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID
))
575 tsn
= g_new0(tsn_t
, 1);
576 sack
= g_new0(tsn_t
, 1);
578 for (chunk_number
= 0; chunk_number
< sctp_info
->number_of_tvbs
; chunk_number
++)
580 idx
= tvb_get_uint8(sctp_info
->tvb
[0],0);
581 if (!IS_SCTP_CHUNK_TYPE(idx
))
582 idx
= OTHER_CHUNKS_INDEX
;
584 info
->chunk_count
[idx
]++;
585 info
->ep1_chunk_count
[idx
]++;
586 info
= add_chunk_count(&tmp_info
.src
, info
, 1, idx
);
588 if ((tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) ||
589 (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_I_DATA_CHUNK_ID
))
592 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) {
593 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - DATA_CHUNK_HEADER_LENGTH
;
595 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - I_DATA_CHUNK_HEADER_LENGTH
;
597 info
->n_data_chunks
++;
598 info
->n_data_bytes
+=length
;
599 info
->outstream1
= tvb_get_ntohs((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_STREAM_ID_OFFSET
)+1;
601 if ((tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_FORWARD_TSN_CHUNK_ID
))
604 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
);
605 info
->n_forward_chunks
++;
607 if (datachunk
|| forwardchunk
)
609 tsnumber
= tvb_get_ntohl((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_TSN_OFFSET
);
610 info
->firstdata
= false;
611 if (tsnumber
< info
->min_tsn1
)
612 info
->min_tsn1
= tsnumber
;
613 if (tsnumber
> info
->max_tsn1
)
617 info
->n_data_chunks_ep1
++;
618 info
->n_data_bytes_ep1
+=length
;
621 info
->n_forward_chunks_ep1
++;
622 info
->max_tsn1
= tsnumber
;
624 if (tsn
->first_tsn
== 0)
625 tsn
->first_tsn
= tsnumber
;
628 t_s_n
= (uint8_t *)g_malloc(16);
629 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, 16);
633 t_s_n
= (uint8_t *)g_malloc(length
);
634 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, length
);
636 tsn
->tsns
= g_list_append(tsn
->tsns
, t_s_n
);
637 tsn_s
= g_new(struct tsn_sort
, 1);
638 tsn_s
->tsnumber
= tsnumber
;
639 tsn_s
->secs
= tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
640 tsn_s
->usecs
= tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
642 tsn_s
->framenumber
= framenumber
;
644 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) {
645 tsn_s
->length
= length
- DATA_CHUNK_HEADER_LENGTH
;
647 tsn_s
->length
= length
- I_DATA_CHUNK_HEADER_LENGTH
;
650 tsn_s
->length
= length
;
651 if (tsn
->secs
< info
->min_secs
)
653 info
->min_secs
= tsn
->secs
;
654 info
->min_usecs
= tsn
->usecs
;
656 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
657 info
->min_usecs
= tsn
->usecs
;
659 if (tsn
->secs
> info
->max_secs
)
661 info
->max_secs
= tsn
->secs
;
662 info
->max_usecs
= tsn
->usecs
;
664 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
665 info
->max_usecs
= tsn
->usecs
;
666 g_ptr_array_add(info
->sort_tsn1
, tsn_s
);
667 info
->n_array_tsn1
++;
669 if ((tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_SACK_CHUNK_ID
) ||
670 (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_NR_SACK_CHUNK_ID
) )
672 tsnumber
= tvb_get_ntohl((sctp_info
->tvb
)[chunk_number
], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET
);
673 if (tsnumber
< info
->min_tsn2
)
674 info
->min_tsn2
= tsnumber
;
675 if (tsnumber
> info
->max_tsn2
)
676 info
->max_tsn2
= tsnumber
;
677 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
);
678 if (sack
->first_tsn
== 0)
679 sack
->first_tsn
= tsnumber
;
680 t_s_n
= (uint8_t *)g_malloc(length
);
681 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, length
);
682 sack
->tsns
= g_list_append(sack
->tsns
, t_s_n
);
684 tsn_s
= g_new(struct tsn_sort
, 1);
685 tsn_s
->tsnumber
= tsnumber
;
686 tsn_s
->secs
= tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
687 tsn_s
->usecs
= tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
689 tsn_s
->framenumber
= framenumber
;
690 tsn_s
->length
= tvb_get_ntohl(sctp_info
->tvb
[chunk_number
], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET
);
691 if (tsn_s
->length
> info
->max_window1
)
692 info
->max_window1
= tsn_s
->length
;
693 if (tsn
->secs
< info
->min_secs
)
695 info
->min_secs
= tsn
->secs
;
696 info
->min_usecs
= tsn
->usecs
;
698 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
699 info
->min_usecs
= tsn
->usecs
;
701 if (tsn
->secs
> info
->max_secs
)
703 info
->max_secs
= tsn
->secs
;
704 info
->max_usecs
= tsn
->usecs
;
706 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
707 info
->max_usecs
= tsn
->usecs
;
708 g_ptr_array_add(info
->sort_sack2
, tsn_s
);
709 info
->n_sack_chunks_ep2
++;
713 if (info
->verification_tag1
!= 0 || info
->verification_tag2
!= 0)
716 store
= g_new(address
, 1);
717 copy_address(store
, &tmp_info
.src
);
718 info
= add_address(store
, info
, info
->direction
);
719 store
= g_new(address
, 1);
720 copy_address(store
, &tmp_info
.dst
);
721 if (info
->direction
== 1)
722 info
= add_address(store
, info
, 2);
724 info
= add_address(store
, info
, 1);
726 info
->frame_numbers
=g_list_prepend(info
->frame_numbers
, GUINT_TO_POINTER(number
));
727 if (datachunk
|| forwardchunk
) {
728 info
->tsn1
= g_list_prepend(info
->tsn1
, tsn
);
731 if (sackchunk
== true) {
732 info
->sack2
= g_list_prepend(info
->sack2
, sack
);
735 sctp_tapinfo_struct
.assoc_info_list
= g_list_append(sctp_tapinfo_struct
.assoc_info_list
, info
);
740 error
= g_new(sctp_error_info_t
, 1);
741 error
->frame_number
= pinfo
->num
;
742 error
->chunk_info
[0] = '\0';
743 if ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
)
745 tmp_str
= val_to_str_wmem(NULL
, tvb_get_uint8(sctp_info
->tvb
[0],0),chunk_type_values
,"Reserved (%d)");
746 (void) g_strlcpy(error
->chunk_info
, tmp_str
, 200);
747 wmem_free(NULL
, tmp_str
);
751 for (chunk_number
= 0; chunk_number
< sctp_info
->number_of_tvbs
; chunk_number
++)
753 tmp_str
= val_to_str_wmem(NULL
, tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0),chunk_type_values
,"Reserved (%d)");
754 (void) g_strlcat(error
->chunk_info
, tmp_str
, 200);
755 wmem_free(NULL
, tmp_str
);
758 error
->info_text
= "INFOS";
759 info
->error_info_list
= g_list_append(info
->error_info_list
, error
);
762 } /* endif (!info) */
766 info
->direction
= sctp_info
->direction
;
768 if (info
->verification_tag1
== 0 && info
->verification_tag2
!= sctp_info
->verification_tag
) {
769 info
->verification_tag1
= sctp_info
->verification_tag
;
770 } else if (info
->verification_tag2
== 0 && info
->verification_tag1
!= sctp_info
->verification_tag
) {
771 info
->verification_tag2
= sctp_info
->verification_tag
;
773 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
) ||
774 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_ACK_CHUNK_ID
) ||
775 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_DATA_CHUNK_ID
) ||
776 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_I_DATA_CHUNK_ID
) ||
777 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_SACK_CHUNK_ID
) ||
778 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_NR_SACK_CHUNK_ID
) ||
779 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID
))
782 tsn
= g_new0(tsn_t
, 1);
783 copy_address(&tsn
->src
, &tmp_info
.src
);
784 copy_address(&tsn
->dst
, &tmp_info
.dst
);
786 sack
= g_new0(tsn_t
, 1);
787 copy_address(&sack
->src
, &tmp_info
.src
);
788 copy_address(&sack
->dst
, &tmp_info
.dst
);
789 sack
->secs
=tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
790 sack
->usecs
=tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
792 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_DATA_CHUNK_ID
) ||
793 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_I_DATA_CHUNK_ID
) ||
794 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_SACK_CHUNK_ID
) ||
795 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_NR_SACK_CHUNK_ID
) ||
796 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID
))
798 if (tsn
->secs
< info
->min_secs
)
800 info
->min_secs
= tsn
->secs
;
801 info
->min_usecs
= tsn
->usecs
;
803 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
804 info
->min_usecs
= tsn
->usecs
;
806 if (tsn
->secs
> info
->max_secs
)
808 info
->max_secs
= tsn
->secs
;
809 info
->max_usecs
= tsn
->usecs
;
811 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
812 info
->max_usecs
= tsn
->usecs
;
814 sack
->frame_number
= tsn
->frame_number
= pinfo
->num
;
817 info
->frame_numbers
=g_list_prepend(info
->frame_numbers
, GUINT_TO_POINTER(number
));
819 store
= g_new(address
, 1);
820 copy_address(store
, &tmp_info
.src
);
822 switch (info
->direction
) {
824 info
= add_address(store
, info
, 1);
827 info
= add_address(store
, info
, 2);
834 store
= g_new(address
, 1);
835 copy_address(store
, &tmp_info
.dst
);
837 switch (info
->direction
) {
839 info
= add_address(store
, info
, 2);
842 info
= add_address(store
, info
, 1);
849 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_ACK_CHUNK_ID
) ||
850 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
))
852 tsnumber
= tvb_get_ntohl((sctp_info
->tvb
)[chunk_number
], INIT_CHUNK_INITIAL_TSN_OFFSET
);
853 if (info
->direction
== 2)
855 if (tsnumber
< info
->min_tsn2
)
856 info
->min_tsn2
= tsnumber
;
857 if (tsnumber
> info
->max_tsn2
)
858 info
->max_tsn2
= tsnumber
;
859 info
->instream2
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET
);
860 info
->outstream2
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET
);
861 info
->arwnd2
= tvb_get_ntohl(sctp_info
->tvb
[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET
);
862 info
->tsn2
= g_list_prepend(info
->tsn2
, tsn
);
865 else if (info
->direction
== 1)
867 if (tsnumber
< info
->min_tsn1
)
868 info
->min_tsn1
= tsnumber
;
869 if (tsnumber
> info
->max_tsn1
)
870 info
->max_tsn1
= tsnumber
;
871 info
->instream1
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET
);
872 info
->outstream1
= tvb_get_ntohs(sctp_info
->tvb
[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET
);
873 info
->arwnd1
= tvb_get_ntohl(sctp_info
->tvb
[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET
);
874 info
->tsn1
= g_list_prepend(info
->tsn1
, tsn
);
878 idx
= tvb_get_uint8(sctp_info
->tvb
[0],0);
879 if (!IS_SCTP_CHUNK_TYPE(idx
))
880 idx
= OTHER_CHUNKS_INDEX
;
881 info
->chunk_count
[idx
]++;
882 if (info
->direction
== 1)
883 info
->ep1_chunk_count
[idx
]++;
885 info
->ep2_chunk_count
[idx
]++;
886 info
= add_chunk_count(&tmp_info
.src
, info
, info
->direction
, idx
);
887 for (chunk_number
= 1; chunk_number
< sctp_info
->number_of_tvbs
; chunk_number
++)
889 type
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
],0);
890 if (type
== IPV4ADDRESS_PARAMETER_ID
)
892 store
= g_new(address
, 1);
893 alloc_address_tvb(NULL
, store
, AT_IPv4
, 4, sctp_info
->tvb
[chunk_number
], IPV4_ADDRESS_OFFSET
);
894 info
= add_address(store
, info
, info
->direction
);
896 else if (type
== IPV6ADDRESS_PARAMETER_ID
)
898 store
= g_new(address
, 1);
899 alloc_address_tvb(NULL
, store
, AT_IPv6
, 16, sctp_info
->tvb
[chunk_number
], IPV6_ADDRESS_OFFSET
);
900 info
= add_address(store
, info
, info
->direction
);
903 if (info
->direction
== 1) {
904 if (info
->dir1
->init
|| info
->dir1
->initack
) {
905 info
->init_collision
= true;
907 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
) {
908 info
->dir1
->init
= true;
909 info
->dir1
->init_min_tsn
= tvb_get_ntohl((sctp_info
->tvb
)[0], INIT_CHUNK_INITIAL_TSN_OFFSET
);
910 info
->min_tsn1
= info
->dir1
->init_min_tsn
;
911 info
->dir1
->init_vtag
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_INITIATE_TAG_OFFSET
);
912 } else if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_ACK_CHUNK_ID
) {
913 info
->dir1
->initack
= true;
914 info
->dir1
->initack_min_tsn
= tvb_get_ntohl((sctp_info
->tvb
)[0], INIT_CHUNK_INITIAL_TSN_OFFSET
);
915 info
->min_tsn1
= info
->dir1
->initack_min_tsn
;
916 info
->dir1
->initack_vtag
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_INITIATE_TAG_OFFSET
);
919 if (info
->dir2
->init
|| info
->dir2
->initack
) {
920 info
->init_collision
= true;
922 if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_CHUNK_ID
) {
923 info
->dir2
->init
= true;
924 info
->dir2
->init_min_tsn
= tvb_get_ntohl((sctp_info
->tvb
)[0], INIT_CHUNK_INITIAL_TSN_OFFSET
);
925 info
->min_tsn2
= info
->dir2
->init_min_tsn
;
926 info
->dir2
->init_vtag
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_INITIATE_TAG_OFFSET
);
927 } else if (tvb_get_uint8(sctp_info
->tvb
[0],0) == SCTP_INIT_ACK_CHUNK_ID
) {
928 info
->dir2
->initack
= true;
929 info
->dir2
->initack_min_tsn
= tvb_get_ntohl((sctp_info
->tvb
)[0], INIT_CHUNK_INITIAL_TSN_OFFSET
);
930 info
->min_tsn2
= info
->dir2
->initack_min_tsn
;
931 info
->dir2
->initack_vtag
= tvb_get_ntohl(sctp_info
->tvb
[0], INIT_CHUNK_INITIATE_TAG_OFFSET
);
934 if ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_ACK_CHUNK_ID
)
936 info
->initack
= true;
937 info
->initack_dir
= info
->direction
;
939 else if ((tvb_get_uint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
)
946 if (((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_INIT_ACK_CHUNK_ID
) &&
947 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_DATA_CHUNK_ID
) &&
948 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_I_DATA_CHUNK_ID
) &&
949 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_SACK_CHUNK_ID
) &&
950 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_NR_SACK_CHUNK_ID
) &&
951 ((tvb_get_uint8(sctp_info
->tvb
[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID
))
954 sack
= g_new0(tsn_t
, 1);
958 tsn
= g_new0(tsn_t
, 1);
962 for (chunk_number
= 0; chunk_number
< sctp_info
->number_of_tvbs
; chunk_number
++)
964 idx
= tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0);
965 if (!IS_SCTP_CHUNK_TYPE(idx
))
966 idx
= OTHER_CHUNKS_INDEX
;
968 info
->chunk_count
[idx
]++;
969 if (info
->direction
== 1)
970 info
->ep1_chunk_count
[idx
]++;
972 info
->ep2_chunk_count
[idx
]++;
973 info
= add_chunk_count(&tmp_info
.src
, info
,info
->direction
, idx
);
975 if ((tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) ||
976 (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_I_DATA_CHUNK_ID
))
978 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_FORWARD_TSN_CHUNK_ID
)
980 if ((datachunk
|| forwardchunk
) && tsn
!= NULL
)
982 tsnumber
= tvb_get_ntohl((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_TSN_OFFSET
);
983 if (tsn
->first_tsn
== 0)
984 tsn
->first_tsn
= tsnumber
;
987 t_s_n
= (uint8_t *)g_malloc(16);
988 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, 16);
989 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) {
990 length
=tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
)-DATA_CHUNK_HEADER_LENGTH
;
992 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - I_DATA_CHUNK_HEADER_LENGTH
;
994 info
->n_data_chunks
++;
995 info
->n_data_bytes
+=length
;
999 length
=tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
);
1000 t_s_n
= (uint8_t *)g_malloc(length
);
1001 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, length
);
1002 info
->n_forward_chunks
++;
1004 tsn
->tsns
= g_list_append(tsn
->tsns
, t_s_n
);
1006 tsn_s
= g_new0(struct tsn_sort
, 1);
1007 tsn_s
->tsnumber
= tsnumber
;
1008 tsn_s
->secs
= tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
1009 tsn_s
->usecs
= tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
1011 tsn_s
->framenumber
= framenumber
;
1012 tsn_s
->length
= length
;
1014 if (tsn
->secs
< info
->min_secs
)
1016 info
->min_secs
= tsn
->secs
;
1017 info
->min_usecs
= tsn
->usecs
;
1019 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
1020 info
->min_usecs
= tsn
->usecs
;
1022 if (tsn
->secs
> info
->max_secs
)
1024 info
->max_secs
= tsn
->secs
;
1025 info
->max_usecs
= tsn
->usecs
;
1027 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
1028 info
->max_usecs
= tsn
->usecs
;
1030 if (info
->direction
== 1)
1032 if (info
->firstdata
) {
1033 info
->firstdata
= false;
1034 if (info
->init_collision
) {
1035 if (tsnumber
!= info
->min_tsn1
) {
1036 info
->min_tsn1
= info
->dir1
->init_min_tsn
;
1038 info
->min_tsn2
= info
->dir2
->initack_min_tsn
;
1041 if(tsnumber
< info
->min_tsn1
) {
1042 info
->min_tsn1
= tsnumber
;
1045 if ((info
->init
|| (info
->initack
&& info
->initack_dir
== 1))&& tsnumber
>= info
->min_tsn1
&& tsnumber
<= info
->max_tsn1
)
1049 info
->n_data_chunks_ep1
++;
1050 info
->n_data_bytes_ep1
+= length
;
1052 else if (forwardchunk
)
1054 info
->n_forward_chunks_ep1
++;
1057 if(tsnumber
> info
->max_tsn1
)
1059 info
->max_tsn1
= tsnumber
;
1062 info
->n_data_chunks_ep1
++;
1063 info
->n_data_bytes_ep1
+= length
;
1065 else if (forwardchunk
)
1067 info
->n_forward_chunks_ep1
++;
1072 if (info
->init
== false) {
1073 uint16_t tmp
= tvb_get_ntohs((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_STREAM_ID_OFFSET
)+1;
1074 if (info
->outstream1
< tmp
) info
->outstream1
= tmp
;
1076 if (info
->initack
== false) {
1077 uint16_t tmp
= tvb_get_ntohs((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_STREAM_ID_OFFSET
)+1;
1078 if (info
->instream2
< tmp
) info
->instream2
= tmp
;
1082 g_ptr_array_add(info
->sort_tsn1
, tsn_s
);
1083 info
->n_array_tsn1
++;
1085 else if (info
->direction
== 2)
1087 if (info
->firstdata
) {
1088 info
->firstdata
= false;
1089 if (info
->init_collision
) {
1090 if (tsnumber
!= info
->min_tsn2
) {
1091 info
->min_tsn2
= info
->dir2
->init_min_tsn
;
1092 info
->initack_dir
= 2;
1094 info
->min_tsn1
= info
->dir1
->initack_min_tsn
;
1097 if(tsnumber
< info
->min_tsn2
)
1098 info
->min_tsn2
= tsnumber
;
1101 if ((info
->initack
&& info
->initack_dir
== 2)&& tsnumber
>= info
->min_tsn2
&& tsnumber
<= info
->max_tsn2
)
1105 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) {
1106 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - DATA_CHUNK_HEADER_LENGTH
;
1108 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - I_DATA_CHUNK_HEADER_LENGTH
;
1110 info
->n_data_chunks_ep2
++;
1111 info
->n_data_bytes_ep2
+=length
;
1113 else if (forwardchunk
)
1115 info
->n_forward_chunks_ep2
++;
1118 if (tsnumber
> info
->max_tsn2
)
1120 info
->max_tsn2
= tsnumber
;
1123 if (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_DATA_CHUNK_ID
) {
1124 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - DATA_CHUNK_HEADER_LENGTH
;
1126 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
) - I_DATA_CHUNK_HEADER_LENGTH
;
1128 info
->n_data_chunks_ep2
++;
1129 info
->n_data_bytes_ep2
+=length
;
1131 else if (forwardchunk
)
1133 info
->n_forward_chunks_ep2
++;
1138 if (info
->init
== false) {
1139 uint16_t tmp
= tvb_get_ntohs((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_STREAM_ID_OFFSET
)+1;
1140 if (info
->instream1
< tmp
) info
->instream1
= tmp
;
1142 if (info
->initack
== false) {
1143 uint16_t tmp
= tvb_get_ntohs((sctp_info
->tvb
)[chunk_number
], DATA_CHUNK_STREAM_ID_OFFSET
)+1;
1144 if (info
->outstream2
< tmp
) info
->outstream2
= tmp
;
1148 g_ptr_array_add(info
->sort_tsn2
, tsn_s
);
1149 info
->n_array_tsn2
++;
1152 else if (((tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_SACK_CHUNK_ID
) ||
1153 (tvb_get_uint8(sctp_info
->tvb
[chunk_number
],0) == SCTP_NR_SACK_CHUNK_ID
)) &&
1156 tsnumber
= tvb_get_ntohl((sctp_info
->tvb
)[chunk_number
], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET
);
1157 length
= tvb_get_ntohs(sctp_info
->tvb
[chunk_number
], CHUNK_LENGTH_OFFSET
);
1159 if (sack
->first_tsn
== 0)
1160 sack
->first_tsn
= tsnumber
;
1162 t_s_n
= (uint8_t *)g_malloc(length
);
1163 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (uint8_t *)(t_s_n
),0, length
);
1164 sack
->tsns
= g_list_append(sack
->tsns
, t_s_n
);
1166 tsn_s
= g_new0(struct tsn_sort
, 1);
1167 tsn_s
->tsnumber
= tsnumber
;
1168 tsn_s
->secs
= tsn
->secs
= (uint32_t)pinfo
->rel_ts
.secs
;
1169 tsn_s
->usecs
= tsn
->usecs
= (uint32_t)pinfo
->rel_ts
.nsecs
/1000;
1171 tsn_s
->framenumber
= framenumber
;
1172 tsn_s
->length
= tvb_get_ntohl(sctp_info
->tvb
[chunk_number
], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET
);
1174 if (tsn
->secs
< info
->min_secs
)
1176 info
->min_secs
= tsn
->secs
;
1177 info
->min_usecs
= tsn
->usecs
;
1179 else if (tsn
->secs
== info
->min_secs
&& tsn
->usecs
< info
->min_usecs
)
1180 info
->min_usecs
= tsn
->usecs
;
1182 if (tsn
->secs
> info
->max_secs
)
1184 info
->max_secs
= tsn
->secs
;
1185 info
->max_usecs
= tsn
->usecs
;
1187 else if (tsn
->secs
== info
->max_secs
&& tsn
->usecs
> info
->max_usecs
)
1188 info
->max_usecs
= tsn
->usecs
;
1191 if (info
->direction
== 2)
1193 if(tsnumber
< info
->min_tsn1
)
1194 info
->min_tsn1
= tsnumber
;
1195 if(tsnumber
> info
->max_tsn1
)
1196 info
->max_tsn1
= tsnumber
;
1197 if (tsn_s
->length
> info
->max_window1
)
1198 info
->max_window1
= tsn_s
->length
;
1199 g_ptr_array_add(info
->sort_sack1
, tsn_s
);
1200 info
->n_sack_chunks_ep1
++;
1202 else if (info
->direction
== 1)
1204 if(tsnumber
< info
->min_tsn2
)
1205 info
->min_tsn2
= tsnumber
;
1206 if(tsnumber
> info
->max_tsn2
)
1207 info
->max_tsn2
= tsnumber
;
1208 if (tsn_s
->length
> info
->max_window2
)
1209 info
->max_window2
= tsn_s
->length
;
1210 g_ptr_array_add(info
->sort_sack2
, tsn_s
);
1211 info
->n_sack_chunks_ep2
++;
1217 if (datachunk
|| forwardchunk
)
1219 if (info
->direction
== 1)
1220 info
->tsn1
= g_list_prepend(info
->tsn1
, tsn
);
1221 else if (info
->direction
== 2)
1222 info
->tsn2
= g_list_prepend(info
->tsn2
, tsn
);
1225 if (sackchunk
== true)
1227 if (info
->direction
== 1)
1228 info
->sack2
= g_list_prepend(info
->sack2
, sack
);
1229 else if(info
->direction
== 2)
1230 info
->sack1
= g_list_prepend(info
->sack1
, sack
);
1233 info
->n_tvbs
+= sctp_info
->number_of_tvbs
;
1234 sctp_tapinfo_struct
.sum_tvbs
+= sctp_info
->number_of_tvbs
;
1235 info
= calc_checksum(sctp_info
, info
);
1238 if (tsn
&& !tsn_used
)
1240 if (sack
&& !sack_used
)
1242 free_address(&tmp_info
.src
);
1243 free_address(&tmp_info
.dst
);
1244 return TAP_PACKET_REDRAW
;
1248 /****************************************************************************/
1250 remove_tap_listener_sctp_stat(void)
1252 if (sctp_tapinfo_struct
.is_registered
) {
1253 remove_tap_listener(&sctp_tapinfo_struct
);
1254 sctp_tapinfo_struct
.is_registered
= false;
1260 sctp_stat_scan(void)
1262 if (!sctp_tapinfo_struct
.is_registered
) {
1263 register_tap_listener_sctp_stat();
1267 const sctp_allassocs_info_t
*
1268 sctp_stat_get_info(void)
1270 return &sctp_tapinfo_struct
;
1273 const sctp_assoc_info_t
*
1274 get_sctp_assoc_info(uint16_t assoc_id
)
1276 sctp_tmp_info_t needle
= { .assoc_id
= assoc_id
};
1277 return find_assoc(&needle
);
1281 register_tap_listener_sctp_stat(void)
1283 GString
*error_string
;
1285 if (!sctp_tapinfo_struct
.is_registered
)
1287 if ((error_string
= register_tap_listener("sctp", &sctp_tapinfo_struct
, NULL
, 0, reset
, packet
, NULL
, NULL
))) {
1288 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", error_string
->str
);
1289 g_string_free(error_string
, TRUE
);
1292 sctp_tapinfo_struct
.is_registered
=true;