Bug Summary

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