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

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-23-100321-3658-1 -x c /builds/wireshark/wireshark/ui/tap-sctp-analysis.c

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