### Bug Summary

File: | builds/wireshark/wireshark/ui/tap-sctp-analysis.c
Warning: | line 904, column 17 Potential leak of memory pointed to by 'store'

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tap-sctp-analysis.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/ui -I /builds/wireshark/wireshark/build/ui -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-05-15-100323-3641-1 -x c /builds/wireshark/wireshark/ui/tap-sctp-analysis.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

#### /builds/wireshark/wireshark/ui/tap-sctp-analysis.c

→

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 <wsutil/value_string.h>
21 |
22 | #include "ui/tap-sctp-analysis.h"
23 |
24 | #include "ui/simple_dialog.h"
25 |
26 | #define FORWARD_STREAM0 0
27 | #define BACKWARD_STREAM1 1
28 | #define FORWARD_ADD_FORWARD_VTAG2 2
29 | #define BACKWARD_ADD_FORWARD_VTAG3 3
30 | #define BACKWARD_ADD_BACKWARD_VTAG4 4
31 | #define ADDRESS_FORWARD_STREAM5 5
32 | #define ADDRESS_BACKWARD_STREAM6 6
33 | #define ADDRESS_FORWARD_ADD_FORWARD_VTAG7 7
34 | #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG8 8
35 | #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG9 9
36 | #define ASSOC_NOT_FOUND10 10
37 |
38 | static sctp_allassocs_info_t sctp_tapinfo_struct;
39 |
40 | static void
41 | free_first(void *data, void *user_data _U___attribute__((unused)))
42 | {
43 | g_free(data);
44 | }
45 |
46 | static void
47 | tsn_free(void *data)
48 | {
49 | tsn_t *tsn;
50 |
51 | tsn = (tsn_t *) data;
52 | if (tsn->tsns != NULL((void*)0))
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
62 | chunk_free(void *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
71 | store_free(void *data)
72 | {
73 | address *addr = (address *) data;
74 |
75 | free_address(addr);
76 | g_free(addr);
77 | }
78 |
79 | static void
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((void*)0))
92 | {
93 | g_list_free_full(info->addr1, store_free);
94 | info->addr1 = NULL((void*)0);
95 | }
96 |
97 | if (info->addr2 != NULL((void*)0))
98 | {
99 | g_list_free_full(info->addr2, store_free);
100 | info->addr2 = NULL((void*)0);
101 | }
102 |
103 | if (info->error_info_list != NULL((void*)0))
104 | {
105 | g_list_free_full(info->error_info_list, g_free);
106 | info->error_info_list = NULL((void*)0);
107 | }
108 |
109 | if (info->frame_numbers != NULL((void*)0))
110 | {
111 | g_list_free(info->frame_numbers);
112 | info->frame_numbers = NULL((void*)0);
113 | }
114 |
115 | if (info->tsn1 != NULL((void*)0))
116 | {
117 | g_list_free_full(info->tsn1, tsn_free);
118 | info->tsn1 = NULL((void*)0);
119 | }
120 |
121 | if (info->tsn2 != NULL((void*)0))
122 | {
123 | g_list_free_full(info->tsn2, tsn_free);
124 | info->tsn2 = NULL((void*)0);
125 | }
126 |
127 | if (info->sack1 != NULL((void*)0))
128 | {
129 | g_list_free_full(info->sack1, tsn_free);
130 | info->sack1 = NULL((void*)0);
131 | }
132 |
133 | if (info->sack2 != NULL((void*)0))
134 | {
135 | g_list_free_full(info->sack2, tsn_free);
136 | info->sack2 = NULL((void*)0);
137 | }
138 |
139 | if (info->sort_tsn1 != NULL((void*)0))
140 | g_ptr_array_free(info->sort_tsn1, true1);
141 |
142 | if (info->sort_tsn2 != NULL((void*)0))
143 | g_ptr_array_free(info->sort_tsn2, true1);
144 |
145 | if (info->sort_sack1 != NULL((void*)0))
146 | g_ptr_array_free(info->sort_sack1, true1);
147 |
148 | if (info->sort_sack2 != NULL((void*)0))
149 | g_ptr_array_free(info->sort_sack2, true1);
150 |
151 | if (info->min_max != NULL((void*)0))
152 | {
153 | g_slist_foreach(info->min_max, free_first, NULL((void*)0));
154 | info->min_max = NULL((void*)0);
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)((list) ? (((GList *)(list))->next) : ((void*)0));
168 | }
169 | g_list_free(tapdata->assoc_info_list);
170 | tapdata->sum_tvbs = 0;
171 | tapdata->assoc_info_list = NULL((void*)0);
172 | }
173 |
174 |
175 | static sctp_assoc_info_t *
176 | calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data)
177 | {
178 | bool_Bool ok = false0;
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, 8);
198 | data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct);
199 | ok = true1;
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, 8);
209 | data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct;
210 | ok = true1;
211 | }
212 | }
213 |
214 | if (!ok)
215 | {
216 | char str[] = "UNKNOWN";
217 | (void) g_strlcpy(data->checksum_type, str, 8);
218 | data->n_checksum_errors=0;
219 | }
220 |
221 | return(data);
222 |
223 | }
224 |
225 |
226 | static sctp_assoc_info_t *
227 | find_assoc(sctp_tmp_info_t *needle)
228 | {
229 | sctp_allassocs_info_t *assoc_info;
230 | sctp_assoc_info_t *info = NULL((void*)0);
231 | GList* list;
232 |
233 | assoc_info = &sctp_tapinfo_struct;
234 | if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL((void*)0))
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)((list) ? (((GList *)(list))->prev) : ((void*)0));
243 | }
244 | }
245 | return NULL((void*)0);
246 | }
247 |
248 | static sctp_assoc_info_t *
249 | add_chunk_count(address *vadd, sctp_assoc_info_t *info, uint32_t direction, uint32_t type)
250 | {
251 | GList *list;
252 | sctp_addr_chunk *ch=NULL((void*)0);
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)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81)))
265 | ch->addr_count[type]++;
266 | else
267 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++;
268 | return info;
269 | }
270 | else
271 | {
272 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0));
273 | }
274 | }
275 | else
276 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0));
277 | }
278 | ch = g_new(sctp_addr_chunk, 1)((sctp_addr_chunk *) g_malloc_n ((1), sizeof (sctp_addr_chunk )));
279 | ch->direction = direction;
280 | copy_address(&ch->addr, vadd);
281 | for (i=0; i < NUM_CHUNKS0x100; i++)
282 | ch->addr_count[i] = 0;
283 |
284 | if (IS_SCTP_CHUNK_TYPE(type)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81)))
285 | ch->addr_count[type]++;
286 | else
287 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++;
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 *
294 | add_address(address *vadd, sctp_assoc_info_t *info, uint16_t direction)
295 | {
296 | GList *list;
297 | address *v=NULL((void*)0);
298 |
299 | if (direction
55.1 | 'direction' is not equal to 1
55.1 | 'direction' is not equal to 1
== 1)
56 | ← | Taking false branch | →
300 | list = g_list_first(info->addr1);
301 | else
302 | list = g_list_first(info->addr2);
303 |
304 | while (list)
57 | ← | Loop condition is false. Execution continues on line 315 | →
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)((list) ? (((GList *)(list))->next) : ((void*)0));
313 | }
314 |
315 | if (direction
57.1 | 'direction' is not equal to 1
57.1 | 'direction' is not equal to 1
== 1)
58 | ← | Taking false branch | →
316 | info->addr1 = g_list_append(info->addr1, vadd);
317 | else if (direction
58.1 | 'direction' is not equal to 2
58.1 | 'direction' is not equal to 2
==2)
59 | ← | Taking false branch | →
318 | info->addr2 = g_list_append(info->addr2, vadd);
319 |
320 | return info;
60 | ← | Returning without deallocating memory or storing the pointer for later deallocation | →
321 | }
322 |
323 | static tap_packet_status
324 | packet(void *tapdata _U___attribute__((unused)), packet_info *pinfo, epan_dissect_t *edt _U___attribute__((unused)), const void *data, tap_flags_t flags _U___attribute__((unused)))
325 | {
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((void*)0);
330 | sctp_error_info_t *error = NULL((void*)0);
331 | uint16_t type, length = 0;
332 | address *store = NULL((void*)0);
333 | tsn_t *tsn = NULL((void*)0);
334 | tsn_t *sack = NULL((void*)0);
335 | uint8_t *t_s_n = NULL((void*)0);
336 | bool_Bool sackchunk = false0;
337 | bool_Bool datachunk = false0;
338 | bool_Bool forwardchunk = false0;
339 | struct tsn_sort *tsn_s;
340 | int i;
341 | uint8_t idx = 0;
342 | bool_Bool tsn_used = false0;
343 | bool_Bool sack_used = false0;
344 |
345 | framenumber = pinfo->num;
346 |
347 | type = sctp_info->ip_src.type;
348 |
349 | if (type == AT_IPv4 || type == AT_IPv6)
1 | Assuming 'type' is not equal to AT_IPv4 | →
2 | ← | Assuming 'type' is not equal to AT_IPv6 | →
3 | ← | Taking false branch | →
350 | copy_address(&tmp_info.src, &sctp_info->ip_src);
351 | else
352 | set_address(&tmp_info.src, AT_NONE, 0, NULL((void*)0));
353 |
354 | type = sctp_info->ip_dst.type;
355 |
356 | if (type == AT_IPv4 || type == AT_IPv6)
4 | ← | Assuming 'type' is not equal to AT_IPv4 | →
5 | ← | Assuming 'type' is not equal to AT_IPv6 | →
6 | ← | Taking false branch | →
357 | copy_address(&tmp_info.dst, &sctp_info->ip_dst);
358 | else
359 | set_address(&tmp_info.dst, AT_NONE, 0, NULL((void*)0));
360 |
361 | tmp_info.port1 = sctp_info->sport;
362 | tmp_info.port2 = sctp_info->dport;
363 |
364 | if (sctp_info->vtag_reflected)
7 | ← | Assuming field 'vtag_reflected' is false | →
8 | ← | Taking false branch | →
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_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1)
9 | ← | Assuming the condition is false | →
10 | ← | Taking false branch | →
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)
11 | ← | Assuming 'info' is non-null | →
12 | ← | Taking false branch | →
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)((sctp_assoc_info_t *) g_malloc0_n ((1), sizeof (sctp_assoc_info_t )));
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 = false0;
405 | info->initack = false0;
406 | info->check_address = false0;
407 | info->firstdata = true1;
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((void*)0);
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((void*)0);
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)((sctp_init_collision_t *) g_malloc0_n ((1), sizeof (sctp_init_collision_t )));
445 | info->dir1->init_min_tsn = 0xffffffff;
446 | info->dir1->initack_min_tsn = 0xffffffff;
447 | info->dir2 = g_new0(sctp_init_collision_t, 1)((sctp_init_collision_t *) g_malloc0_n ((1), sizeof (sctp_init_collision_t )));
448 | info->dir2->init_min_tsn = 0xffffffff;
449 | info->dir2->initack_min_tsn = 0xffffffff;
450 |
451 | for (i=0; i < NUM_CHUNKS0x100; 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((void*)0);
458 |
459 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) ||
460 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) ||
461 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) ||
462 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) ||
463 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) ||
464 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) ||
465 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0))
466 | {
467 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
468 | copy_address(&tsn->src, &tmp_info.src);
469 | copy_address(&tsn->dst, &tmp_info.dst);
470 |
471 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
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;
476 |
477 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) ||
478 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) ||
479 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) ||
480 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) ||
481 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0))
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_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) || (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2))
503 | {
504 | info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
505 | info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2));
506 | info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ));
507 | info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET(((((0 + 1) + 1) + 2) + 4 ) + 4 ));
508 | info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET((((0 + 1) + 1) + 2) + 4 ));
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_ID0x0005)
513 | {
514 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
515 | alloc_address_tvb(NULL((void*)0), store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET((0 + 2) + 2));
516 | info = add_address(store, info, info->direction);
517 | }
518 | else if (type == IPV6ADDRESS_PARAMETER_ID0x0006)
519 | {
520 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
521 | alloc_address_tvb(NULL((void*)0), store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET((0 + 2) + 2));
522 | info = add_address(store, info, info->direction);
523 | }
524 | }
525 |
526 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1)
527 | {
528 | info->init = true1;
529 | }
530 | else
531 | {
532 | info->initack_dir = 1;
533 | info->initack = true1;
534 | }
535 |
536 | idx = tvb_get_uint8(sctp_info->tvb[0],0);
537 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81)))
538 | idx = OTHER_CHUNKS_INDEX0xfe;
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_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) {
545 | info->dir1->init = true1;
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_ID2) {
549 | info->dir1->initack = true1;
550 | info->dir1->initack_min_tsn = info->min_tsn1;
551 | info->dir1->initack_vtag = info->verification_tag2;
552 | }
553 | } else {
554 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) {
555 | info->dir2->init = true1;
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_ID2) {
559 | info->dir2->initack = true1;
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_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID1) &&
568 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID2) &&
569 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID0) &&
570 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID0x40) &&
571 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID3) &&
572 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID16) &&
573 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID0xC0))
574 | {
575 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
576 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
577 | }
578 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
579 | {
580 | idx = tvb_get_uint8(sctp_info->tvb[0],0);
581 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81)))
582 | idx = OTHER_CHUNKS_INDEX0xfe;
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_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) ||
589 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID0x40))
590 | {
591 | datachunk = true1;
592 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) {
593 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4);
594 | } else {
595 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4);
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(((((0 + 1) + 1) + 2) + 0) + 4))+1;
600 | }
601 | if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID0xC0))
602 | {
603 | forwardchunk = true1;
604 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1));
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((((0 + 1) + 1) + 2) + 0));
610 | info->firstdata = false0;
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 = (uint8_t *)g_malloc(16);
629 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16);
630 | }
631 | else
632 | {
633 | t_s_n = (uint8_t *)g_malloc(length);
634 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(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)((struct tsn_sort *) g_malloc_n ((1), sizeof (struct tsn_sort )));
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;
641 | tsn_s->offset = 0;
642 | tsn_s->framenumber = framenumber;
643 | if (datachunk)
644 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) {
645 | tsn_s->length = length - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4);
646 | } else {
647 | tsn_s->length = length - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4);
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_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID3) ||
670 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID16) )
671 | {
672 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET((((0 + 1) + 1) + 2) + 0));
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((0 + 1) + 1));
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);
683 | sackchunk = true1;
684 | tsn_s = g_new(struct tsn_sort, 1)((struct tsn_sort *) g_malloc_n ((1), sizeof (struct tsn_sort )));
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;
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(((((0 + 1) + 1) + 2) + 0) + 4));
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 | uint32_t number;
716 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
717 | copy_address(store, &tmp_info.src);
718 | info = add_address(store, info, info->direction);
719 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
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)((gpointer) (gulong) (number)));
727 | if (datachunk || forwardchunk) {
728 | info->tsn1 = g_list_prepend(info->tsn1, tsn);
729 | tsn_used = true1;
730 | }
731 | if (sackchunk == true1) {
732 | info->sack2 = g_list_prepend(info->sack2, sack);
733 | sack_used = true1;
734 | }
735 | sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info);
736 | }
737 | else
738 | {
739 | char* tmp_str;
740 | error = g_new(sctp_error_info_t, 1)((sctp_error_info_t *) g_malloc_n ((1), sizeof (sctp_error_info_t )));
741 | error->frame_number = pinfo->num;
742 | error->chunk_info[0] = '\0';
743 | value_string* chunk_vals = get_external_value_string("chunk_type_values");
744 | if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1)
745 | {
746 | tmp_str = val_to_str(NULL((void*)0), tvb_get_uint8(sctp_info->tvb[0],0), chunk_vals,"Reserved (%d)");
747 | (void) g_strlcpy(error->chunk_info, tmp_str, 200);
748 | wmem_free(NULL((void*)0), tmp_str);
749 | }
750 | else
751 | {
752 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
753 | {
754 | tmp_str = val_to_str(NULL((void*)0), tvb_get_uint8(sctp_info->tvb[chunk_number],0), chunk_vals,"Reserved (%d)");
755 | (void) g_strlcat(error->chunk_info, tmp_str, 200);
756 | wmem_free(NULL((void*)0), tmp_str);
757 | }
758 | }
759 | error->info_text = "INFOS";
760 | info->error_info_list = g_list_append(info->error_info_list, error);
761 | }
762 | }
763 | } /* endif (!info) */
764 | else
765 | {
766 | uint32_t number;
767 | info->direction = sctp_info->direction;
768 |
769 | if (info->verification_tag1 == 0 && info->verification_tag2 != sctp_info->verification_tag) {
13 | ← | Assuming field 'verification_tag1' is not equal to 0 | →
770 | info->verification_tag1 = sctp_info->verification_tag;
771 | } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) {
14 | ← | Assuming field 'verification_tag2' is not equal to 0 | →
772 | info->verification_tag2 = sctp_info->verification_tag;
773 | }
774 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) ||
15 | ← | Assuming the condition is false | →
22 | ← | Taking false branch | →
775 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) ||
16 | ← | Assuming the condition is false | →
776 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) ||
17 | ← | Assuming the condition is false | →
777 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) ||
18 | ← | Assuming the condition is false | →
778 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) ||
19 | ← | Assuming the condition is false | →
779 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) ||
20 | ← | Assuming the condition is false | →
780 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0))
21 | ← | Assuming the condition is false | →
781 | {
782 |
783 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
784 | copy_address(&tsn->src, &tmp_info.src);
785 | copy_address(&tsn->dst, &tmp_info.dst);
786 |
787 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
788 | copy_address(&sack->src, &tmp_info.src);
789 | copy_address(&sack->dst, &tmp_info.dst);
790 | sack->secs=tsn->secs = (uint32_t)pinfo->rel_ts.secs;
791 | sack->usecs=tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
792 |
793 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) ||
794 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) ||
795 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) ||
796 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) ||
797 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0))
798 | {
799 | if (tsn->secs < info->min_secs)
800 | {
801 | info->min_secs = tsn->secs;
802 | info->min_usecs = tsn->usecs;
803 | }
804 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
805 | info->min_usecs = tsn->usecs;
806 |
807 | if (tsn->secs > info->max_secs)
808 | {
809 | info->max_secs = tsn->secs;
810 | info->max_usecs = tsn->usecs;
811 | }
812 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
813 | info->max_usecs = tsn->usecs;
814 | }
815 | sack->frame_number = tsn->frame_number = pinfo->num;
816 | }
817 | number = pinfo->num;
818 | info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number)((gpointer) (gulong) (number)));
819 |
820 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
821 | copy_address(store, &tmp_info.src);
822 |
823 | switch (info->direction) {
23 | ← | Control jumps to the 'default' case at line 830 | →
824 | case 1:
825 | info = add_address(store, info, 1);
826 | break;
827 | case 2:
828 | info = add_address(store, info, 2);
829 | break;
830 | default:
831 | g_free(store);
832 | break;
24 | ← | Execution continues on line 835 | →
833 | }
834 |
835 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
836 | copy_address(store, &tmp_info.dst);
837 |
838 | switch (info->direction) {
25 | ← | Control jumps to the 'default' case at line 845 | →
839 | case 1:
840 | info = add_address(store, info, 2);
841 | break;
842 | case 2:
843 | info = add_address(store, info, 1);
844 | break;
845 | default:
846 | g_free(store);
847 | break;
848 | }
849 |
850 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) ||
26 | ← | Assuming the condition is true | →
851 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1))
852 | {
853 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
854 | if (info->direction
26.1 | Field 'direction' is not equal to 2
26.1 | Field 'direction' is not equal to 2
== 2)
27 | ← | Taking false branch | →
855 | {
856 | if (tsnumber < info->min_tsn2)
857 | info->min_tsn2 = tsnumber;
858 | if (tsnumber > info->max_tsn2)
859 | info->max_tsn2 = tsnumber;
860 | info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ));
861 | info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET(((((0 + 1) + 1) + 2) + 4 ) + 4 ));
862 | info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET((((0 + 1) + 1) + 2) + 4 ));
863 | info->tsn2 = g_list_prepend(info->tsn2, tsn);
864 | tsn_used = true1;
865 | }
866 | else if (info->direction
27.1 | Field 'direction' is not equal to 1
27.1 | Field 'direction' is not equal to 1
== 1)
28 | ← | Taking false branch | →
867 | {
868 | if (tsnumber < info->min_tsn1)
869 | info->min_tsn1 = tsnumber;
870 | if (tsnumber > info->max_tsn1)
871 | info->max_tsn1 = tsnumber;
872 | info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ));
873 | info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET(((((0 + 1) + 1) + 2) + 4 ) + 4 ));
874 | info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET((((0 + 1) + 1) + 2) + 4 ));
875 | info->tsn1 = g_list_prepend(info->tsn1, tsn);
876 | tsn_used = true1;
877 | }
878 |
879 | idx = tvb_get_uint8(sctp_info->tvb[0],0);
880 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81)))
29 | ← | Assuming 'idx' is > 16 | →
30 | ← | Assuming 'idx' is not equal to 64 | →
31 | ← | Assuming 'idx' is not equal to 192 | →
32 | ← | Assuming 'idx' is not equal to 193 | →
33 | ← | Assuming 'idx' is not equal to 128 | →
34 | ← | Assuming 'idx' is not equal to 129 | →
35 | ← | Taking true branch | →
881 | idx = OTHER_CHUNKS_INDEX0xfe;
882 | info->chunk_count[idx]++;
883 | if (info->direction
35.1 | Field 'direction' is not equal to 1
35.1 | Field 'direction' is not equal to 1
== 1)
36 | ← | Taking false branch | →
884 | info->ep1_chunk_count[idx]++;
885 | else
886 | info->ep2_chunk_count[idx]++;
887 | info = add_chunk_count(&tmp_info.src, info, info->direction, idx);
888 | for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
37 | ← | Assuming 'chunk_number' is < field 'number_of_tvbs' | →
38 | ← | Loop condition is true. Entering loop body | →
62 | ← | Assuming 'chunk_number' is >= field 'number_of_tvbs' | →
63 | ← | Loop condition is false. Execution jumps to the end of the function | →
889 | {
890 | type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0);
891 | if (type == IPV4ADDRESS_PARAMETER_ID0x0005)
39 | ← | Assuming 'type' is equal to IPV4ADDRESS_PARAMETER_ID | →
40 | ← | Taking true branch | →
892 | {
893 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
41 | ← | Memory is allocated | →
894 | alloc_address_tvb(NULL((void*)0), store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET((0 + 2) + 2));
42 | ← | Calling 'alloc_address_tvb' | →
54 | ← | Returning from 'alloc_address_tvb' | →
895 | info = add_address(store, info, info->direction);
55 | ← | Calling 'add_address' | →
61 | ← | Returning from 'add_address' | →
896 | }
897 | else if (type == IPV6ADDRESS_PARAMETER_ID0x0006)
898 | {
899 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
900 | alloc_address_tvb(NULL((void*)0), store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET((0 + 2) + 2));
901 | info = add_address(store, info, info->direction);
902 | }
903 | }
904 | if (info->direction == 1) {
64 | ← | Potential leak of memory pointed to by 'store'
905 | if (info->dir1->init || info->dir1->initack) {
906 | info->init_collision = true1;
907 | }
908 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) {
909 | info->dir1->init = true1;
910 | info->dir1->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
911 | info->min_tsn1 = info->dir1->init_min_tsn;
912 | info->dir1->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2));
913 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) {
914 | info->dir1->initack = true1;
915 | info->dir1->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
916 | info->min_tsn1 = info->dir1->initack_min_tsn;
917 | info->dir1->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2));
918 | }
919 | } else {
920 | if (info->dir2->init || info->dir2->initack) {
921 | info->init_collision = true1;
922 | }
923 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) {
924 | info->dir2->init = true1;
925 | info->dir2->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
926 | info->min_tsn2 = info->dir2->init_min_tsn;
927 | info->dir2->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2));
928 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) {
929 | info->dir2->initack = true1;
930 | info->dir2->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 ));
931 | info->min_tsn2 = info->dir2->initack_min_tsn;
932 | info->dir2->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2));
933 | }
934 | }
935 | if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2)
936 | {
937 | info->initack = true1;
938 | info->initack_dir = info->direction;
939 | }
940 | else if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1)
941 | {
942 | info->init = true1;
943 | }
944 | }
945 | else
946 | {
947 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID2) &&
948 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID0) &&
949 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID0x40) &&
950 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID3) &&
951 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID16) &&
952 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID0xC0))
953 | {
954 | if (!sack)
955 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
956 | sack->tsns = NULL((void*)0);
957 | sack->first_tsn = 0;
958 | if (!tsn)
959 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t)));
960 | tsn->tsns = NULL((void*)0);
961 | tsn->first_tsn = 0;
962 | }
963 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++)
964 | {
965 | idx = tvb_get_uint8(sctp_info->tvb[chunk_number],0);
966 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81)))
967 | idx = OTHER_CHUNKS_INDEX0xfe;
968 |
969 | info->chunk_count[idx]++;
970 | if (info->direction == 1)
971 | info->ep1_chunk_count[idx]++;
972 | else
973 | info->ep2_chunk_count[idx]++;
974 | info = add_chunk_count(&tmp_info.src, info,info->direction, idx);
975 |
976 | if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) ||
977 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID0x40))
978 | datachunk = true1;
979 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID0xC0)
980 | forwardchunk = true1;
981 | if ((datachunk || forwardchunk) && tsn != NULL((void*)0))
982 | {
983 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET((((0 + 1) + 1) + 2) + 0));
984 | if (tsn->first_tsn == 0)
985 | tsn->first_tsn = tsnumber;
986 | if (datachunk)
987 | {
988 | t_s_n = (uint8_t *)g_malloc(16);
989 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16);
990 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) {
991 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1))-DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4);
992 | } else {
993 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4);
994 | }
995 | info->n_data_chunks++;
996 | info->n_data_bytes+=length;
997 | }
998 | else
999 | {
1000 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1));
1001 | t_s_n = (uint8_t *)g_malloc(length);
1002 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length);
1003 | info->n_forward_chunks++;
1004 | }
1005 | tsn->tsns = g_list_append(tsn->tsns, t_s_n);
1006 |
1007 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort )));
1008 | tsn_s->tsnumber = tsnumber;
1009 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs;
1010 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
1011 | tsn_s->offset = 0;
1012 | tsn_s->framenumber = framenumber;
1013 | tsn_s->length = length;
1014 |
1015 | if (tsn->secs < info->min_secs)
1016 | {
1017 | info->min_secs = tsn->secs;
1018 | info->min_usecs = tsn->usecs;
1019 | }
1020 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1021 | info->min_usecs = tsn->usecs;
1022 |
1023 | if (tsn->secs > info->max_secs)
1024 | {
1025 | info->max_secs = tsn->secs;
1026 | info->max_usecs = tsn->usecs;
1027 | }
1028 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1029 | info->max_usecs = tsn->usecs;
1030 |
1031 | if (info->direction == 1)
1032 | {
1033 | if (info->firstdata) {
1034 | info->firstdata = false0;
1035 | if (info->init_collision) {
1036 | if (tsnumber != info->min_tsn1) {
1037 | info->min_tsn1 = info->dir1->init_min_tsn;
1038 | }
1039 | info->min_tsn2 = info->dir2->initack_min_tsn;
1040 | }
1041 | } else {
1042 | if(tsnumber < info->min_tsn1) {
1043 | info->min_tsn1 = tsnumber;
1044 | }
1045 | }
1046 | if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1)
1047 | {
1048 | if (datachunk)
1049 | {
1050 | info->n_data_chunks_ep1++;
1051 | info->n_data_bytes_ep1 += length;
1052 | }
1053 | else if (forwardchunk)
1054 | {
1055 | info->n_forward_chunks_ep1++;
1056 | }
1057 | }
1058 | if(tsnumber > info->max_tsn1)
1059 | {
1060 | info->max_tsn1 = tsnumber;
1061 | if (datachunk)
1062 | {
1063 | info->n_data_chunks_ep1++;
1064 | info->n_data_bytes_ep1 += length;
1065 | }
1066 | else if (forwardchunk)
1067 | {
1068 | info->n_forward_chunks_ep1++;
1069 | }
1070 | }
1071 | if (datachunk)
1072 | {
1073 | if (info->init == false0) {
1074 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1;
1075 | if (info->outstream1 < tmp) info->outstream1 = tmp;
1076 | }
1077 | if (info->initack == false0) {
1078 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1;
1079 | if (info->instream2 < tmp) info->instream2 = tmp;
1080 | }
1081 | }
1082 |
1083 | g_ptr_array_add(info->sort_tsn1, tsn_s);
1084 | info->n_array_tsn1++;
1085 | }
1086 | else if (info->direction == 2)
1087 | {
1088 | if (info->firstdata) {
1089 | info->firstdata = false0;
1090 | if (info->init_collision) {
1091 | if (tsnumber != info->min_tsn2) {
1092 | info->min_tsn2 = info->dir2->init_min_tsn;
1093 | info->initack_dir = 2;
1094 | }
1095 | info->min_tsn1 = info->dir1->initack_min_tsn;
1096 | }
1097 | } else {
1098 | if(tsnumber < info->min_tsn2)
1099 | info->min_tsn2 = tsnumber;
1100 | }
1101 |
1102 | if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2)
1103 | {
1104 | if (datachunk)
1105 | {
1106 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) {
1107 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4);
1108 | } else {
1109 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4);
1110 | }
1111 | info->n_data_chunks_ep2++;
1112 | info->n_data_bytes_ep2+=length;
1113 | }
1114 | else if (forwardchunk)
1115 | {
1116 | info->n_forward_chunks_ep2++;
1117 | }
1118 | }
1119 | if (tsnumber > info->max_tsn2)
1120 | {
1121 | info->max_tsn2 = tsnumber;
1122 | if (datachunk)
1123 | {
1124 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) {
1125 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4);
1126 | } else {
1127 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4);
1128 | }
1129 | info->n_data_chunks_ep2++;
1130 | info->n_data_bytes_ep2+=length;
1131 | }
1132 | else if (forwardchunk)
1133 | {
1134 | info->n_forward_chunks_ep2++;
1135 | }
1136 | }
1137 | if (datachunk)
1138 | {
1139 | if (info->init == false0) {
1140 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1;
1141 | if (info->instream1 < tmp) info->instream1 = tmp;
1142 | }
1143 | if (info->initack == false0) {
1144 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1;
1145 | if (info->outstream2 < tmp) info->outstream2 = tmp;
1146 | }
1147 | }
1148 |
1149 | g_ptr_array_add(info->sort_tsn2, tsn_s);
1150 | info->n_array_tsn2++;
1151 | }
1152 | }
1153 | else if (((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID3) ||
1154 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID16)) &&
1155 | sack != NULL((void*)0))
1156 | {
1157 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET((((0 + 1) + 1) + 2) + 0));
1158 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1));
1159 |
1160 | if (sack->first_tsn == 0)
1161 | sack->first_tsn = tsnumber;
1162 |
1163 | t_s_n = (uint8_t *)g_malloc(length);
1164 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length);
1165 | sack->tsns = g_list_append(sack->tsns, t_s_n);
1166 | sackchunk = true1;
1167 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort )));
1168 | tsn_s->tsnumber = tsnumber;
1169 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs;
1170 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000;
1171 | tsn_s->offset = 0;
1172 | tsn_s->framenumber = framenumber;
1173 | tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4));
1174 |
1175 | if (tsn->secs < info->min_secs)
1176 | {
1177 | info->min_secs = tsn->secs;
1178 | info->min_usecs = tsn->usecs;
1179 | }
1180 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs)
1181 | info->min_usecs = tsn->usecs;
1182 |
1183 | if (tsn->secs > info->max_secs)
1184 | {
1185 | info->max_secs = tsn->secs;
1186 | info->max_usecs = tsn->usecs;
1187 | }
1188 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs)
1189 | info->max_usecs = tsn->usecs;
1190 |
1191 |
1192 | if (info->direction == 2)
1193 | {
1194 | if(tsnumber < info->min_tsn1)
1195 | info->min_tsn1 = tsnumber;
1196 | if(tsnumber > info->max_tsn1)
1197 | info->max_tsn1 = tsnumber;
1198 | if (tsn_s->length > info->max_window1)
1199 | info->max_window1 = tsn_s->length;
1200 | g_ptr_array_add(info->sort_sack1, tsn_s);
1201 | info->n_sack_chunks_ep1++;
1202 | }
1203 | else if (info->direction == 1)
1204 | {
1205 | if(tsnumber < info->min_tsn2)
1206 | info->min_tsn2 = tsnumber;
1207 | if(tsnumber > info->max_tsn2)
1208 | info->max_tsn2 = tsnumber;
1209 | if (tsn_s->length > info->max_window2)
1210 | info->max_window2 = tsn_s->length;
1211 | g_ptr_array_add(info->sort_sack2, tsn_s);
1212 | info->n_sack_chunks_ep2++;
1213 | }
1214 | }
1215 | }
1216 | }
1217 |
1218 | if (datachunk || forwardchunk)
1219 | {
1220 | if (info->direction == 1)
1221 | info->tsn1 = g_list_prepend(info->tsn1, tsn);
1222 | else if (info->direction == 2)
1223 | info->tsn2 = g_list_prepend(info->tsn2, tsn);
1224 | tsn_used = true1;
1225 | }
1226 | if (sackchunk == true1)
1227 | {
1228 | if (info->direction == 1)
1229 | info->sack2 = g_list_prepend(info->sack2, sack);
1230 | else if(info->direction == 2)
1231 | info->sack1 = g_list_prepend(info->sack1, sack);
1232 | sack_used = true1;
1233 | }
1234 | info->n_tvbs += sctp_info->number_of_tvbs;
1235 | sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs;
1236 | info = calc_checksum(sctp_info, info);
1237 | info->n_packets++;
1238 | }
1239 | if (tsn && !tsn_used)
1240 | tsn_free(tsn);
1241 | if (sack && !sack_used)
1242 | tsn_free(sack);
1243 | free_address(&tmp_info.src);
1244 | free_address(&tmp_info.dst);
1245 | return TAP_PACKET_REDRAW;
1246 | }
1247 |
1248 |
1249 | /****************************************************************************/
1250 | void
1251 | remove_tap_listener_sctp_stat(void)
1252 | {
1253 | if (sctp_tapinfo_struct.is_registered) {
1254 | remove_tap_listener(&sctp_tapinfo_struct);
1255 | sctp_tapinfo_struct.is_registered = false0;
1256 | }
1257 | }
1258 |
1259 |
1260 | void
1261 | sctp_stat_scan(void)
1262 | {
1263 | if (!sctp_tapinfo_struct.is_registered) {
1264 | register_tap_listener_sctp_stat();
1265 | }
1266 | }
1267 |
1268 | const sctp_allassocs_info_t *
1269 | sctp_stat_get_info(void)
1270 | {
1271 | return &sctp_tapinfo_struct;
1272 | }
1273 |
1274 | const sctp_assoc_info_t *
1275 | get_sctp_assoc_info(uint16_t assoc_id)
1276 | {
1277 | sctp_tmp_info_t needle = { .assoc_id = assoc_id };
1278 | return find_assoc(&needle);
1279 | }
1280 |
1281 | void
1282 | register_tap_listener_sctp_stat(void)
1283 | {
1284 | GString *error_string;
1285 |
1286 | if (!sctp_tapinfo_struct.is_registered)
1287 | {
1288 | if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL((void*)0), 0, reset, packet, NULL((void*)0), NULL((void*)0)))) {
1289 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", error_string->str);
1290 | g_string_free(error_string, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (error_string), ((!(0)))) : g_string_free_and_steal (error_string )) : (g_string_free) ((error_string), ((!(0)))));
1291 | return;
1292 | }
1293 | sctp_tapinfo_struct.is_registered=true1;
1294 | }
1295 | }

