File: | builds/wireshark/wireshark/ui/tap-sctp-analysis.c |
Warning: | line 903, column 17 Potential leak of memory pointed to by 'store' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 "epan/value_string.h" | ||||
21 | |||||
22 | #include "ui/tap-sctp-analysis.h" | ||||
23 | |||||
24 | #include "ui/simple_dialog.h" | ||||
25 | |||||
26 | #define FORWARD_STREAM0 0 | ||||
27 | #define BACKWARD_STREAM1 1 | ||||
28 | #define FORWARD_ADD_FORWARD_VTAG2 2 | ||||
29 | #define BACKWARD_ADD_FORWARD_VTAG3 3 | ||||
30 | #define BACKWARD_ADD_BACKWARD_VTAG4 4 | ||||
31 | #define ADDRESS_FORWARD_STREAM5 5 | ||||
32 | #define ADDRESS_BACKWARD_STREAM6 6 | ||||
33 | #define ADDRESS_FORWARD_ADD_FORWARD_VTAG7 7 | ||||
34 | #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG8 8 | ||||
35 | #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG9 9 | ||||
36 | #define ASSOC_NOT_FOUND10 10 | ||||
37 | |||||
38 | static sctp_allassocs_info_t sctp_tapinfo_struct; | ||||
39 | |||||
40 | static void | ||||
41 | free_first(void *data, void *user_data _U___attribute__((unused))) | ||||
42 | { | ||||
43 | g_free(data); | ||||
44 | } | ||||
45 | |||||
46 | static void | ||||
47 | tsn_free(void *data) | ||||
48 | { | ||||
49 | tsn_t *tsn; | ||||
50 | |||||
51 | tsn = (tsn_t *) data; | ||||
52 | if (tsn->tsns != NULL((void*)0)) | ||||
53 | { | ||||
54 | g_list_free_full(tsn->tsns, g_free); | ||||
55 | } | ||||
56 | free_address(&tsn->src); | ||||
57 | free_address(&tsn->dst); | ||||
58 | g_free(tsn); | ||||
59 | } | ||||
60 | |||||
61 | static void | ||||
62 | chunk_free(void *data) | ||||
63 | { | ||||
64 | sctp_addr_chunk *chunk = (sctp_addr_chunk *) data; | ||||
65 | |||||
66 | free_address(&chunk->addr); | ||||
67 | g_free(chunk); | ||||
68 | } | ||||
69 | |||||
70 | static void | ||||
71 | store_free(void *data) | ||||
72 | { | ||||
73 | address *addr = (address *) data; | ||||
74 | |||||
75 | free_address(addr); | ||||
76 | g_free(addr); | ||||
77 | } | ||||
78 | |||||
79 | static void | ||||
80 | reset(void *arg) | ||||
81 | { | ||||
82 | sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg; | ||||
83 | GList* list; | ||||
84 | sctp_assoc_info_t * info; | ||||
85 | |||||
86 | list = g_list_first(tapdata->assoc_info_list); | ||||
87 | while (list) | ||||
88 | { | ||||
89 | info = (sctp_assoc_info_t *) (list->data); | ||||
90 | |||||
91 | if (info->addr1 != NULL((void*)0)) | ||||
92 | { | ||||
93 | g_list_free_full(info->addr1, store_free); | ||||
94 | info->addr1 = NULL((void*)0); | ||||
95 | } | ||||
96 | |||||
97 | if (info->addr2 != NULL((void*)0)) | ||||
98 | { | ||||
99 | g_list_free_full(info->addr2, store_free); | ||||
100 | info->addr2 = NULL((void*)0); | ||||
101 | } | ||||
102 | |||||
103 | if (info->error_info_list != NULL((void*)0)) | ||||
104 | { | ||||
105 | g_list_free_full(info->error_info_list, g_free); | ||||
106 | info->error_info_list = NULL((void*)0); | ||||
107 | } | ||||
108 | |||||
109 | if (info->frame_numbers != NULL((void*)0)) | ||||
110 | { | ||||
111 | g_list_free(info->frame_numbers); | ||||
112 | info->frame_numbers = NULL((void*)0); | ||||
113 | } | ||||
114 | |||||
115 | if (info->tsn1 != NULL((void*)0)) | ||||
116 | { | ||||
117 | g_list_free_full(info->tsn1, tsn_free); | ||||
118 | info->tsn1 = NULL((void*)0); | ||||
119 | } | ||||
120 | |||||
121 | if (info->tsn2 != NULL((void*)0)) | ||||
122 | { | ||||
123 | g_list_free_full(info->tsn2, tsn_free); | ||||
124 | info->tsn2 = NULL((void*)0); | ||||
125 | } | ||||
126 | |||||
127 | if (info->sack1 != NULL((void*)0)) | ||||
128 | { | ||||
129 | g_list_free_full(info->sack1, tsn_free); | ||||
130 | info->sack1 = NULL((void*)0); | ||||
131 | } | ||||
132 | |||||
133 | if (info->sack2 != NULL((void*)0)) | ||||
134 | { | ||||
135 | g_list_free_full(info->sack2, tsn_free); | ||||
136 | info->sack2 = NULL((void*)0); | ||||
137 | } | ||||
138 | |||||
139 | if (info->sort_tsn1 != NULL((void*)0)) | ||||
140 | g_ptr_array_free(info->sort_tsn1, true1); | ||||
141 | |||||
142 | if (info->sort_tsn2 != NULL((void*)0)) | ||||
143 | g_ptr_array_free(info->sort_tsn2, true1); | ||||
144 | |||||
145 | if (info->sort_sack1 != NULL((void*)0)) | ||||
146 | g_ptr_array_free(info->sort_sack1, true1); | ||||
147 | |||||
148 | if (info->sort_sack2 != NULL((void*)0)) | ||||
149 | g_ptr_array_free(info->sort_sack2, true1); | ||||
150 | |||||
151 | if (info->min_max != NULL((void*)0)) | ||||
152 | { | ||||
153 | g_slist_foreach(info->min_max, free_first, NULL((void*)0)); | ||||
154 | info->min_max = NULL((void*)0); | ||||
155 | } | ||||
156 | |||||
157 | if (info->addr_chunk_count) { | ||||
158 | g_list_free_full(info->addr_chunk_count, chunk_free); | ||||
159 | } | ||||
160 | |||||
161 | g_free(info->dir1); | ||||
162 | g_free(info->dir2); | ||||
163 | free_address(&info->src); | ||||
164 | free_address(&info->dst); | ||||
165 | |||||
166 | g_free(list->data); | ||||
167 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
168 | } | ||||
169 | g_list_free(tapdata->assoc_info_list); | ||||
170 | tapdata->sum_tvbs = 0; | ||||
171 | tapdata->assoc_info_list = NULL((void*)0); | ||||
172 | } | ||||
173 | |||||
174 | |||||
175 | static sctp_assoc_info_t * | ||||
176 | calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data) | ||||
177 | { | ||||
178 | bool_Bool ok = false0; | ||||
179 | |||||
180 | if (check_data->adler32_calculated) | ||||
181 | { | ||||
182 | data->n_adler32_calculated++; | ||||
183 | if (check_data->adler32_correct) | ||||
184 | data->n_adler32_correct++; | ||||
185 | } | ||||
186 | if (check_data->crc32c_calculated) | ||||
187 | { | ||||
188 | data->n_crc32c_calculated++; | ||||
189 | if (check_data->crc32c_correct) | ||||
190 | data->n_crc32c_correct++; | ||||
191 | } | ||||
192 | if (data->n_adler32_calculated > 0) | ||||
193 | { | ||||
194 | if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5) | ||||
195 | { | ||||
196 | char str[] = "ADLER32"; | ||||
197 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
198 | data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct); | ||||
199 | ok = true1; | ||||
200 | } | ||||
201 | } | ||||
202 | |||||
203 | if (data->n_crc32c_calculated>0) | ||||
204 | { | ||||
205 | if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5) | ||||
206 | { | ||||
207 | char str[] = "CRC32C"; | ||||
208 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
209 | data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct; | ||||
210 | ok = true1; | ||||
211 | } | ||||
212 | } | ||||
213 | |||||
214 | if (!ok) | ||||
215 | { | ||||
216 | char str[] = "UNKNOWN"; | ||||
217 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
218 | data->n_checksum_errors=0; | ||||
219 | } | ||||
220 | |||||
221 | return(data); | ||||
222 | |||||
223 | } | ||||
224 | |||||
225 | |||||
226 | static sctp_assoc_info_t * | ||||
227 | find_assoc(sctp_tmp_info_t *needle) | ||||
228 | { | ||||
229 | sctp_allassocs_info_t *assoc_info; | ||||
230 | sctp_assoc_info_t *info = NULL((void*)0); | ||||
231 | GList* list; | ||||
232 | |||||
233 | assoc_info = &sctp_tapinfo_struct; | ||||
234 | if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL((void*)0)) | ||||
235 | { | ||||
236 | while (list) | ||||
237 | { | ||||
238 | info = (sctp_assoc_info_t*)(list->data); | ||||
239 | if (needle->assoc_id == info->assoc_id) | ||||
240 | return info; | ||||
241 | |||||
242 | list = g_list_previous(list)((list) ? (((GList *)(list))->prev) : ((void*)0)); | ||||
243 | } | ||||
244 | } | ||||
245 | return NULL((void*)0); | ||||
246 | } | ||||
247 | |||||
248 | static sctp_assoc_info_t * | ||||
249 | add_chunk_count(address *vadd, sctp_assoc_info_t *info, uint32_t direction, uint32_t type) | ||||
250 | { | ||||
251 | GList *list; | ||||
252 | sctp_addr_chunk *ch=NULL((void*)0); | ||||
253 | int i; | ||||
254 | |||||
255 | list = g_list_first(info->addr_chunk_count); | ||||
256 | |||||
257 | while (list) | ||||
258 | { | ||||
259 | ch = (sctp_addr_chunk *)(list->data); | ||||
260 | if (ch->direction == direction) | ||||
261 | { | ||||
262 | if (addresses_equal(vadd, &ch->addr)) | ||||
263 | { | ||||
264 | if (IS_SCTP_CHUNK_TYPE(type)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81))) | ||||
265 | ch->addr_count[type]++; | ||||
266 | else | ||||
267 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++; | ||||
268 | return info; | ||||
269 | } | ||||
270 | else | ||||
271 | { | ||||
272 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
273 | } | ||||
274 | } | ||||
275 | else | ||||
276 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
277 | } | ||||
278 | ch = g_new(sctp_addr_chunk, 1)((sctp_addr_chunk *) g_malloc_n ((1), sizeof (sctp_addr_chunk ))); | ||||
279 | ch->direction = direction; | ||||
280 | copy_address(&ch->addr, vadd); | ||||
281 | for (i=0; i < NUM_CHUNKS0x100; i++) | ||||
282 | ch->addr_count[i] = 0; | ||||
283 | |||||
284 | if (IS_SCTP_CHUNK_TYPE(type)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81))) | ||||
285 | ch->addr_count[type]++; | ||||
286 | else | ||||
287 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++; | ||||
288 | |||||
289 | info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch); | ||||
290 | return info; | ||||
291 | } | ||||
292 | |||||
293 | static sctp_assoc_info_t * | ||||
294 | add_address(address *vadd, sctp_assoc_info_t *info, uint16_t direction) | ||||
295 | { | ||||
296 | GList *list; | ||||
297 | address *v=NULL((void*)0); | ||||
298 | |||||
299 | if (direction
| ||||
300 | list = g_list_first(info->addr1); | ||||
301 | else | ||||
302 | list = g_list_first(info->addr2); | ||||
303 | |||||
304 | while (list) | ||||
305 | { | ||||
306 | v = (address *) (list->data); | ||||
307 | if (addresses_equal(vadd, v)) { | ||||
308 | free_address(vadd); | ||||
309 | g_free(vadd); | ||||
310 | return info; | ||||
311 | } | ||||
312 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
313 | } | ||||
314 | |||||
315 | if (direction
| ||||
316 | info->addr1 = g_list_append(info->addr1, vadd); | ||||
317 | else if (direction
| ||||
318 | info->addr2 = g_list_append(info->addr2, vadd); | ||||
319 | |||||
320 | return info; | ||||
321 | } | ||||
322 | |||||
323 | static tap_packet_status | ||||
324 | packet(void *tapdata _U___attribute__((unused)), packet_info *pinfo, epan_dissect_t *edt _U___attribute__((unused)), const void *data, tap_flags_t flags _U___attribute__((unused))) | ||||
325 | { | ||||
326 | const struct _sctp_info *sctp_info = (const struct _sctp_info *)data; | ||||
327 | uint32_t chunk_number = 0, tsnumber, framenumber; | ||||
328 | sctp_tmp_info_t tmp_info; | ||||
329 | sctp_assoc_info_t *info = NULL((void*)0); | ||||
330 | sctp_error_info_t *error = NULL((void*)0); | ||||
331 | uint16_t type, length = 0; | ||||
332 | address *store = NULL((void*)0); | ||||
333 | tsn_t *tsn = NULL((void*)0); | ||||
334 | tsn_t *sack = NULL((void*)0); | ||||
335 | uint8_t *t_s_n = NULL((void*)0); | ||||
336 | bool_Bool sackchunk = false0; | ||||
337 | bool_Bool datachunk = false0; | ||||
338 | bool_Bool forwardchunk = false0; | ||||
339 | struct tsn_sort *tsn_s; | ||||
340 | int i; | ||||
341 | uint8_t idx = 0; | ||||
342 | bool_Bool tsn_used = false0; | ||||
343 | bool_Bool sack_used = false0; | ||||
344 | |||||
345 | framenumber = pinfo->num; | ||||
346 | |||||
347 | type = sctp_info->ip_src.type; | ||||
348 | |||||
349 | if (type == AT_IPv4 || type == AT_IPv6) | ||||
| |||||
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) | ||||
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) | ||||
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) | ||||
376 | { | ||||
377 | tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4); | ||||
378 | } | ||||
379 | else | ||||
380 | { | ||||
381 | tmp_info.initiate_tag = 0; | ||||
382 | } | ||||
383 | |||||
384 | tmp_info.direction = sctp_info->direction; | ||||
385 | tmp_info.assoc_id = sctp_info->assoc_index; | ||||
386 | info = find_assoc(&tmp_info); | ||||
387 | if (!info) | ||||
388 | { | ||||
389 | tmp_info.n_tvbs = sctp_info->number_of_tvbs; | ||||
390 | sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs; | ||||
391 | |||||
392 | if (sctp_info->number_of_tvbs > 0) | ||||
393 | { | ||||
394 | info = g_new0(sctp_assoc_info_t, 1)((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 | if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) | ||||
744 | { | ||||
745 | tmp_str = val_to_str_wmem(NULL((void*)0), tvb_get_uint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved (%d)"); | ||||
746 | (void) g_strlcpy(error->chunk_info, tmp_str, 200); | ||||
747 | wmem_free(NULL((void*)0), tmp_str); | ||||
748 | } | ||||
749 | else | ||||
750 | { | ||||
751 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) | ||||
752 | { | ||||
753 | tmp_str = val_to_str_wmem(NULL((void*)0), tvb_get_uint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved (%d)"); | ||||
754 | (void) g_strlcat(error->chunk_info, tmp_str, 200); | ||||
755 | wmem_free(NULL((void*)0), tmp_str); | ||||
756 | } | ||||
757 | } | ||||
758 | error->info_text = "INFOS"; | ||||
759 | info->error_info_list = g_list_append(info->error_info_list, error); | ||||
760 | } | ||||
761 | } | ||||
762 | } /* endif (!info) */ | ||||
763 | else | ||||
764 | { | ||||
765 | uint32_t number; | ||||
766 | info->direction = sctp_info->direction; | ||||
767 | |||||
768 | if (info->verification_tag1 == 0 && info->verification_tag2 != sctp_info->verification_tag) { | ||||
769 | info->verification_tag1 = sctp_info->verification_tag; | ||||
770 | } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) { | ||||
771 | info->verification_tag2 = sctp_info->verification_tag; | ||||
772 | } | ||||
773 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) || | ||||
774 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) || | ||||
775 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) || | ||||
776 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) || | ||||
777 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) || | ||||
778 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) || | ||||
779 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0)) | ||||
780 | { | ||||
781 | |||||
782 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
783 | copy_address(&tsn->src, &tmp_info.src); | ||||
784 | copy_address(&tsn->dst, &tmp_info.dst); | ||||
785 | |||||
786 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
787 | copy_address(&sack->src, &tmp_info.src); | ||||
788 | copy_address(&sack->dst, &tmp_info.dst); | ||||
789 | sack->secs=tsn->secs = (uint32_t)pinfo->rel_ts.secs; | ||||
790 | sack->usecs=tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000; | ||||
791 | |||||
792 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) || | ||||
793 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) || | ||||
794 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) || | ||||
795 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) || | ||||
796 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0)) | ||||
797 | { | ||||
798 | if (tsn->secs < info->min_secs) | ||||
799 | { | ||||
800 | info->min_secs = tsn->secs; | ||||
801 | info->min_usecs = tsn->usecs; | ||||
802 | } | ||||
803 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) | ||||
804 | info->min_usecs = tsn->usecs; | ||||
805 | |||||
806 | if (tsn->secs > info->max_secs) | ||||
807 | { | ||||
808 | info->max_secs = tsn->secs; | ||||
809 | info->max_usecs = tsn->usecs; | ||||
810 | } | ||||
811 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) | ||||
812 | info->max_usecs = tsn->usecs; | ||||
813 | } | ||||
814 | sack->frame_number = tsn->frame_number = pinfo->num; | ||||
815 | } | ||||
816 | number = pinfo->num; | ||||
817 | info->frame_numbers=g_list_prepend(info->frame_numbers, GUINT_TO_POINTER(number)((gpointer) (gulong) (number))); | ||||
818 | |||||
819 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address))); | ||||
820 | copy_address(store, &tmp_info.src); | ||||
821 | |||||
822 | switch (info->direction) { | ||||
823 | case 1: | ||||
824 | info = add_address(store, info, 1); | ||||
825 | break; | ||||
826 | case 2: | ||||
827 | info = add_address(store, info, 2); | ||||
828 | break; | ||||
829 | default: | ||||
830 | g_free(store); | ||||
831 | break; | ||||
832 | } | ||||
833 | |||||
834 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address))); | ||||
835 | copy_address(store, &tmp_info.dst); | ||||
836 | |||||
837 | switch (info->direction) { | ||||
838 | case 1: | ||||
839 | info = add_address(store, info, 2); | ||||
840 | break; | ||||
841 | case 2: | ||||
842 | info = add_address(store, info, 1); | ||||
843 | break; | ||||
844 | default: | ||||
845 | g_free(store); | ||||
846 | break; | ||||
847 | } | ||||
848 | |||||
849 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) || | ||||
850 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1)) | ||||
851 | { | ||||
852 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 )); | ||||
853 | if (info->direction
| ||||
854 | { | ||||
855 | if (tsnumber < info->min_tsn2) | ||||
856 | info->min_tsn2 = tsnumber; | ||||
857 | if (tsnumber > info->max_tsn2) | ||||
858 | info->max_tsn2 = tsnumber; | ||||
859 | info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 )); | ||||
860 | info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET(((((0 + 1) + 1) + 2) + 4 ) + 4 )); | ||||
861 | info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET((((0 + 1) + 1) + 2) + 4 )); | ||||
862 | info->tsn2 = g_list_prepend(info->tsn2, tsn); | ||||
863 | tsn_used = true1; | ||||
864 | } | ||||
865 | else if (info->direction
| ||||
866 | { | ||||
867 | if (tsnumber < info->min_tsn1) | ||||
868 | info->min_tsn1 = tsnumber; | ||||
869 | if (tsnumber > info->max_tsn1) | ||||
870 | info->max_tsn1 = tsnumber; | ||||
871 | info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 )); | ||||
872 | info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET(((((0 + 1) + 1) + 2) + 4 ) + 4 )); | ||||
873 | info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET((((0 + 1) + 1) + 2) + 4 )); | ||||
874 | info->tsn1 = g_list_prepend(info->tsn1, tsn); | ||||
875 | tsn_used = true1; | ||||
876 | } | ||||
877 | |||||
878 | idx = tvb_get_uint8(sctp_info->tvb[0],0); | ||||
879 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81))) | ||||
880 | idx = OTHER_CHUNKS_INDEX0xfe; | ||||
881 | info->chunk_count[idx]++; | ||||
882 | if (info->direction
| ||||
883 | info->ep1_chunk_count[idx]++; | ||||
884 | else | ||||
885 | info->ep2_chunk_count[idx]++; | ||||
886 | info = add_chunk_count(&tmp_info.src, info, info->direction, idx); | ||||
887 | for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++) | ||||
888 | { | ||||
889 | type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); | ||||
890 | if (type == IPV4ADDRESS_PARAMETER_ID0x0005) | ||||
891 | { | ||||
892 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address))); | ||||
893 | alloc_address_tvb(NULL((void*)0), store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET((0 + 2) + 2)); | ||||
894 | info = add_address(store, info, info->direction); | ||||
895 | } | ||||
896 | else if (type == IPV6ADDRESS_PARAMETER_ID0x0006) | ||||
897 | { | ||||
898 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address))); | ||||
899 | alloc_address_tvb(NULL((void*)0), store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET((0 + 2) + 2)); | ||||
900 | info = add_address(store, info, info->direction); | ||||
901 | } | ||||
902 | } | ||||
903 | if (info->direction == 1) { | ||||
| |||||
904 | if (info->dir1->init || info->dir1->initack) { | ||||
905 | info->init_collision = true1; | ||||
906 | } | ||||
907 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) { | ||||
908 | info->dir1->init = true1; | ||||
909 | 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 )); | ||||
910 | info->min_tsn1 = info->dir1->init_min_tsn; | ||||
911 | info->dir1->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
912 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) { | ||||
913 | info->dir1->initack = true1; | ||||
914 | 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 )); | ||||
915 | info->min_tsn1 = info->dir1->initack_min_tsn; | ||||
916 | info->dir1->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
917 | } | ||||
918 | } else { | ||||
919 | if (info->dir2->init || info->dir2->initack) { | ||||
920 | info->init_collision = true1; | ||||
921 | } | ||||
922 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) { | ||||
923 | info->dir2->init = true1; | ||||
924 | 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 )); | ||||
925 | info->min_tsn2 = info->dir2->init_min_tsn; | ||||
926 | info->dir2->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
927 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) { | ||||
928 | info->dir2->initack = true1; | ||||
929 | 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 )); | ||||
930 | info->min_tsn2 = info->dir2->initack_min_tsn; | ||||
931 | info->dir2->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
932 | } | ||||
933 | } | ||||
934 | if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) | ||||
935 | { | ||||
936 | info->initack = true1; | ||||
937 | info->initack_dir = info->direction; | ||||
938 | } | ||||
939 | else if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) | ||||
940 | { | ||||
941 | info->init = true1; | ||||
942 | } | ||||
943 | } | ||||
944 | else | ||||
945 | { | ||||
946 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID2) && | ||||
947 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID0) && | ||||
948 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID0x40) && | ||||
949 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID3) && | ||||
950 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID16) && | ||||
951 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID0xC0)) | ||||
952 | { | ||||
953 | if (!sack) | ||||
954 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
955 | sack->tsns = NULL((void*)0); | ||||
956 | sack->first_tsn = 0; | ||||
957 | if (!tsn) | ||||
958 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
959 | tsn->tsns = NULL((void*)0); | ||||
960 | tsn->first_tsn = 0; | ||||
961 | } | ||||
962 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) | ||||
963 | { | ||||
964 | idx = tvb_get_uint8(sctp_info->tvb[chunk_number],0); | ||||
965 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81))) | ||||
966 | idx = OTHER_CHUNKS_INDEX0xfe; | ||||
967 | |||||
968 | info->chunk_count[idx]++; | ||||
969 | if (info->direction == 1) | ||||
970 | info->ep1_chunk_count[idx]++; | ||||
971 | else | ||||
972 | info->ep2_chunk_count[idx]++; | ||||
973 | info = add_chunk_count(&tmp_info.src, info,info->direction, idx); | ||||
974 | |||||
975 | if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) || | ||||
976 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID0x40)) | ||||
977 | datachunk = true1; | ||||
978 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID0xC0) | ||||
979 | forwardchunk = true1; | ||||
980 | if ((datachunk || forwardchunk) && tsn != NULL((void*)0)) | ||||
981 | { | ||||
982 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET((((0 + 1) + 1) + 2) + 0)); | ||||
983 | if (tsn->first_tsn == 0) | ||||
984 | tsn->first_tsn = tsnumber; | ||||
985 | if (datachunk) | ||||
986 | { | ||||
987 | t_s_n = (uint8_t *)g_malloc(16); | ||||
988 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16); | ||||
989 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
990 | 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); | ||||
991 | } else { | ||||
992 | 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); | ||||
993 | } | ||||
994 | info->n_data_chunks++; | ||||
995 | info->n_data_bytes+=length; | ||||
996 | } | ||||
997 | else | ||||
998 | { | ||||
999 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)); | ||||
1000 | t_s_n = (uint8_t *)g_malloc(length); | ||||
1001 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length); | ||||
1002 | info->n_forward_chunks++; | ||||
1003 | } | ||||
1004 | tsn->tsns = g_list_append(tsn->tsns, t_s_n); | ||||
1005 | |||||
1006 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort ))); | ||||
1007 | tsn_s->tsnumber = tsnumber; | ||||
1008 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs; | ||||
1009 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000; | ||||
1010 | tsn_s->offset = 0; | ||||
1011 | tsn_s->framenumber = framenumber; | ||||
1012 | tsn_s->length = length; | ||||
1013 | |||||
1014 | if (tsn->secs < info->min_secs) | ||||
1015 | { | ||||
1016 | info->min_secs = tsn->secs; | ||||
1017 | info->min_usecs = tsn->usecs; | ||||
1018 | } | ||||
1019 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) | ||||
1020 | info->min_usecs = tsn->usecs; | ||||
1021 | |||||
1022 | if (tsn->secs > info->max_secs) | ||||
1023 | { | ||||
1024 | info->max_secs = tsn->secs; | ||||
1025 | info->max_usecs = tsn->usecs; | ||||
1026 | } | ||||
1027 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) | ||||
1028 | info->max_usecs = tsn->usecs; | ||||
1029 | |||||
1030 | if (info->direction == 1) | ||||
1031 | { | ||||
1032 | if (info->firstdata) { | ||||
1033 | info->firstdata = false0; | ||||
1034 | if (info->init_collision) { | ||||
1035 | if (tsnumber != info->min_tsn1) { | ||||
1036 | info->min_tsn1 = info->dir1->init_min_tsn; | ||||
1037 | } | ||||
1038 | info->min_tsn2 = info->dir2->initack_min_tsn; | ||||
1039 | } | ||||
1040 | } else { | ||||
1041 | if(tsnumber < info->min_tsn1) { | ||||
1042 | info->min_tsn1 = tsnumber; | ||||
1043 | } | ||||
1044 | } | ||||
1045 | if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1) | ||||
1046 | { | ||||
1047 | if (datachunk) | ||||
1048 | { | ||||
1049 | info->n_data_chunks_ep1++; | ||||
1050 | info->n_data_bytes_ep1 += length; | ||||
1051 | } | ||||
1052 | else if (forwardchunk) | ||||
1053 | { | ||||
1054 | info->n_forward_chunks_ep1++; | ||||
1055 | } | ||||
1056 | } | ||||
1057 | if(tsnumber > info->max_tsn1) | ||||
1058 | { | ||||
1059 | info->max_tsn1 = tsnumber; | ||||
1060 | if (datachunk) | ||||
1061 | { | ||||
1062 | info->n_data_chunks_ep1++; | ||||
1063 | info->n_data_bytes_ep1 += length; | ||||
1064 | } | ||||
1065 | else if (forwardchunk) | ||||
1066 | { | ||||
1067 | info->n_forward_chunks_ep1++; | ||||
1068 | } | ||||
1069 | } | ||||
1070 | if (datachunk) | ||||
1071 | { | ||||
1072 | if (info->init == false0) { | ||||
1073 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
1074 | if (info->outstream1 < tmp) info->outstream1 = tmp; | ||||
1075 | } | ||||
1076 | if (info->initack == false0) { | ||||
1077 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
1078 | if (info->instream2 < tmp) info->instream2 = tmp; | ||||
1079 | } | ||||
1080 | } | ||||
1081 | |||||
1082 | g_ptr_array_add(info->sort_tsn1, tsn_s); | ||||
1083 | info->n_array_tsn1++; | ||||
1084 | } | ||||
1085 | else if (info->direction == 2) | ||||
1086 | { | ||||
1087 | if (info->firstdata) { | ||||
1088 | info->firstdata = false0; | ||||
1089 | if (info->init_collision) { | ||||
1090 | if (tsnumber != info->min_tsn2) { | ||||
1091 | info->min_tsn2 = info->dir2->init_min_tsn; | ||||
1092 | info->initack_dir = 2; | ||||
1093 | } | ||||
1094 | info->min_tsn1 = info->dir1->initack_min_tsn; | ||||
1095 | } | ||||
1096 | } else { | ||||
1097 | if(tsnumber < info->min_tsn2) | ||||
1098 | info->min_tsn2 = tsnumber; | ||||
1099 | } | ||||
1100 | |||||
1101 | if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2) | ||||
1102 | { | ||||
1103 | if (datachunk) | ||||
1104 | { | ||||
1105 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
1106 | 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); | ||||
1107 | } else { | ||||
1108 | 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); | ||||
1109 | } | ||||
1110 | info->n_data_chunks_ep2++; | ||||
1111 | info->n_data_bytes_ep2+=length; | ||||
1112 | } | ||||
1113 | else if (forwardchunk) | ||||
1114 | { | ||||
1115 | info->n_forward_chunks_ep2++; | ||||
1116 | } | ||||
1117 | } | ||||
1118 | if (tsnumber > info->max_tsn2) | ||||
1119 | { | ||||
1120 | info->max_tsn2 = tsnumber; | ||||
1121 | if (datachunk) | ||||
1122 | { | ||||
1123 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
1124 | 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); | ||||
1125 | } else { | ||||
1126 | 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); | ||||
1127 | } | ||||
1128 | info->n_data_chunks_ep2++; | ||||
1129 | info->n_data_bytes_ep2+=length; | ||||
1130 | } | ||||
1131 | else if (forwardchunk) | ||||
1132 | { | ||||
1133 | info->n_forward_chunks_ep2++; | ||||
1134 | } | ||||
1135 | } | ||||
1136 | if (datachunk) | ||||
1137 | { | ||||
1138 | if (info->init == false0) { | ||||
1139 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
1140 | if (info->instream1 < tmp) info->instream1 = tmp; | ||||
1141 | } | ||||
1142 | if (info->initack == false0) { | ||||
1143 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
1144 | if (info->outstream2 < tmp) info->outstream2 = tmp; | ||||
1145 | } | ||||
1146 | } | ||||
1147 | |||||
1148 | g_ptr_array_add(info->sort_tsn2, tsn_s); | ||||
1149 | info->n_array_tsn2++; | ||||
1150 | } | ||||
1151 | } | ||||
1152 | else if (((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID3) || | ||||
1153 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID16)) && | ||||
1154 | sack != NULL((void*)0)) | ||||
1155 | { | ||||
1156 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET((((0 + 1) + 1) + 2) + 0)); | ||||
1157 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)); | ||||
1158 | |||||
1159 | if (sack->first_tsn == 0) | ||||
1160 | sack->first_tsn = tsnumber; | ||||
1161 | |||||
1162 | t_s_n = (uint8_t *)g_malloc(length); | ||||
1163 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length); | ||||
1164 | sack->tsns = g_list_append(sack->tsns, t_s_n); | ||||
1165 | sackchunk = true1; | ||||
1166 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort ))); | ||||
1167 | tsn_s->tsnumber = tsnumber; | ||||
1168 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs; | ||||
1169 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000; | ||||
1170 | tsn_s->offset = 0; | ||||
1171 | tsn_s->framenumber = framenumber; | ||||
1172 | tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4)); | ||||
1173 | |||||
1174 | if (tsn->secs < info->min_secs) | ||||
1175 | { | ||||
1176 | info->min_secs = tsn->secs; | ||||
1177 | info->min_usecs = tsn->usecs; | ||||
1178 | } | ||||
1179 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) | ||||
1180 | info->min_usecs = tsn->usecs; | ||||
1181 | |||||
1182 | if (tsn->secs > info->max_secs) | ||||
1183 | { | ||||
1184 | info->max_secs = tsn->secs; | ||||
1185 | info->max_usecs = tsn->usecs; | ||||
1186 | } | ||||
1187 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) | ||||
1188 | info->max_usecs = tsn->usecs; | ||||
1189 | |||||
1190 | |||||
1191 | if (info->direction == 2) | ||||
1192 | { | ||||
1193 | if(tsnumber < info->min_tsn1) | ||||
1194 | info->min_tsn1 = tsnumber; | ||||
1195 | if(tsnumber > info->max_tsn1) | ||||
1196 | info->max_tsn1 = tsnumber; | ||||
1197 | if (tsn_s->length > info->max_window1) | ||||
1198 | info->max_window1 = tsn_s->length; | ||||
1199 | g_ptr_array_add(info->sort_sack1, tsn_s); | ||||
1200 | info->n_sack_chunks_ep1++; | ||||
1201 | } | ||||
1202 | else if (info->direction == 1) | ||||
1203 | { | ||||
1204 | if(tsnumber < info->min_tsn2) | ||||
1205 | info->min_tsn2 = tsnumber; | ||||
1206 | if(tsnumber > info->max_tsn2) | ||||
1207 | info->max_tsn2 = tsnumber; | ||||
1208 | if (tsn_s->length > info->max_window2) | ||||
1209 | info->max_window2 = tsn_s->length; | ||||
1210 | g_ptr_array_add(info->sort_sack2, tsn_s); | ||||
1211 | info->n_sack_chunks_ep2++; | ||||
1212 | } | ||||
1213 | } | ||||
1214 | } | ||||
1215 | } | ||||
1216 | |||||
1217 | if (datachunk || forwardchunk) | ||||
1218 | { | ||||
1219 | if (info->direction == 1) | ||||
1220 | info->tsn1 = g_list_prepend(info->tsn1, tsn); | ||||
1221 | else if (info->direction == 2) | ||||
1222 | info->tsn2 = g_list_prepend(info->tsn2, tsn); | ||||
1223 | tsn_used = true1; | ||||
1224 | } | ||||
1225 | if (sackchunk == true1) | ||||
1226 | { | ||||
1227 | if (info->direction == 1) | ||||
1228 | info->sack2 = g_list_prepend(info->sack2, sack); | ||||
1229 | else if(info->direction == 2) | ||||
1230 | info->sack1 = g_list_prepend(info->sack1, sack); | ||||
1231 | sack_used = true1; | ||||
1232 | } | ||||
1233 | info->n_tvbs += sctp_info->number_of_tvbs; | ||||
1234 | sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs; | ||||
1235 | info = calc_checksum(sctp_info, info); | ||||
1236 | info->n_packets++; | ||||
1237 | } | ||||
1238 | if (tsn && !tsn_used) | ||||
1239 | tsn_free(tsn); | ||||
1240 | if (sack && !sack_used) | ||||
1241 | tsn_free(sack); | ||||
1242 | free_address(&tmp_info.src); | ||||
1243 | free_address(&tmp_info.dst); | ||||
1244 | return TAP_PACKET_REDRAW; | ||||
1245 | } | ||||
1246 | |||||
1247 | |||||
1248 | /****************************************************************************/ | ||||
1249 | void | ||||
1250 | remove_tap_listener_sctp_stat(void) | ||||
1251 | { | ||||
1252 | if (sctp_tapinfo_struct.is_registered) { | ||||
1253 | remove_tap_listener(&sctp_tapinfo_struct); | ||||
1254 | sctp_tapinfo_struct.is_registered = false0; | ||||
1255 | } | ||||
1256 | } | ||||
1257 | |||||
1258 | |||||
1259 | void | ||||
1260 | sctp_stat_scan(void) | ||||
1261 | { | ||||
1262 | if (!sctp_tapinfo_struct.is_registered) { | ||||
1263 | register_tap_listener_sctp_stat(); | ||||
1264 | } | ||||
1265 | } | ||||
1266 | |||||
1267 | const sctp_allassocs_info_t * | ||||
1268 | sctp_stat_get_info(void) | ||||
1269 | { | ||||
1270 | return &sctp_tapinfo_struct; | ||||
1271 | } | ||||
1272 | |||||
1273 | const sctp_assoc_info_t * | ||||
1274 | get_sctp_assoc_info(uint16_t assoc_id) | ||||
1275 | { | ||||
1276 | sctp_tmp_info_t needle = { .assoc_id = assoc_id }; | ||||
1277 | return find_assoc(&needle); | ||||
1278 | } | ||||
1279 | |||||
1280 | void | ||||
1281 | register_tap_listener_sctp_stat(void) | ||||
1282 | { | ||||
1283 | GString *error_string; | ||||
1284 | |||||
1285 | if (!sctp_tapinfo_struct.is_registered) | ||||
1286 | { | ||||
1287 | if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL((void*)0), 0, reset, packet, NULL((void*)0), NULL((void*)0)))) { | ||||
1288 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", error_string->str); | ||||
1289 | 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))))); | ||||
1290 | return; | ||||
1291 | } | ||||
1292 | sctp_tapinfo_struct.is_registered=true1; | ||||
1293 | } | ||||
1294 | } |
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 | ||||
23 | extern "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 | */ | ||||
37 | typedef 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 | |||||
53 | AT_END_OF_LIST /* Must be last in list */ | ||||
54 | } address_type; | ||||
55 | |||||
56 | typedef struct _address { | ||||
57 | int type; /* type of address */ | ||||
58 | int len; /* length of address, in bytes */ | ||||
59 | const void *data; /* pointer to address data */ | ||||
60 | |||||
61 | /* private */ | ||||
62 | void *priv; | ||||
63 | } address; | ||||
64 | |||||
65 | #define ADDRESS_INIT(type, len, data){type, len, data, ((void*)0)} {type, len, data, NULL((void*)0)} | ||||
66 | #define ADDRESS_INIT_NONE{AT_NONE, 0, ((void*)0), ((void*)0)} ADDRESS_INIT(AT_NONE, 0, NULL){AT_NONE, 0, ((void*)0), ((void*)0)} | ||||
67 | |||||
68 | static inline void | ||||
69 | clear_address(address *addr) | ||||
70 | { | ||||
71 | addr->type = AT_NONE; | ||||
72 | addr->len = 0; | ||||
73 | addr->data = NULL((void*)0); | ||||
74 | addr->priv = NULL((void*)0); | ||||
75 | } | ||||
76 | |||||
77 | /** Initialize an address with the given values. | ||||
78 | * | ||||
79 | * @param addr [in,out] The address to initialize. | ||||
80 | * @param addr_type [in] Address type. | ||||
81 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for | ||||
82 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6. | ||||
83 | * @param addr_data [in] Pointer to the address data. | ||||
84 | */ | ||||
85 | static inline void | ||||
86 | set_address(address *addr, int addr_type, int addr_len, const void *addr_data) { | ||||
87 | if (addr_len == 0) { | ||||
88 | /* Zero length must mean no data */ | ||||
89 | ws_assert(addr_data == NULL)do { if ((1) && !(addr_data == ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 89, __func__, "assertion failed: %s" , "addr_data == ((void*)0)"); } while (0); | ||||
90 | } else { | ||||
91 | /* Must not be AT_NONE - AT_NONE must have no data */ | ||||
92 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 92, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0); | ||||
93 | /* Make sure we *do* have data */ | ||||
94 | ws_assert(addr_data != NULL)do { if ((1) && !(addr_data != ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 94, __func__, "assertion failed: %s" , "addr_data != ((void*)0)"); } while (0); | ||||
95 | } | ||||
96 | addr->type = addr_type; | ||||
97 | addr->len = addr_len; | ||||
98 | addr->data = addr_data; | ||||
99 | addr->priv = NULL((void*)0); | ||||
100 | } | ||||
101 | |||||
102 | static inline void | ||||
103 | set_address_ipv4(address *addr, const ipv4_addr_and_mask *ipv4) { | ||||
104 | addr->type = AT_IPv4; | ||||
105 | addr->len = 4; | ||||
106 | 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)))))); | ||||
107 | addr->priv = g_memdup2(&val, sizeof(val)); | ||||
108 | addr->data = addr->priv; | ||||
109 | } | ||||
110 | |||||
111 | static inline void | ||||
112 | set_address_ipv6(address *addr, const ipv6_addr_and_prefix *ipv6) { | ||||
113 | set_address(addr, AT_IPv6, sizeof(ws_in6_addr), &ipv6->addr); | ||||
114 | } | ||||
115 | |||||
116 | /** Initialize an address from TVB data. | ||||
117 | * | ||||
118 | * Same as set_address but it takes a TVB and an offset. This is preferred | ||||
119 | * over passing the return value of tvb_get_ptr() to set_address(). | ||||
120 | * | ||||
121 | * This calls tvb_get_ptr() (including throwing any exceptions) before | ||||
122 | * modifying the address. | ||||
123 | * | ||||
124 | * @param addr [in,out] The address to initialize. | ||||
125 | * @param addr_type [in] Address type. | ||||
126 | * @param tvb [in] Pointer to the TVB. | ||||
127 | * @param offset [in] Offset within the TVB. | ||||
128 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for | ||||
129 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6. | ||||
130 | */ | ||||
131 | static inline void | ||||
132 | set_address_tvb(address *addr, int addr_type, int addr_len, tvbuff_t *tvb, int offset) { | ||||
133 | const void *p; | ||||
134 | |||||
135 | if (addr_len != 0) { | ||||
136 | /* Must not be AT_NONE - AT_NONE must have no data */ | ||||
137 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 137, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0); | ||||
138 | p = tvb_get_ptr(tvb, offset, addr_len); | ||||
139 | } else | ||||
140 | p = NULL((void*)0); | ||||
141 | set_address(addr, addr_type, addr_len, p); | ||||
142 | } | ||||
143 | |||||
144 | /** Initialize an address with the given values, allocating a new buffer | ||||
145 | * for the address data using wmem-scoped memory. | ||||
146 | * | ||||
147 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool | ||||
148 | * @param addr [in,out] The address to initialize. | ||||
149 | * @param addr_type [in] Address type. | ||||
150 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for | ||||
151 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6. | ||||
152 | * @param addr_data [in] Pointer to the address data. | ||||
153 | */ | ||||
154 | static inline void | ||||
155 | alloc_address_wmem(wmem_allocator_t *scope, address *addr, | ||||
156 | int addr_type, int addr_len, const void *addr_data) { | ||||
157 | ws_assert(addr)do { if ((1) && !(addr)) ws_log_fatal_full("", LOG_LEVEL_ERROR , "epan/address.h", 157, __func__, "assertion failed: %s", "addr" ); } while (0); | ||||
158 | clear_address(addr); | ||||
159 | addr->type = addr_type; | ||||
160 | if (addr_len
| ||||
161 | /* Zero length must mean no data */ | ||||
162 | ws_assert(addr_data == NULL)do { if ((1) && !(addr_data == ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 162, __func__, "assertion failed: %s" , "addr_data == ((void*)0)"); } while (0); | ||||
163 | /* Nothing to copy */ | ||||
164 | return; | ||||
165 | } | ||||
166 | /* Must not be AT_NONE - AT_NONE must have no data */ | ||||
167 | ws_assert(addr_type != AT_NONE)do { if ((1) && !(addr_type != AT_NONE)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 167, __func__, "assertion failed: %s" , "addr_type != AT_NONE"); } while (0); | ||||
168 | /* Make sure we *do* have data to copy */ | ||||
169 | ws_assert(addr_data != NULL)do { if ((1) && !(addr_data != ((void*)0))) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 169, __func__, "assertion failed: %s" , "addr_data != ((void*)0)"); } while (0); | ||||
170 | addr->data = addr->priv = wmem_memdup(scope, addr_data, addr_len); | ||||
171 | addr->len = addr_len; | ||||
172 | } | ||||
173 | |||||
174 | /** Allocate an address from TVB data. | ||||
175 | * | ||||
176 | * Same as alloc_address_wmem but it takes a TVB and an offset. | ||||
177 | * | ||||
178 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool | ||||
179 | * @param addr [in,out] The address to initialize. | ||||
180 | * @param addr_type [in] Address type. | ||||
181 | * @param addr_len [in] The length in bytes of the address data. For example, 4 for | ||||
182 | * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6. | ||||
183 | * @param tvb [in] Pointer to the TVB. | ||||
184 | * @param offset [in] Offset within the TVB. | ||||
185 | */ | ||||
186 | static inline void | ||||
187 | alloc_address_tvb(wmem_allocator_t *scope, address *addr, | ||||
188 | int addr_type, int addr_len, tvbuff_t *tvb, int offset) { | ||||
189 | const void *p; | ||||
190 | |||||
191 | p = tvb_get_ptr(tvb, offset, addr_len); | ||||
192 | alloc_address_wmem(scope, addr, addr_type, addr_len, p); | ||||
193 | } | ||||
194 | |||||
195 | /** Compare two addresses. | ||||
196 | * | ||||
197 | * @param addr1 [in] The first address to compare. | ||||
198 | * @param addr2 [in] The second address to compare. | ||||
199 | * @return 0 if the addresses are equal, | ||||
200 | * A positive number if addr1 > addr2 in some nondefined metric, | ||||
201 | * A negative number if addr1 < addr2 in some nondefined metric. | ||||
202 | */ | ||||
203 | static inline int | ||||
204 | cmp_address(const address *addr1, const address *addr2) { | ||||
205 | if (addr1->type > addr2->type) return 1; | ||||
206 | if (addr1->type < addr2->type) return -1; | ||||
207 | if (addr1->len > addr2->len) return 1; | ||||
208 | if (addr1->len < addr2->len) return -1; | ||||
209 | if (addr1->len == 0) { | ||||
210 | /* | ||||
211 | * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so | ||||
212 | * if both addresses are zero-length, don't compare them | ||||
213 | * (there's nothing to compare, so they're equal). | ||||
214 | */ | ||||
215 | return 0; | ||||
216 | } | ||||
217 | return memcmp(addr1->data, addr2->data, addr1->len); | ||||
218 | } | ||||
219 | |||||
220 | /** Check two addresses for equality. | ||||
221 | * | ||||
222 | * Given two addresses, return "true" if they're equal, "false" otherwise. | ||||
223 | * Addresses are equal only if they have the same type and length; if the | ||||
224 | * length is zero, they are then equal, otherwise the data must be the | ||||
225 | * same. | ||||
226 | * | ||||
227 | * @param addr1 [in] The first address to compare. | ||||
228 | * @param addr2 [in] The second address to compare. | ||||
229 | * @return true if the addresses are equal, false otherwise. | ||||
230 | */ | ||||
231 | static inline bool_Bool | ||||
232 | addresses_equal(const address *addr1, const address *addr2) { | ||||
233 | /* | ||||
234 | * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so | ||||
235 | * if both addresses are zero-length, don't compare them | ||||
236 | * (there's nothing to compare, so they're equal). | ||||
237 | */ | ||||
238 | if (addr1->type == addr2->type && | ||||
239 | addr1->len == addr2->len && | ||||
240 | (addr1->len == 0 || | ||||
241 | memcmp(addr1->data, addr2->data, addr1->len) == 0)) | ||||
242 | return true1; | ||||
243 | return false0; | ||||
244 | } | ||||
245 | |||||
246 | /** Check the data of two addresses for equality. | ||||
247 | * | ||||
248 | * Given two addresses, return "true" if they have the same length and, | ||||
249 | * their data is equal, "false" otherwise. | ||||
250 | * The address types are ignored. This can be used to compare custom | ||||
251 | * address types defined with address_type_dissector_register. | ||||
252 | * | ||||
253 | * @param addr1 [in] The first address to compare. | ||||
254 | * @param addr2 [in] The second address to compare. | ||||
255 | * @return true if the addresses are equal, false otherwise. | ||||
256 | */ | ||||
257 | static inline bool_Bool | ||||
258 | addresses_data_equal(const address *addr1, const address *addr2) { | ||||
259 | if ( addr1->len == addr2->len | ||||
260 | && memcmp(addr1->data, addr2->data, addr1->len) == 0 | ||||
261 | ) return true1; | ||||
262 | return false0; | ||||
263 | } | ||||
264 | |||||
265 | /** Perform a shallow copy of the address (both addresses point to the same | ||||
266 | * memory location). | ||||
267 | * | ||||
268 | * @param to [in,out] The destination address. | ||||
269 | * @param from [in] The source address. | ||||
270 | * | ||||
271 | * \warning Make sure 'from' memory stays valid for the lifetime of this object. | ||||
272 | * Also it's strongly recommended to use this function instead of copy-assign. | ||||
273 | */ | ||||
274 | static inline void | ||||
275 | copy_address_shallow(address *to, const address *from) { | ||||
276 | set_address(to, from->type, from->len, from->data); | ||||
277 | } | ||||
278 | |||||
279 | /** Copy an address, allocating a new buffer for the address data | ||||
280 | * using wmem-scoped memory. | ||||
281 | * | ||||
282 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool | ||||
283 | * @param to [in,out] The destination address. | ||||
284 | * @param from [in] The source address. | ||||
285 | */ | ||||
286 | static inline void | ||||
287 | copy_address_wmem(wmem_allocator_t *scope, address *to, const address *from) { | ||||
288 | alloc_address_wmem(scope, to, from->type, from->len, from->data); | ||||
289 | } | ||||
290 | |||||
291 | /** Copy an address, allocating a new buffer for the address data. | ||||
292 | * | ||||
293 | * @param to [in,out] The destination address. | ||||
294 | * @param from [in] The source address. | ||||
295 | */ | ||||
296 | static inline void | ||||
297 | copy_address(address *to, const address *from) { | ||||
298 | copy_address_wmem(NULL((void*)0), to, from); | ||||
299 | } | ||||
300 | |||||
301 | /** Free an address allocated with wmem-scoped memory. | ||||
302 | * | ||||
303 | * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool | ||||
304 | * @param addr [in,out] The address whose data to free. | ||||
305 | */ | ||||
306 | static inline void | ||||
307 | free_address_wmem(wmem_allocator_t *scope, address *addr) { | ||||
308 | /* Because many dissectors set 'type = AT_NONE' to mean clear we check for that */ | ||||
309 | if (addr->type != AT_NONE && addr->len > 0 && addr->priv != NULL((void*)0)) { | ||||
310 | /* Make sure API use is correct */ | ||||
311 | /* if priv is not null then data == priv */ | ||||
312 | ws_assert(addr->data == addr->priv)do { if ((1) && !(addr->data == addr->priv)) ws_log_fatal_full ("", LOG_LEVEL_ERROR, "epan/address.h", 312, __func__, "assertion failed: %s" , "addr->data == addr->priv"); } while (0); | ||||
313 | wmem_free(scope, addr->priv); | ||||
314 | } | ||||
315 | clear_address(addr); | ||||
316 | } | ||||
317 | |||||
318 | /** Free an address. | ||||
319 | * | ||||
320 | * @param addr [in,out] The address whose data to free. | ||||
321 | */ | ||||
322 | static inline void | ||||
323 | free_address(address *addr) { | ||||
324 | free_address_wmem(NULL((void*)0), addr); | ||||
325 | } | ||||
326 | |||||
327 | /** Hash an address into a hash value (which must already have been set). | ||||
328 | * | ||||
329 | * @param hash_val The existing hash value. | ||||
330 | * @param addr The address to add. | ||||
331 | * @return The new hash value. | ||||
332 | */ | ||||
333 | static inline unsigned | ||||
334 | add_address_to_hash(unsigned hash_val, const address *addr) { | ||||
335 | const uint8_t *hash_data = (const uint8_t *)(addr)->data; | ||||
336 | int idx; | ||||
337 | |||||
338 | for (idx = 0; idx < (addr)->len; idx++) { | ||||
339 | hash_val += hash_data[idx]; | ||||
340 | hash_val += ( hash_val << 10 ); | ||||
341 | hash_val ^= ( hash_val >> 6 ); | ||||
342 | } | ||||
343 | return hash_val; | ||||
344 | } | ||||
345 | |||||
346 | /** Hash an address into a hash value (which must already have been set). | ||||
347 | * 64-bit version of add_address_to_hash(). | ||||
348 | * | ||||
349 | * @param hash_val The existing hash value. | ||||
350 | * @param addr The address to add. | ||||
351 | * @return The new hash value. | ||||
352 | */ | ||||
353 | static inline uint64_t | ||||
354 | add_address_to_hash64(uint64_t hash_val, const address *addr) { | ||||
355 | const uint8_t *hash_data = (const uint8_t *)(addr)->data; | ||||
356 | int idx; | ||||
357 | |||||
358 | for (idx = 0; idx < (addr)->len; idx++) { | ||||
359 | hash_val += hash_data[idx]; | ||||
360 | hash_val += ( hash_val << 10 ); | ||||
361 | hash_val ^= ( hash_val >> 6 ); | ||||
362 | } | ||||
363 | return hash_val; | ||||
364 | } | ||||
365 | |||||
366 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern unsigned address_to_bytes(const address *addr, uint8_t *buf, unsigned buf_len); | ||||
367 | |||||
368 | /* Types of port numbers Wireshark knows about. */ | ||||
369 | typedef enum { | ||||
370 | PT_NONE, /* no port number */ | ||||
371 | PT_SCTP, /* SCTP */ | ||||
372 | PT_TCP, /* TCP */ | ||||
373 | PT_UDP, /* UDP */ | ||||
374 | PT_DCCP, /* DCCP */ | ||||
375 | PT_IPX, /* IPX sockets */ | ||||
376 | PT_DDP, /* DDP AppleTalk connection */ | ||||
377 | PT_IDP, /* XNS IDP sockets */ | ||||
378 | PT_USB, /* USB endpoint 0xffff means the host */ | ||||
379 | PT_I2C, | ||||
380 | PT_IBQP, /* Infiniband QP number */ | ||||
381 | PT_BLUETOOTH, | ||||
382 | PT_IWARP_MPA, /* iWarp MPA */ | ||||
383 | PT_MCTP | ||||
384 | } port_type; | ||||
385 | |||||
386 | #ifdef __cplusplus | ||||
387 | } | ||||
388 | #endif /* __cplusplus */ | ||||
389 | |||||
390 | #endif /* __ADDRESS_H__ */ | ||||
391 | |||||
392 | /* | ||||
393 | * Editor modelines - https://www.wireshark.org/tools/modelines.html | ||||
394 | * | ||||
395 | * Local variables: | ||||
396 | * c-basic-offset: 4 | ||||
397 | * tab-width: 8 | ||||
398 | * indent-tabs-mode: nil | ||||
399 | * End: | ||||
400 | * | ||||
401 | * vi: set shiftwidth=4 tabstop=8 expandtab: | ||||
402 | * :indentSize=4:tabSize=8:noTabs=true: | ||||
403 | */ |