1 /*
2 * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de>
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "config.h"
12
13 #include <string.h>
14 #include <math.h>
15
16 #include <glib.h>
17
18 #include "epan/packet_info.h"
19 #include "epan/tap.h"
20 #include "epan/value_string.h"
21
22 #include "ui/tap-sctp-analysis.h"
23
24 #include "ui/simple_dialog.h"
25
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
37
38 static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL};
39
40 static void
free_first(gpointer data,gpointer user_data _U_)41 free_first(gpointer data, gpointer user_data _U_)
42 {
43 g_free(data);
44 }
45
46 static void
tsn_free(gpointer data)47 tsn_free(gpointer data)
48 {
49 tsn_t *tsn;
50
51 tsn = (tsn_t *) data;
52 if (tsn->tsns != NULL)
53 {
54 g_list_free_full(tsn->tsns, g_free);
55 }
56 free_address(&tsn->src);
57 free_address(&tsn->dst);
58 g_free(tsn);
59 }
60
61 static void
chunk_free(gpointer data)62 chunk_free(gpointer data)
63 {
64 sctp_addr_chunk *chunk = (sctp_addr_chunk *) data;
65
66 free_address(&chunk->addr);
67 g_free(chunk);
68 }
69
70 static void
store_free(gpointer data)71 store_free(gpointer data)
72 {
73 address *addr = (address *) data;
74
75 free_address(addr);
76 g_free(addr);
77 }
78
79 static void
reset(void * arg)80 reset(void *arg)
81 {
82 sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg;
83 GList* list;
84 sctp_assoc_info_t * info;
85
86 list = g_list_first(tapdata->assoc_info_list);
87 while (list)
88 {
89 info = (sctp_assoc_info_t *) (list->data);
90
91 if (info->addr1 != NULL)
92 {
93 g_list_free_full(info->addr1, store_free);
94 info->addr1 = NULL;
95 }
96
97 if (info->addr2 != NULL)
98 {
99 g_list_free_full(info->addr2, store_free);
100 info->addr2 = NULL;
101 }
102
103 if (info->error_info_list != NULL)
104 {
105 g_list_free_full(info->error_info_list, g_free);
106 info->error_info_list = NULL;
107 }
108
109 if (info->frame_numbers != NULL)
110 {
111 g_list_free(info->frame_numbers);
112 info->frame_numbers = NULL;
113 }
114
115 if (info->tsn1 != NULL)
116 {
117 g_list_free_full(info->tsn1, tsn_free);
118 info->tsn1 = NULL;
119 }
120
121 if (info->tsn2 != NULL)
122 {
123 g_list_free_full(info->tsn2, tsn_free);
124 info->tsn2 = NULL;
125 }
126
127 if (info->sack1 != NULL)
128 {
129 g_list_free_full(info->sack1, tsn_free);
130 info->sack1 = NULL;
131 }
132
133 if (info->sack2 != NULL)
134 {
135 g_list_free_full(info->sack2, tsn_free);
136 info->sack2 = NULL;
137 }
138
139 if (info->sort_tsn1 != NULL)
140 g_ptr_array_free(info->sort_tsn1, TRUE);
141
142 if (info->sort_tsn2 != NULL)
143 g_ptr_array_free(info->sort_tsn2, TRUE);
144
145 if (info->sort_sack1 != NULL)
146 g_ptr_array_free(info->sort_sack1, TRUE);
147
148 if (info->sort_sack2 != NULL)
149 g_ptr_array_free(info->sort_sack2, TRUE);
150
151 if (info->min_max != NULL)
152 {
153 g_slist_foreach(info->min_max, free_first, NULL);
154 info->min_max = NULL;
155 }
156
157 if (info->addr_chunk_count) {
158 g_list_free_full(info->addr_chunk_count, chunk_free);
159 }
160
161 g_free(info->dir1);
162 g_free(info->dir2);
163 free_address(&info->src);
164 free_address(&info->dst);
165
166 g_free(list->data);
167 list = g_list_next(list);
168 }
169 g_list_free(tapdata->assoc_info_list);
170 tapdata->sum_tvbs = 0;
171 tapdata->assoc_info_list = NULL;
172 }
173
174
175 static sctp_assoc_info_t *
calc_checksum(const struct _sctp_info * check_data,sctp_assoc_info_t * data)176 calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data)
177 {
178 gboolean ok = FALSE;
179
180 if (check_data->adler32_calculated)
181 {
182 data->n_adler32_calculated++;
183 if (check_data->adler32_correct)
184 data->n_adler32_correct++;
185 }
186 if (check_data->crc32c_calculated)
187 {
188 data->n_crc32c_calculated++;
189 if (check_data->crc32c_correct)
190 data->n_crc32c_correct++;
191 }
192 if (data->n_adler32_calculated > 0)
193 {
194 if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5)
195 {
196 char str[] = "ADLER32";
197 (void) g_strlcpy(data->checksum_type, str, strlen(str));
198 data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
199 ok = TRUE;
200 }
201 }
202
203 if (data->n_crc32c_calculated>0)
204 {
205 if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5)
206 {
207 char str[] = "CRC32C";
208 (void) g_strlcpy(data->checksum_type, str, strlen(str));
209 data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
210 ok = TRUE;
211 }
212 }
213
214 if (!ok)
215 {
216 char str[] = "UNKNOWN";
217 (void) g_strlcpy(data->checksum_type, str, strlen(str));
218 data->n_checksum_errors=0;
219 }
220
221 return(data);
222
223 }
224
225
226 static sctp_assoc_info_t *
find_assoc(sctp_tmp_info_t * needle)227 find_assoc(sctp_tmp_info_t *needle)
228 {
229 sctp_allassocs_info_t *assoc_info;
230 sctp_assoc_info_t *info = NULL;
231 GList* list;
232
233 assoc_info = &sctp_tapinfo_struct;
234 if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL)
235 {
236 while (list)
237 {
238 info = (sctp_assoc_info_t*)(list->data);
239 if (needle->assoc_id == info->assoc_id)
240 return info;
241
242 list = g_list_previous(list);
243 }
244 }
245 return NULL;
246 }
247
248 static sctp_assoc_info_t *
add_chunk_count(address * vadd,sctp_assoc_info_t * info,guint32 direction,guint32 type)249 add_chunk_count(address *vadd, sctp_assoc_info_t *info, guint32 direction, guint32 type)
250 {
251 GList *list;
252 sctp_addr_chunk *ch=NULL;
253 int i;
254
255 list = g_list_first(info->addr_chunk_count);
256
257 while (list)
258 {
259 ch = (sctp_addr_chunk *)(list->data);
260 if (ch->direction == direction)
261 {
262 if (addresses_equal(vadd, &ch->addr))
263 {
264 if (IS_SCTP_CHUNK_TYPE(type))
265 ch->addr_count[type]++;
266 else
267 ch->addr_count[OTHER_CHUNKS_INDEX]++;
268 return info;
269 }
270 else
271 {
272 list = g_list_next(list);
273 }
274 }
275 else
276 list = g_list_next(list);
277 }
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;
283
284 if (IS_SCTP_CHUNK_TYPE(type))
285 ch->addr_count[type]++;
286 else
287 ch->addr_count[OTHER_CHUNKS_INDEX]++;
288
289 info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch);
290 return info;
291 }
292
293 static sctp_assoc_info_t *
add_address(address * vadd,sctp_assoc_info_t * info,guint16 direction)294 add_address(address *vadd, sctp_assoc_info_t *info, guint16 direction)
295 {
296 GList *list;
297 address *v=NULL;
298
299 if (direction == 1)
300 list = g_list_first(info->addr1);
301 else
302 list = g_list_first(info->addr2);
303
304 while (list)
305 {
306 v = (address *) (list->data);
307 if (addresses_equal(vadd, v)) {
308 free_address(vadd);
309 g_free(vadd);
310 return info;
311 }
312 list = g_list_next(list);
313 }
314
315 if (direction == 1)
316 info->addr1 = g_list_append(info->addr1, vadd);
317 else if (direction==2)
318 info->addr2 = g_list_append(info->addr2, vadd);
319
320 return info;
321 }
322
323 static tap_packet_status
packet(void * tapdata _U_,packet_info * pinfo,epan_dissect_t * edt _U_,const void * data)324 packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
325 {
326 const struct _sctp_info *sctp_info = (const struct _sctp_info *)data;
327 guint32 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 guint16 type, length = 0;
332 address *store = NULL;
333 tsn_t *tsn = NULL;
334 tsn_t *sack = NULL;
335 guint8 *t_s_n = NULL;
336 gboolean sackchunk = FALSE;
337 gboolean datachunk = FALSE;
338 gboolean forwardchunk = FALSE;
339 struct tsn_sort *tsn_s;
340 int i;
341 guint8 idx = 0;
342 gboolean tsn_used = FALSE;
343 gboolean sack_used = FALSE;
344
345 framenumber = pinfo->num;
346
347 type = sctp_info->ip_src.type;
348
349 if (type == AT_IPv4 || type == AT_IPv6)
350 copy_address(&tmp_info.src, &sctp_info->ip_src);
351 else
352 set_address(&tmp_info.src, AT_NONE, 0, NULL);
353
354 type = sctp_info->ip_dst.type;
355
356 if (type == AT_IPv4 || type == AT_IPv6)
357 copy_address(&tmp_info.dst, &sctp_info->ip_dst);
358 else
359 set_address(&tmp_info.dst, AT_NONE, 0, NULL);
360
361 tmp_info.port1 = sctp_info->sport;
362 tmp_info.port2 = sctp_info->dport;
363
364 if (sctp_info->vtag_reflected)
365 {
366 tmp_info.verification_tag2 = sctp_info->verification_tag;
367 tmp_info.verification_tag1 = 0;
368 }
369 else
370 {
371 tmp_info.verification_tag1 = sctp_info->verification_tag;
372 tmp_info.verification_tag2 = 0;
373 }
374 tmp_info.n_tvbs = 0;
375 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
376 {
377 tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4);
378 }
379 else
380 {
381 tmp_info.initiate_tag = 0;
382 }
383
384 tmp_info.direction = sctp_info->direction;
385 tmp_info.assoc_id = sctp_info->assoc_index;
386 info = find_assoc(&tmp_info);
387 if (!info)
388 {
389 tmp_info.n_tvbs = sctp_info->number_of_tvbs;
390 sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs;
391
392 if (sctp_info->number_of_tvbs > 0)
393 {
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;
404 info->init = FALSE;
405 info->initack = FALSE;
406 info->check_address = FALSE;
407 info->firstdata = TRUE;
408 info->direction = sctp_info->direction;
409 info->instream1 = 0;
410 info->outstream1 = 0;
411 info->instream2 = 0;
412 info->outstream2 = 0;
413 info = calc_checksum(sctp_info, info);
414 info->n_packets = 1;
415 info->error_info_list = NULL;
416 info->min_secs = 0xffffffff;
417 info->min_usecs = 0xffffffff;
418 info->max_secs = 0;
419 info->max_usecs = 0;
420 info->min_tsn2 = 0xFFFFFFFF;
421 info->min_tsn1 = 0xffffffff;
422 info->max_tsn1 = 0;
423 info->max_tsn2 = 0;
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;
450
451 for (i=0; i < NUM_CHUNKS; i++)
452 {
453 info->chunk_count[i] = 0;
454 info->ep1_chunk_count[i] = 0;
455 info->ep2_chunk_count[i] = 0;
456 }
457 info->addr_chunk_count = NULL;
458
459 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
460 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
461 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
462 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
463 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
464 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
465 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
466 {
467 tsn = g_new0(tsn_t, 1);
468 copy_address(&tsn->src, &tmp_info.src);
469 copy_address(&tsn->dst, &tmp_info.dst);
470
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 = (guint32)pinfo->rel_ts.secs;
475 sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
476
477 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
478 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
479 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
480 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
481 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
482 {
483 if (tsn->secs < info->min_secs)
484 {
485 info->min_secs = tsn->secs;
486 info->min_usecs = tsn->usecs;
487 }
488 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
489 info->min_usecs = tsn->usecs;
490
491 if (tsn->secs > info->max_secs)
492 {
493 info->max_secs = tsn->secs;
494 info->max_usecs = tsn->usecs;
495 }
496 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
497 info->max_usecs = tsn->usecs;
498 }
499
500 sack->frame_number = tsn->frame_number = pinfo->num;
501 }
502 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))
503 {
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++)
510 {
511 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
512 if (type == IPV4ADDRESS_PARAMETER_ID)
513 {
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);
517 }
518 else if (type == IPV6ADDRESS_PARAMETER_ID)
519 {
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);
523 }
524 }
525
526 if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID)
527 {
528 info->init = TRUE;
529 }
530 else
531 {
532 info->initack_dir = 1;
533 info->initack = TRUE;
534 }
535
536 idx = tvb_get_guint8(sctp_info->tvb[0],0);
537 if (!IS_SCTP_CHUNK_TYPE(idx))
538 idx = OTHER_CHUNKS_INDEX;
539
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_guint8(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_guint8(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;
552 }
553 } else {
554 if (tvb_get_guint8(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_guint8(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;
562 }
563 }
564 }
565 else
566 {
567 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) &&
568 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
569 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
570 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) &&
571 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) &&
572 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) &&
573 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID))
574 {
575 tsn = g_new0(tsn_t, 1);
576 sack = g_new0(tsn_t, 1);
577 }
578 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
579 {
580 idx = tvb_get_guint8(sctp_info->tvb[0],0);
581 if (!IS_SCTP_CHUNK_TYPE(idx))
582 idx = OTHER_CHUNKS_INDEX;
583
584 info->chunk_count[idx]++;
585 info->ep1_chunk_count[idx]++;
586 info = add_chunk_count(&tmp_info.src, info, 1, idx);
587
588 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
589 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
590 {
591 datachunk = TRUE;
592 if (tvb_get_guint8(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;
594 } else {
595 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
596 }
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;
600 }
601 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID))
602 {
603 forwardchunk = TRUE;
604 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
605 info->n_forward_chunks++;
606 }
607 if (datachunk || forwardchunk)
608 {
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)
614 {
615 if (datachunk)
616 {
617 info->n_data_chunks_ep1++;
618 info->n_data_bytes_ep1+=length;
619 }
620 else
621 info->n_forward_chunks_ep1++;
622 info->max_tsn1 = tsnumber;
623 }
624 if (tsn->first_tsn == 0)
625 tsn->first_tsn = tsnumber;
626 if (datachunk)
627 {
628 t_s_n = (guint8 *)g_malloc(16);
629 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
630 }
631 else
632 {
633 t_s_n = (guint8 *)g_malloc(length);
634 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
635 }
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 = (guint32)pinfo->rel_ts.secs;
640 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
641 tsn_s->offset = 0;
642 tsn_s->framenumber = framenumber;
643 if (datachunk)
644 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) {
645 tsn_s->length = length - DATA_CHUNK_HEADER_LENGTH;
646 } else {
647 tsn_s->length = length - I_DATA_CHUNK_HEADER_LENGTH;
648 }
649 else
650 tsn_s->length = length;
651 if (tsn->secs < info->min_secs)
652 {
653 info->min_secs = tsn->secs;
654 info->min_usecs = tsn->usecs;
655 }
656 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
657 info->min_usecs = tsn->usecs;
658
659 if (tsn->secs > info->max_secs)
660 {
661 info->max_secs = tsn->secs;
662 info->max_usecs = tsn->usecs;
663 }
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++;
668 }
669 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
670 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) )
671 {
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 = (guint8 *)g_malloc(length);
681 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
682 sack->tsns = g_list_append(sack->tsns, t_s_n);
683 sackchunk = TRUE;
684 tsn_s = g_new(struct tsn_sort, 1);
685 tsn_s->tsnumber = tsnumber;
686 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
687 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
688 tsn_s->offset = 0;
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)
694 {
695 info->min_secs = tsn->secs;
696 info->min_usecs = tsn->usecs;
697 }
698 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
699 info->min_usecs = tsn->usecs;
700
701 if (tsn->secs > info->max_secs)
702 {
703 info->max_secs = tsn->secs;
704 info->max_usecs = tsn->usecs;
705 }
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++;
710 }
711 }
712 }
713 if (info->verification_tag1 != 0 || info->verification_tag2 != 0)
714 {
715 guint32 number;
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);
723 else
724 info = add_address(store, info, 1);
725 number = pinfo->num;
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);
729 tsn_used = TRUE;
730 }
731 if (sackchunk == TRUE) {
732 info->sack2 = g_list_prepend(info->sack2, sack);
733 sack_used = TRUE;
734 }
735 sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
736 }
737 else
738 {
739 gchar* tmp_str;
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_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
744 {
745 tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(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);
748 }
749 else
750 {
751 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
752 {
753 tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(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);
756 }
757 }
758 error->info_text = "INFOS";
759 info->error_info_list = g_list_append(info->error_info_list, error);
760 }
761 }
762 } /* endif (!info) */
763 else
764 {
765 guint32 number;
766 info->direction = sctp_info->direction;
767
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;
772 }
773 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) ||
774 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
775 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
776 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
777 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
778 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
779 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
780 {
781
782 tsn = g_new0(tsn_t, 1);
783 copy_address(&tsn->src, &tmp_info.src);
784 copy_address(&tsn->dst, &tmp_info.dst);
785
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 = (guint32)pinfo->rel_ts.secs;
790 sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
791
792 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) ||
793 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) ||
794 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) ||
795 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) ||
796 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID))
797 {
798 if (tsn->secs < info->min_secs)
799 {
800 info->min_secs = tsn->secs;
801 info->min_usecs = tsn->usecs;
802 }
803 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
804 info->min_usecs = tsn->usecs;
805
806 if (tsn->secs > info->max_secs)
807 {
808 info->max_secs = tsn->secs;
809 info->max_usecs = tsn->usecs;
810 }
811 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
812 info->max_usecs = tsn->usecs;
813 }
814 sack->frame_number = tsn->frame_number = pinfo->num;
815 }
816 number = pinfo->num;
817 info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number));
818
819 store = g_new(address, 1);
820 copy_address(store, &tmp_info.src);
821
822 switch (info->direction) {
823 case 1:
824 info = add_address(store, info, 1);
825 break;
826 case 2:
827 info = add_address(store, info, 2);
828 break;
829 default:
830 g_free(store);
831 break;
832 }
833
834 store = g_new(address, 1);
835 copy_address(store, &tmp_info.dst);
836
837 switch (info->direction) {
838 case 1:
839 info = add_address(store, info, 2);
840 break;
841 case 2:
842 info = add_address(store, info, 1);
843 break;
844 default:
845 g_free(store);
846 break;
847 }
848
849 if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) ||
850 ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID))
851 {
852 tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET);
853 if (info->direction == 2)
854 {
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);
863 tsn_used = TRUE;
864 }
865 else if (info->direction == 1)
866 {
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);
875 tsn_used = TRUE;
876 }
877
878 idx = tvb_get_guint8(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]++;
884 else
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++)
888 {
889 type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
890 if (type == IPV4ADDRESS_PARAMETER_ID)
891 {
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);
895 }
896 else if (type == IPV6ADDRESS_PARAMETER_ID)
897 {
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);
901 }
902 }
903 if (info->direction == 1) {
904 if (info->dir1->init || info->dir1->initack) {
905 info->init_collision = TRUE;
906 }
907 if (tvb_get_guint8(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_guint8(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);
917 }
918 } else {
919 if (info->dir2->init || info->dir2->initack) {
920 info->init_collision = TRUE;
921 }
922 if (tvb_get_guint8(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_guint8(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);
932 }
933 }
934 if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID)
935 {
936 info->initack = TRUE;
937 info->initack_dir = info->direction;
938 }
939 else if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)
940 {
941 info->init = TRUE;
942 }
943 }
944 else
945 {
946 if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) &&
947 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) &&
948 ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_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))
952 {
953 if (!sack)
954 sack = g_new0(tsn_t, 1);
955 sack->tsns = NULL;
956 sack->first_tsn = 0;
957 if (!tsn)
958 tsn = g_new0(tsn_t, 1);
959 tsn->tsns = NULL;
960 tsn->first_tsn = 0;
961 }
962 for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
963 {
964 idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0);
965 if (!IS_SCTP_CHUNK_TYPE(idx))
966 idx = OTHER_CHUNKS_INDEX;
967
968 info->chunk_count[idx]++;
969 if (info->direction == 1)
970 info->ep1_chunk_count[idx]++;
971 else
972 info->ep2_chunk_count[idx]++;
973 info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
974
975 if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) ||
976 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID))
977 datachunk = TRUE;
978 if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID)
979 forwardchunk = TRUE;
980 if ((datachunk || forwardchunk) && tsn != NULL)
981 {
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;
985 if (datachunk)
986 {
987 t_s_n = (guint8 *)g_malloc(16);
988 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16);
989 if (tvb_get_guint8(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;
991 } else {
992 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
993 }
994 info->n_data_chunks++;
995 info->n_data_bytes+=length;
996 }
997 else
998 {
999 length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET);
1000 t_s_n = (guint8 *)g_malloc(length);
1001 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1002 info->n_forward_chunks++;
1003 }
1004 tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1005
1006 tsn_s = g_new0(struct tsn_sort, 1);
1007 tsn_s->tsnumber = tsnumber;
1008 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
1009 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1010 tsn_s->offset = 0;
1011 tsn_s->framenumber = framenumber;
1012 tsn_s->length = length;
1013
1014 if (tsn->secs < info->min_secs)
1015 {
1016 info->min_secs = tsn->secs;
1017 info->min_usecs = tsn->usecs;
1018 }
1019 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1020 info->min_usecs = tsn->usecs;
1021
1022 if (tsn->secs > info->max_secs)
1023 {
1024 info->max_secs = tsn->secs;
1025 info->max_usecs = tsn->usecs;
1026 }
1027 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1028 info->max_usecs = tsn->usecs;
1029
1030 if (info->direction == 1)
1031 {
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;
1037 }
1038 info->min_tsn2 = info->dir2->initack_min_tsn;
1039 }
1040 } else {
1041 if(tsnumber < info->min_tsn1) {
1042 info->min_tsn1 = tsnumber;
1043 }
1044 }
1045 if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1046 {
1047 if (datachunk)
1048 {
1049 info->n_data_chunks_ep1++;
1050 info->n_data_bytes_ep1 += length;
1051 }
1052 else if (forwardchunk)
1053 {
1054 info->n_forward_chunks_ep1++;
1055 }
1056 }
1057 if(tsnumber > info->max_tsn1)
1058 {
1059 info->max_tsn1 = tsnumber;
1060 if (datachunk)
1061 {
1062 info->n_data_chunks_ep1++;
1063 info->n_data_bytes_ep1 += length;
1064 }
1065 else if (forwardchunk)
1066 {
1067 info->n_forward_chunks_ep1++;
1068 }
1069 }
1070 if (datachunk)
1071 {
1072 if (info->init == FALSE) {
1073 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1074 if (info->outstream1 < tmp) info->outstream1 = tmp;
1075 }
1076 if (info->initack == FALSE) {
1077 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1078 if (info->instream2 < tmp) info->instream2 = tmp;
1079 }
1080 }
1081
1082 g_ptr_array_add(info->sort_tsn1, tsn_s);
1083 info->n_array_tsn1++;
1084 }
1085 else if (info->direction == 2)
1086 {
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;
1093 }
1094 info->min_tsn1 = info->dir1->initack_min_tsn;
1095 }
1096 } else {
1097 if(tsnumber < info->min_tsn2)
1098 info->min_tsn2 = tsnumber;
1099 }
1100
1101 if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1102 {
1103 if (datachunk)
1104 {
1105 if (tvb_get_guint8(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;
1107 } else {
1108 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
1109 }
1110 info->n_data_chunks_ep2++;
1111 info->n_data_bytes_ep2+=length;
1112 }
1113 else if (forwardchunk)
1114 {
1115 info->n_forward_chunks_ep2++;
1116 }
1117 }
1118 if (tsnumber > info->max_tsn2)
1119 {
1120 info->max_tsn2 = tsnumber;
1121 if (datachunk)
1122 {
1123 if (tvb_get_guint8(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;
1125 } else {
1126 length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH;
1127 }
1128 info->n_data_chunks_ep2++;
1129 info->n_data_bytes_ep2+=length;
1130 }
1131 else if (forwardchunk)
1132 {
1133 info->n_forward_chunks_ep2++;
1134 }
1135 }
1136 if (datachunk)
1137 {
1138 if (info->init == FALSE) {
1139 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1140 if (info->instream1 < tmp) info->instream1 = tmp;
1141 }
1142 if (info->initack == FALSE) {
1143 guint16 tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1;
1144 if (info->outstream2 < tmp) info->outstream2 = tmp;
1145 }
1146 }
1147
1148 g_ptr_array_add(info->sort_tsn2, tsn_s);
1149 info->n_array_tsn2++;
1150 }
1151 }
1152 else if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) ||
1153 (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID)) &&
1154 sack != NULL)
1155 {
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);
1158
1159 if (sack->first_tsn == 0)
1160 sack->first_tsn = tsnumber;
1161
1162 t_s_n = (guint8 *)g_malloc(length);
1163 tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length);
1164 sack->tsns = g_list_append(sack->tsns, t_s_n);
1165 sackchunk = TRUE;
1166 tsn_s = g_new0(struct tsn_sort, 1);
1167 tsn_s->tsnumber = tsnumber;
1168 tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs;
1169 tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000;
1170 tsn_s->offset = 0;
1171 tsn_s->framenumber = framenumber;
1172 tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET);
1173
1174 if (tsn->secs < info->min_secs)
1175 {
1176 info->min_secs = tsn->secs;
1177 info->min_usecs = tsn->usecs;
1178 }
1179 else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1180 info->min_usecs = tsn->usecs;
1181
1182 if (tsn->secs > info->max_secs)
1183 {
1184 info->max_secs = tsn->secs;
1185 info->max_usecs = tsn->usecs;
1186 }
1187 else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1188 info->max_usecs = tsn->usecs;
1189
1190
1191 if (info->direction == 2)
1192 {
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++;
1201 }
1202 else if (info->direction == 1)
1203 {
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++;
1212 }
1213 }
1214 }
1215 }
1216
1217 if (datachunk || forwardchunk)
1218 {
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);
1223 tsn_used = TRUE;
1224 }
1225 if (sackchunk == TRUE)
1226 {
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);
1231 sack_used = TRUE;
1232 }
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);
1236 info->n_packets++;
1237 }
1238 if (tsn && !tsn_used)
1239 tsn_free(tsn);
1240 if (sack && !sack_used)
1241 tsn_free(sack);
1242 free_address(&tmp_info.src);
1243 free_address(&tmp_info.dst);
1244 return TAP_PACKET_REDRAW;
1245 }
1246
1247
1248 /****************************************************************************/
1249 void
remove_tap_listener_sctp_stat(void)1250 remove_tap_listener_sctp_stat(void)
1251 {
1252 if (sctp_tapinfo_struct.is_registered) {
1253 remove_tap_listener(&sctp_tapinfo_struct);
1254 sctp_tapinfo_struct.is_registered = FALSE;
1255 }
1256 }
1257
1258
1259 void
sctp_stat_scan(void)1260 sctp_stat_scan(void)
1261 {
1262 if (!sctp_tapinfo_struct.is_registered) {
1263 register_tap_listener_sctp_stat();
1264 }
1265 }
1266
1267 const sctp_allassocs_info_t *
sctp_stat_get_info(void)1268 sctp_stat_get_info(void)
1269 {
1270 return &sctp_tapinfo_struct;
1271 }
1272
1273 const sctp_assoc_info_t *
get_sctp_assoc_info(guint16 assoc_id)1274 get_sctp_assoc_info(guint16 assoc_id)
1275 {
1276 sctp_tmp_info_t needle = { .assoc_id = assoc_id };
1277 return find_assoc(&needle);
1278 }
1279
1280 void
register_tap_listener_sctp_stat(void)1281 register_tap_listener_sctp_stat(void)
1282 {
1283 GString *error_string;
1284
1285 if (!sctp_tapinfo_struct.is_registered)
1286 {
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);
1290 return;
1291 }
1292 sctp_tapinfo_struct.is_registered=TRUE;
1293 }
1294 }
1295