←

#### /builds/wireshark/wireshark/epan/address.h

1 | /** @file
2 | * Definitions for structures storing addresses, and for the type of
3 | * variables holding port-type values
4 | *
5 | * Wireshark - Network traffic analyzer
6 | * By Gerald Combs <gerald@wireshark.org>
7 | * Copyright 1998 Gerald Combs
8 | *
9 | * SPDX-License-Identifier: GPL-2.0-or-later
10 | */
11 | #pragma once
12 | #include <string.h> /* for memcmp */
13 |
14 | #include "tvbuff.h"
15 | #include <epan/wmem_scopes.h>
16 | #include <wsutil/ws_assert.h>
17 | #include <wsutil/inet_cidr.h>
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif /* __cplusplus */
22 |
23 | /* Types of "global" addresses Wireshark knows about. */
24 | /* Address types can be added here if there are many dissectors that use them or just
25 | * within a specific dissector.
26 | * If an address type is added here, it must be "registered" within address_types.c
27 | * For dissector address types, just use the address_type_dissector_register function
28 | * from address_types.h
29 | *
30 | * AT_NUMERIC - a numeric address type can consist of a uint8_t, uint16_t, uint32_t or uint64_t
31 | * value. If no correct length is provided, to avoid data bleed, a uint8_t is
32 | * assumed. Only representation (aka conversion of value to string) is implemented for this type.
33 | */
34 | typedef enum {
35 | AT_NONE, /* no link-layer address */
36 | AT_ETHER, /* MAC (Ethernet, 802.x, FDDI) address */
37 | AT_IPv4, /* IPv4 */
38 | AT_IPv6, /* IPv6 */
39 | AT_IPX, /* IPX */
40 | AT_FC, /* Fibre Channel */
41 | AT_FCWWN, /* Fibre Channel WWN */
42 | AT_STRINGZ, /* null-terminated string */
43 | AT_EUI64, /* IEEE EUI-64 */
44 | AT_IB, /* Infiniband GID/LID */
45 | AT_AX25, /* AX.25 */
46 | AT_VINES, /* Banyan Vines address */
47 | AT_NUMERIC, /* Numeric address type. */
48 | AT_MCTP, /* MCTP */
49 | AT_ILNP_NID, /* ILNP NID */
50 | AT_ILNP_L64, /* ILNP L64 */
51 | AT_ILNP_ILV, /* ILNP ILV */
52 | AT_END_OF_LIST /* Must be last in list */
53 | } address_type;
54 |
55 | typedef struct _address {
56 | int type; /* type of address */
57 | int len; /* length of address, in bytes */
58 | const void *data; /* pointer to address data */
59 |
60 | /* private */
61 | void *priv;
62 | } address;
63 |
64 | #define ADDRESS_INIT(type, len, data){type, len, data, ((void*)0)} {type, len, data, NULL((void*)0)}
65 | #define ADDRESS_INIT_NONE{AT_NONE, 0, ((void*)0), ((void*)0)} ADDRESS_INIT(AT_NONE, 0, NULL){AT_NONE, 0, ((void*)0), ((void*)0)}
66 |
67 | /** @brief Clear an address structure by setting its fields to default values.
68 |
69 | @param addr Pointer to the address structure to be cleared.
70 | */
71 | static inline void
72 | clear_address(address *addr)
73 | {
74 | addr->type = AT_NONE;
75 | addr->len = 0;
76 | addr->data = NULL((void*)0);
77 | addr->priv = NULL((void*)0);
78 | }
79 |
80 | /** Initialize an address with the given values.
81 | *
82 | * @param addr [in,out] The address to initialize.
83 | * @param addr_type [in] Address type.
84 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for
85 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
86 | * @param addr_data [in] Pointer to the address data.
87 | */
88 | static inline void
89 | set_address(address *addr, int addr_type, int addr_len, const void *addr_data) {
90 | if (addr_len == 0) {
91 | /* Zero length must mean no data */
92 | ws_assert(addr_data == NULL)do { if ((1) && !(addr_data == ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 92, __func__, "assertion failed: %s" , "addr_data == ((void*)0)"); } while (0);
93 | } else {
94 | /* Must not be AT_NONE - AT_NONE must have no data */
95 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 95, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0);
96 | /* Make sure we *do* have data */
97 | ws_assert(addr_data != NULL)do { if ((1) && !(addr_data != ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 97, __func__, "assertion failed: %s" , "addr_data != ((void*)0)"); } while (0);
98 | }
99 | addr->type = addr_type;
100 | addr->len = addr_len;
101 | addr->data = addr_data;
102 | addr->priv = NULL((void*)0);
103 | }
104 |
105 | /**
106 | * @brief Sets an address with the values from a provided IPv4 address.
107 | *
108 | * This function initializes an address structure with the provided IPv4 address and its length.
109 | *
110 | * @param addr Pointer to the address structure to be initialized.
111 | * @param ipv4 Pointer to the IPv4 address and mask information.
112 | */
113 | static inline void
114 | set_address_ipv4(address *addr, const ipv4_addr_and_mask *ipv4) {
115 | addr->type = AT_IPv4;
116 | addr->len = 4;
117 | uint32_t val = g_htonl(ipv4->addr)(((((guint32) ( (((guint32) (ipv4->addr) & (guint32) 0x000000ffU ) << 24) | (((guint32) (ipv4->addr) & (guint32) 0x0000ff00U ) << 8) | (((guint32) (ipv4->addr) & (guint32) 0x00ff0000U ) >> 8) | (((guint32) (ipv4->addr) & (guint32) 0xff000000U ) >> 24))))));
118 | addr->priv = g_memdup2(&val, sizeof(val));
119 | addr->data = addr->priv;
120 | }
121 |
122 | /**
123 | * @brief Sets an address with the values from a provided IPv6 address.
124 | *
125 | * This function initializes an address structure with the provided IPv6 address and its length.
126 | *
127 | * @param addr Pointer to the address structure to be initialized.
128 | * @param ipv6 Pointer to the IPv6 address and prefix information.
129 | */
130 | static inline void
131 | set_address_ipv6(address *addr, const ipv6_addr_and_prefix *ipv6) {
132 | set_address(addr, AT_IPv6, sizeof(ws_in6_addr), &ipv6->addr);
133 | }
134 |
135 | /**
136 | * @brief Initialize an address from TVB data.
137 | *
138 | * Same as set_address but it takes a TVB and an offset. This is preferred
139 | * over passing the return value of tvb_get_ptr() to set_address().
140 | *
141 | * This calls tvb_get_ptr() (including throwing any exceptions) before
142 | * modifying the address.
143 | *
144 | * @param addr [in,out] The address to initialize.
145 | * @param addr_type [in] Address type.
146 | * @param tvb [in] Pointer to the TVB.
147 | * @param offset [in] Offset within the TVB.
148 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for
149 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
150 | */
151 | static inline void
152 | set_address_tvb(address *addr, int addr_type, unsigned addr_len, tvbuff_t *tvb, unsigned offset) {
153 | const void *p;
154 |
155 | if (addr_len != 0) {
156 | /* Must not be AT_NONE - AT_NONE must have no data */
157 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 157, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0);
158 | p = tvb_get_ptr(tvb, offset, addr_len);
159 | } else
160 | p = NULL((void*)0);
161 | set_address(addr, addr_type, addr_len, p);
162 | }
163 |
164 | /**
165 | * @brief Initialize an address with the given values, allocating a new buffer
166 | * for the address data using wmem-scoped memory.
167 | *
168 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
169 | * @param addr [in,out] The address to initialize.
170 | * @param addr_type [in] Address type.
171 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for
172 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
173 | * @param addr_data [in] Pointer to the address data.
174 | */
175 | static inline void
176 | alloc_address_wmem(wmem_allocator_t *scope, address *addr,
177 | int addr_type, int addr_len, const void *addr_data) {
178 | ws_assert(addr)do { if ((1) && !(addr)) ws_log_fatal_full("", LOG_LEVEL_ERROR , "epan/address.h", 178, __func__, "assertion failed: %s", "addr" ); } while (0);
44 | ← | Assuming 'addr' is non-null | →
45 | ← | Taking false branch | →
46 | ← | Loop condition is false. Exiting loop | →
179 | clear_address(addr);
180 | addr->type = addr_type;
181 | if (addr_len
46.1 | 'addr_len' is not equal to 0
46.1 | 'addr_len' is not equal to 0
== 0) {
182 | /* Zero length must mean no data */
183 | ws_assert(addr_data == NULL)do { if ((1) && !(addr_data == ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 183, __func__, "assertion failed: %s" , "addr_data == ((void*)0)"); } while (0);
184 | /* Nothing to copy */
185 | return;
186 | }
187 | /* Must not be AT_NONE - AT_NONE must have no data */
188 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 188, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0);
47 | ← | Taking false branch | →
48 | ← | Taking false branch | →
189 | /* Make sure we *do* have data to copy */
190 | ws_assert(addr_data != NULL)do { if ((1) && !(addr_data != ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 190, __func__, "assertion failed: %s" , "addr_data != ((void*)0)"); } while (0);
49 | ← | Loop condition is false. Exiting loop | →
50 | ← | Assuming 'addr_data' is not equal to null | →
51 | ← | Taking false branch | →
52 | ← | Loop condition is false. Exiting loop | →
191 | addr->data = addr->priv = wmem_memdup(scope, addr_data, addr_len);
192 | addr->len = addr_len;
193 | }
194 |
195 | /**
196 | * @brief Allocate an address from TVB data.
197 | *
198 | * Same as alloc_address_wmem but it takes a TVB and an offset.
199 | *
200 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
201 | * @param addr [in,out] The address to initialize.
202 | * @param addr_type [in] Address type.
203 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for
204 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
205 | * @param tvb [in] Pointer to the TVB.
206 | * @param offset [in] Offset within the TVB.
207 | */
208 | static inline void
209 | alloc_address_tvb(wmem_allocator_t *scope, address *addr,
210 | int addr_type, int addr_len, tvbuff_t *tvb, int offset) {
211 | const void *p;
212 |
213 | p = tvb_get_ptr(tvb, offset, addr_len);
214 | alloc_address_wmem(scope, addr, addr_type, addr_len, p);
43 | ← | Calling 'alloc_address_wmem' | →
53 | ← | Returning from 'alloc_address_wmem' | →
215 | }
216 |
217 | /**
218 | * @brief Compare two addresses.
219 | *
220 | * @param addr1 [in] The first address to compare.
221 | * @param addr2 [in] The second address to compare.
222 | * @return 0 if the addresses are equal,
223 | * A positive number if addr1 > addr2 in some nondefined metric,
224 | * A negative number if addr1 < addr2 in some nondefined metric.
225 | */
226 | static inline int
227 | cmp_address(const address *addr1, const address *addr2) {
228 | if (addr1->type > addr2->type) return 1;
229 | if (addr1->type < addr2->type) return -1;
230 | if (addr1->len > addr2->len) return 1;
231 | if (addr1->len < addr2->len) return -1;
232 | if (addr1->len == 0) {
233 | /*
234 | * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
235 | * if both addresses are zero-length, don't compare them
236 | * (there's nothing to compare, so they're equal).
237 | */
238 | return 0;
239 | }
240 | return memcmp(addr1->data, addr2->data, addr1->len);
241 | }
242 |
243 | /**
244 | * @brief Check two addresses for equality.
245 | *
246 | * Given two addresses, return "true" if they're equal, "false" otherwise.
247 | * Addresses are equal only if they have the same type and length; if the
248 | * length is zero, they are then equal, otherwise the data must be the
249 | * same.
250 | *
251 | * @param addr1 [in] The first address to compare.
252 | * @param addr2 [in] The second address to compare.
253 | * @return true if the addresses are equal, false otherwise.
254 | */
255 | static inline bool_Bool
256 | addresses_equal(const address *addr1, const address *addr2) {
257 | /*
258 | * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
259 | * if both addresses are zero-length, don't compare them
260 | * (there's nothing to compare, so they're equal).
261 | */
262 | if (addr1->type == addr2->type &&
263 | addr1->len == addr2->len &&
264 | (addr1->len == 0 ||
265 | memcmp(addr1->data, addr2->data, addr1->len) == 0))
266 | return true1;
267 | return false0;
268 | }
269 |
270 | /**
271 | * @brief Check the data of two addresses for equality.
272 | *
273 | * Given two addresses, return "true" if they have the same length and,
274 | * their data is equal, "false" otherwise.
275 | * The address types are ignored. This can be used to compare custom
276 | * address types defined with address_type_dissector_register.
277 | *
278 | * @param addr1 [in] The first address to compare.
279 | * @param addr2 [in] The second address to compare.
280 | * @return true if the addresses are equal, false otherwise.
281 | */
282 | static inline bool_Bool
283 | addresses_data_equal(const address *addr1, const address *addr2) {
284 | if ( addr1->len == addr2->len
285 | && memcmp(addr1->data, addr2->data, addr1->len) == 0
286 | ) return true1;
287 | return false0;
288 | }
289 |
290 | /**
291 | * @brief Perform a shallow copy of the address (both addresses point to the same
292 | * memory location).
293 | *
294 | * @param to [in,out] The destination address.
295 | * @param from [in] The source address.
296 | *
297 | * \warning Make sure 'from' memory stays valid for the lifetime of this object.
298 | * Also it's strongly recommended to use this function instead of copy-assign.
299 | */
300 | static inline void
301 | copy_address_shallow(address *to, const address *from) {
302 | set_address(to, from->type, from->len, from->data);
303 | }
304 |
305 | /**
306 | * @brief Copy an address, allocating a new buffer for the address data
307 | * using wmem-scoped memory.
308 | *
309 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
310 | * @param to [in,out] The destination address.
311 | * @param from [in] The source address.
312 | */
313 | static inline void
314 | copy_address_wmem(wmem_allocator_t *scope, address *to, const address *from) {
315 | alloc_address_wmem(scope, to, from->type, from->len, from->data);
316 | }
317 |
318 | /**
319 | * @brief Copy an address, allocating a new buffer for the address data.
320 | *
321 | * @param to [in,out] The destination address.
322 | * @param from [in] The source address.
323 | */
324 | static inline void
325 | copy_address(address *to, const address *from) {
326 | copy_address_wmem(NULL((void*)0), to, from);
327 | }
328 |
329 | /**
330 | * @brief Free an address allocated with wmem-scoped memory.
331 | *
332 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
333 | * @param addr [in,out] The address whose data to free.
334 | */
335 | static inline void
336 | free_address_wmem(wmem_allocator_t *scope, address *addr) {
337 | /* Because many dissectors set 'type = AT_NONE' to mean clear we check for that */
338 | if (addr->type != AT_NONE && addr->len > 0 && addr->priv != NULL((void*)0)) {
339 | /* Make sure API use is correct */
340 | /* if priv is not null then data == priv */
341 | ws_assert(addr->data == addr->priv)do { if ((1) && !(addr->data == addr->priv)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 341, __func__, "assertion failed: %s" , "addr->data == addr->priv"); } while (0);
342 | wmem_free(scope, addr->priv);
343 | }
344 | clear_address(addr);
345 | }
346 |
347 | /**
348 | * @brief Free an address.
349 | *
350 | * @param addr [in,out] The address whose data to free.
351 | */
352 | static inline void
353 | free_address(address *addr) {
354 | free_address_wmem(NULL((void*)0), addr);
355 | }
356 |
357 | /**
358 | * @brief Hash an address into a hash value (which must already have been set).
359 | *
360 | * @param hash_val The existing hash value.
361 | * @param addr The address to add.
362 | * @return The new hash value.
363 | */
364 | static inline unsigned
365 | add_address_to_hash(unsigned hash_val, const address *addr) {
366 | const uint8_t *hash_data = (const uint8_t *)(addr)->data;
367 | int idx;
368 |
369 | for (idx = 0; idx < (addr)->len; idx++) {
370 | hash_val += hash_data[idx];
371 | hash_val += ( hash_val << 10 );
372 | hash_val ^= ( hash_val >> 6 );
373 | }
374 | return hash_val;
375 | }
376 |
377 | /**
378 | * @brief Hash an address into a hash value (which must already have been set).
379 | * 64-bit version of add_address_to_hash().
380 | *
381 | * @param hash_val The existing hash value.
382 | * @param addr The address to add.
383 | * @return The new hash value.
384 | */
385 | static inline uint64_t
386 | add_address_to_hash64(uint64_t hash_val, const address *addr) {
387 | const uint8_t *hash_data = (const uint8_t *)(addr)->data;
388 | int idx;
389 |
390 | for (idx = 0; idx < (addr)->len; idx++) {
391 | hash_val += hash_data[idx];
392 | hash_val += ( hash_val << 10 );
393 | hash_val ^= ( hash_val >> 6 );
394 | }
395 | return hash_val;
396 | }
397 |
398 | /**
399 | * @brief Converts an address to a byte array.
400 | *
401 | * This function takes an address structure and converts it into a byte array.
402 | * The output buffer must be provided with sufficient space to hold the address data.
403 | *
404 | * @param addr Pointer to the address structure to convert.
405 | * @param buf Buffer to store the converted byte array.
406 | * @param buf_len Length of the output buffer.
407 | * @return Number of bytes copied to the buffer, or 0 if an error occurred.
408 | */
409 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern unsigned address_to_bytes(const address *addr, uint8_t *buf, unsigned buf_len);
410 |
411 | /* Types of port numbers Wireshark knows about. */
412 | typedef enum {
413 | PT_NONE, /* no port number */
414 | PT_SCTP, /* SCTP */
415 | PT_TCP, /* TCP */
416 | PT_UDP, /* UDP */
417 | PT_DCCP, /* DCCP */
418 | PT_IPX, /* IPX sockets */
419 | PT_DDP, /* DDP AppleTalk connection */
420 | PT_IDP, /* XNS IDP sockets */
421 | PT_USB, /* USB endpoint 0xffff means the host */
422 | PT_I2C,
423 | PT_IBQP, /* Infiniband QP number */
424 | PT_BLUETOOTH,
425 | PT_IWARP_MPA, /* iWarp MPA */
426 | PT_MCTP
427 | } port_type;
428 |
429 | #ifdef __cplusplus
430 | }
431 | #endif /* __cplusplus */
432 |
433 | /*
434 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
435 | *
436 | * Local variables:
437 | * c-basic-offset: 4
438 | * tab-width: 8
439 | * indent-tabs-mode: nil
440 | * End:
441 | *
442 | * vi: set shiftwidth=4 tabstop=8 expandtab:
443 | * :indentSize=4:tabSize=8:noTabs=true:
444 | */