2 * Copyright 2004-2013, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "epan/packet_info.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 + \
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" },
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
};
116 void free_first(gpointer data
, gpointer user_data _U_
)
121 static void tsn_free(gpointer data
, gpointer user_data _U_
)
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
);
135 static void reset(void *arg
)
137 sctp_allassocs_info_t
*tapdata
= (sctp_allassocs_info_t
*)arg
;
139 sctp_assoc_info_t
* info
;
141 list
= g_list_first(tapdata
->assoc_info_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
);
153 if (info
->addr2
!= NULL
)
155 g_list_foreach(info
->addr2
,free_first
, NULL
);
156 g_list_free(info
->addr2
);
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
);
180 if (info
->tsn2
!= NULL
)
182 g_list_foreach(info
->tsn2
, tsn_free
, NULL
);
183 g_list_free(info
->tsn2
);
187 if (info
->sack1
!= NULL
)
189 g_list_foreach(info
->sack1
, tsn_free
, NULL
);
190 g_list_free(info
->sack1
);
194 if (info
->sack2
!= NULL
)
196 g_list_foreach(info
->sack2
, tsn_free
, NULL
);
197 g_list_free(info
->sack2
);
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
;
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
)
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
);
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
;
266 g_strlcpy(data
->checksum_type
,"UNKNOWN",8);
267 data
->n_checksum_errors
=0;
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 */
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
;
353 assoc_info
= &sctp_tapinfo_struct
;
354 if ((list
= g_list_last(assoc_info
->assoc_info_list
))!=NULL
)
358 cmp
=sctp_assoc_vtag_cmp(needle
, (sctp_assoc_info_t
*)(list
->data
));
363 info
= (sctp_assoc_info_t
*)(list
->data
);
366 case BACKWARD_STREAM
:
367 info
= (sctp_assoc_info_t
*)(list
->data
);
370 case FORWARD_ADD_FORWARD_VTAG
:
371 info
= (sctp_assoc_info_t
*)(list
->data
);
372 info
->verification_tag1
=needle
->verification_tag1
;
375 case BACKWARD_ADD_FORWARD_VTAG
:
376 info
= (sctp_assoc_info_t
*)(list
->data
);
377 info
->verification_tag1
=needle
->verification_tag1
;
380 case BACKWARD_ADD_BACKWARD_VTAG
:
381 info
= (sctp_assoc_info_t
*)(list
->data
);
382 info
->verification_tag2
=needle
->verification_tag1
;
385 case ADDRESS_FORWARD_STREAM
:
386 info
= (sctp_assoc_info_t
*)(list
->data
);
388 info
->check_address
=TRUE
;
390 case ADDRESS_BACKWARD_STREAM
:
391 info
= (sctp_assoc_info_t
*)(list
->data
);
393 info
->check_address
=TRUE
;
395 case ADDRESS_FORWARD_ADD_FORWARD_VTAG
:
396 info
= (sctp_assoc_info_t
*)(list
->data
);
397 info
->verification_tag1
=needle
->verification_tag1
;
399 info
->check_address
=TRUE
;
401 case ADDRESS_BACKWARD_ADD_FORWARD_VTAG
:
402 info
= (sctp_assoc_info_t
*)(list
->data
);
403 info
->verification_tag1
=needle
->verification_tag1
;
405 info
->check_address
=TRUE
;
407 case ADDRESS_BACKWARD_ADD_BACKWARD_VTAG
:
408 info
= (sctp_assoc_info_t
*)(list
->data
);
409 info
->verification_tag2
=needle
->verification_tag1
;
411 info
->check_address
=TRUE
;
415 list
= g_list_previous(list
);
421 static sctp_assoc_info_t
* add_chunk_count(address
* vadd
, sctp_assoc_info_t
* info
, guint32 direction
, guint32 type
)
425 sctp_addr_chunk
*ch
=NULL
;
429 list
= g_list_first(info
->addr_chunk_count
);
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
]++;
442 ch
->addr_count
[OTHER_CHUNKS_INDEX
]++;
447 list
= g_list_next(list
);
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
]++;
467 ch
->addr_count
[OTHER_CHUNKS_INDEX
]++;
469 info
->addr_chunk_count
= g_list_append(info
->addr_chunk_count
, ch
);
473 static sctp_assoc_info_t
* add_address(address
* vadd
, sctp_assoc_info_t
*info
, guint8 direction
)
479 list
= g_list_first(info
->addr1
);
481 list
= g_list_first(info
->addr2
);
485 v
= (address
*) (list
->data
);
486 if (ADDRESSES_EQUAL(vadd
, v
)) {
490 list
= g_list_next(list
);
494 info
->addr1
= g_list_append(info
->addr1
, vadd
);
495 else if (direction
==2)
496 info
->addr2
= g_list_append(info
->addr2
, vadd
);
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
;
513 guint8
*t_s_n
= NULL
;
514 gboolean sackchunk
= FALSE
;
515 gboolean datachunk
= FALSE
;
516 gboolean forwardchunk
= FALSE
;
517 struct tsn_sort
*tsn_s
;
522 sctp_info
= (struct _sctp_info
*) data
;
524 framenumber
=pinfo
->fd
->num
;
526 type
= sctp_info
->ip_src
.type
;
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;
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
;
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;
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;
580 tmp_info
.verification_tag1
= sctp_info
->verification_tag
;
581 tmp_info
.verification_tag2
= 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);
590 tmp_info
.initiate_tag
= 0;
593 info
= find_assoc(&tmp_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
;
620 info
->initack
= FALSE
;
621 info
->check_address
= FALSE
;
623 info
= calc_checksum(sctp_info
, info
);
625 info
->error_info_list
= NULL
;
626 info
->min_secs
= 0xffffffff;
627 info
->min_usecs
= 0xffffffff;
630 info
->min_tsn2
= 0xFFFFFFFF;
631 info
->min_tsn1
= 0xffffffff;
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
));
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
;
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
;
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
)
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
);
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
));
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
))
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
))
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
)
814 info
->n_data_chunks_ep1
++;
815 info
->n_data_bytes_ep1
+=length
;
818 info
->n_forward_chunks_ep1
++;
819 info
->max_tsn1
= tsnumber
;
821 if (tsn
->first_tsn
== 0)
822 tsn
->first_tsn
= tsnumber
;
825 t_s_n
= (guint8
*)g_malloc(16);
826 tvb_memcpy(sctp_info
->tvb
[chunk_number
], (guint8
*)(t_s_n
),0, 16);
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;
839 tsn_s
->framenumber
= framenumber
;
841 tsn_s
->length
= length
-DATA_CHUNK_HEADER_LENGTH
;
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
);
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;
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
);
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
);
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
);
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);
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) */
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
));
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
);
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
);
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
]++;
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
;
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
;
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
;
1092 if ((tvb_get_guint8(sctp_info
->tvb
[0],0)) == SCTP_INIT_CHUNK_ID
)
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
));
1107 sack
->first_tsn
= 0;
1108 tsn
= (tsn_t
*)g_malloc(sizeof(tsn_t
));
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
]++;
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
))
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
;
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
;
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;
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
)
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
;
1196 info
->n_data_chunks_ep1
++;
1197 info
->n_data_bytes_ep1
+= length
;
1199 else if (forwardchunk
)
1201 info
->n_forward_chunks_ep1
++;
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
)
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
;
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
++;
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
);
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;
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
);
1347 /****************************************************************************/
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
;
1371 sctp_update(void *dummy _U_)
1373 if (get_stat_dlg()!=NULL)
1374 sctp_stat_dlg_update();
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
);
1389 sctp_tapinfo_struct
.is_registered
=TRUE
;