| File: | ui/tap-sctp-analysis.c |
| Warning: | line 904, 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 <wsutil/value_string.h> | ||||
| 21 | |||||
| 22 | #include "ui/tap-sctp-analysis.h" | ||||
| 23 | |||||
| 24 | #include "ui/simple_dialog.h" | ||||
| 25 | |||||
| 26 | #define FORWARD_STREAM0 0 | ||||
| 27 | #define BACKWARD_STREAM1 1 | ||||
| 28 | #define FORWARD_ADD_FORWARD_VTAG2 2 | ||||
| 29 | #define BACKWARD_ADD_FORWARD_VTAG3 3 | ||||
| 30 | #define BACKWARD_ADD_BACKWARD_VTAG4 4 | ||||
| 31 | #define ADDRESS_FORWARD_STREAM5 5 | ||||
| 32 | #define ADDRESS_BACKWARD_STREAM6 6 | ||||
| 33 | #define ADDRESS_FORWARD_ADD_FORWARD_VTAG7 7 | ||||
| 34 | #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG8 8 | ||||
| 35 | #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG9 9 | ||||
| 36 | #define ASSOC_NOT_FOUND10 10 | ||||
| 37 | |||||
| 38 | static sctp_allassocs_info_t sctp_tapinfo_struct; | ||||
| 39 | |||||
| 40 | static void | ||||
| 41 | free_first(void *data, void *user_data _U___attribute__((unused))) | ||||
| 42 | { | ||||
| 43 | g_free(data); | ||||
| 44 | } | ||||
| 45 | |||||
| 46 | static void | ||||
| 47 | tsn_free(void *data) | ||||
| 48 | { | ||||
| 49 | tsn_t *tsn; | ||||
| 50 | |||||
| 51 | tsn = (tsn_t *) data; | ||||
| 52 | if (tsn->tsns != NULL((void*)0)) | ||||
| 53 | { | ||||
| 54 | g_list_free_full(tsn->tsns, g_free); | ||||
| 55 | } | ||||
| 56 | free_address(&tsn->src); | ||||
| 57 | free_address(&tsn->dst); | ||||
| 58 | g_free(tsn); | ||||
| 59 | } | ||||
| 60 | |||||
| 61 | static void | ||||
| 62 | chunk_free(void *data) | ||||
| 63 | { | ||||
| 64 | sctp_addr_chunk *chunk = (sctp_addr_chunk *) data; | ||||
| 65 | |||||
| 66 | free_address(&chunk->addr); | ||||
| 67 | g_free(chunk); | ||||
| 68 | } | ||||
| 69 | |||||
| 70 | static void | ||||
| 71 | store_free(void *data) | ||||
| 72 | { | ||||
| 73 | address *addr = (address *) data; | ||||
| 74 | |||||
| 75 | free_address(addr); | ||||
| 76 | g_free(addr); | ||||
| 77 | } | ||||
| 78 | |||||
| 79 | static void | ||||
| 80 | reset(void *arg) | ||||
| 81 | { | ||||
| 82 | sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg; | ||||
| 83 | GList* list; | ||||
| 84 | sctp_assoc_info_t * info; | ||||
| 85 | |||||
| 86 | list = g_list_first(tapdata->assoc_info_list); | ||||
| 87 | while (list) | ||||
| 88 | { | ||||
| 89 | info = (sctp_assoc_info_t *) (list->data); | ||||
| 90 | |||||
| 91 | if (info->addr1 != NULL((void*)0)) | ||||
| 92 | { | ||||
| 93 | g_list_free_full(info->addr1, store_free); | ||||
| 94 | info->addr1 = NULL((void*)0); | ||||
| 95 | } | ||||
| 96 | |||||
| 97 | if (info->addr2 != NULL((void*)0)) | ||||
| 98 | { | ||||
| 99 | g_list_free_full(info->addr2, store_free); | ||||
| 100 | info->addr2 = NULL((void*)0); | ||||
| 101 | } | ||||
| 102 | |||||
| 103 | if (info->error_info_list != NULL((void*)0)) | ||||
| 104 | { | ||||
| 105 | g_list_free_full(info->error_info_list, g_free); | ||||
| 106 | info->error_info_list = NULL((void*)0); | ||||
| 107 | } | ||||
| 108 | |||||
| 109 | if (info->frame_numbers != NULL((void*)0)) | ||||
| 110 | { | ||||
| 111 | g_list_free(info->frame_numbers); | ||||
| 112 | info->frame_numbers = NULL((void*)0); | ||||
| 113 | } | ||||
| 114 | |||||
| 115 | if (info->tsn1 != NULL((void*)0)) | ||||
| 116 | { | ||||
| 117 | g_list_free_full(info->tsn1, tsn_free); | ||||
| 118 | info->tsn1 = NULL((void*)0); | ||||
| 119 | } | ||||
| 120 | |||||
| 121 | if (info->tsn2 != NULL((void*)0)) | ||||
| 122 | { | ||||
| 123 | g_list_free_full(info->tsn2, tsn_free); | ||||
| 124 | info->tsn2 = NULL((void*)0); | ||||
| 125 | } | ||||
| 126 | |||||
| 127 | if (info->sack1 != NULL((void*)0)) | ||||
| 128 | { | ||||
| 129 | g_list_free_full(info->sack1, tsn_free); | ||||
| 130 | info->sack1 = NULL((void*)0); | ||||
| 131 | } | ||||
| 132 | |||||
| 133 | if (info->sack2 != NULL((void*)0)) | ||||
| 134 | { | ||||
| 135 | g_list_free_full(info->sack2, tsn_free); | ||||
| 136 | info->sack2 = NULL((void*)0); | ||||
| 137 | } | ||||
| 138 | |||||
| 139 | if (info->sort_tsn1 != NULL((void*)0)) | ||||
| 140 | g_ptr_array_free(info->sort_tsn1, true1); | ||||
| 141 | |||||
| 142 | if (info->sort_tsn2 != NULL((void*)0)) | ||||
| 143 | g_ptr_array_free(info->sort_tsn2, true1); | ||||
| 144 | |||||
| 145 | if (info->sort_sack1 != NULL((void*)0)) | ||||
| 146 | g_ptr_array_free(info->sort_sack1, true1); | ||||
| 147 | |||||
| 148 | if (info->sort_sack2 != NULL((void*)0)) | ||||
| 149 | g_ptr_array_free(info->sort_sack2, true1); | ||||
| 150 | |||||
| 151 | if (info->min_max != NULL((void*)0)) | ||||
| 152 | { | ||||
| 153 | g_slist_foreach(info->min_max, free_first, NULL((void*)0)); | ||||
| 154 | info->min_max = NULL((void*)0); | ||||
| 155 | } | ||||
| 156 | |||||
| 157 | if (info->addr_chunk_count) { | ||||
| 158 | g_list_free_full(info->addr_chunk_count, chunk_free); | ||||
| 159 | } | ||||
| 160 | |||||
| 161 | g_free(info->dir1); | ||||
| 162 | g_free(info->dir2); | ||||
| 163 | free_address(&info->src); | ||||
| 164 | free_address(&info->dst); | ||||
| 165 | |||||
| 166 | g_free(list->data); | ||||
| 167 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
| 168 | } | ||||
| 169 | g_list_free(tapdata->assoc_info_list); | ||||
| 170 | tapdata->sum_tvbs = 0; | ||||
| 171 | tapdata->assoc_info_list = NULL((void*)0); | ||||
| 172 | } | ||||
| 173 | |||||
| 174 | |||||
| 175 | static sctp_assoc_info_t * | ||||
| 176 | calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data) | ||||
| 177 | { | ||||
| 178 | bool_Bool ok = false0; | ||||
| 179 | |||||
| 180 | if (check_data->adler32_calculated) | ||||
| 181 | { | ||||
| 182 | data->n_adler32_calculated++; | ||||
| 183 | if (check_data->adler32_correct) | ||||
| 184 | data->n_adler32_correct++; | ||||
| 185 | } | ||||
| 186 | if (check_data->crc32c_calculated) | ||||
| 187 | { | ||||
| 188 | data->n_crc32c_calculated++; | ||||
| 189 | if (check_data->crc32c_correct) | ||||
| 190 | data->n_crc32c_correct++; | ||||
| 191 | } | ||||
| 192 | if (data->n_adler32_calculated > 0) | ||||
| 193 | { | ||||
| 194 | if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5) | ||||
| 195 | { | ||||
| 196 | char str[] = "ADLER32"; | ||||
| 197 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
| 198 | data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct); | ||||
| 199 | ok = true1; | ||||
| 200 | } | ||||
| 201 | } | ||||
| 202 | |||||
| 203 | if (data->n_crc32c_calculated>0) | ||||
| 204 | { | ||||
| 205 | if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5) | ||||
| 206 | { | ||||
| 207 | char str[] = "CRC32C"; | ||||
| 208 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
| 209 | data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct; | ||||
| 210 | ok = true1; | ||||
| 211 | } | ||||
| 212 | } | ||||
| 213 | |||||
| 214 | if (!ok) | ||||
| 215 | { | ||||
| 216 | char str[] = "UNKNOWN"; | ||||
| 217 | (void) g_strlcpy(data->checksum_type, str, 8); | ||||
| 218 | data->n_checksum_errors=0; | ||||
| 219 | } | ||||
| 220 | |||||
| 221 | return(data); | ||||
| 222 | |||||
| 223 | } | ||||
| 224 | |||||
| 225 | |||||
| 226 | static sctp_assoc_info_t * | ||||
| 227 | find_assoc(sctp_tmp_info_t *needle) | ||||
| 228 | { | ||||
| 229 | sctp_allassocs_info_t *assoc_info; | ||||
| 230 | sctp_assoc_info_t *info = NULL((void*)0); | ||||
| 231 | GList* list; | ||||
| 232 | |||||
| 233 | assoc_info = &sctp_tapinfo_struct; | ||||
| 234 | if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL((void*)0)) | ||||
| 235 | { | ||||
| 236 | while (list) | ||||
| 237 | { | ||||
| 238 | info = (sctp_assoc_info_t*)(list->data); | ||||
| 239 | if (needle->assoc_id == info->assoc_id) | ||||
| 240 | return info; | ||||
| 241 | |||||
| 242 | list = g_list_previous(list)((list) ? (((GList *)(list))->prev) : ((void*)0)); | ||||
| 243 | } | ||||
| 244 | } | ||||
| 245 | return NULL((void*)0); | ||||
| 246 | } | ||||
| 247 | |||||
| 248 | static sctp_assoc_info_t * | ||||
| 249 | add_chunk_count(address *vadd, sctp_assoc_info_t *info, uint32_t direction, uint32_t type) | ||||
| 250 | { | ||||
| 251 | GList *list; | ||||
| 252 | sctp_addr_chunk *ch=NULL((void*)0); | ||||
| 253 | int i; | ||||
| 254 | |||||
| 255 | list = g_list_first(info->addr_chunk_count); | ||||
| 256 | |||||
| 257 | while (list) | ||||
| 258 | { | ||||
| 259 | ch = (sctp_addr_chunk *)(list->data); | ||||
| 260 | if (ch->direction == direction) | ||||
| 261 | { | ||||
| 262 | if (addresses_equal(vadd, &ch->addr)) | ||||
| 263 | { | ||||
| 264 | if (IS_SCTP_CHUNK_TYPE(type)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81))) | ||||
| 265 | ch->addr_count[type]++; | ||||
| 266 | else | ||||
| 267 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++; | ||||
| 268 | return info; | ||||
| 269 | } | ||||
| 270 | else | ||||
| 271 | { | ||||
| 272 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
| 273 | } | ||||
| 274 | } | ||||
| 275 | else | ||||
| 276 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : ((void*)0)); | ||||
| 277 | } | ||||
| 278 | ch = g_new(sctp_addr_chunk, 1)((sctp_addr_chunk *) g_malloc_n ((1), sizeof (sctp_addr_chunk ))); | ||||
| 279 | ch->direction = direction; | ||||
| 280 | copy_address(&ch->addr, vadd); | ||||
| 281 | for (i=0; i < NUM_CHUNKS0x100; i++) | ||||
| 282 | ch->addr_count[i] = 0; | ||||
| 283 | |||||
| 284 | if (IS_SCTP_CHUNK_TYPE(type)(((type) <= 16) || ((type) == 0x40) || ((type) == 0xC0) || ((type) == 0xC1) || ((type) == 0x80) || ((type) == 0x81))) | ||||
| 285 | ch->addr_count[type]++; | ||||
| 286 | else | ||||
| 287 | ch->addr_count[OTHER_CHUNKS_INDEX0xfe]++; | ||||
| 288 | |||||
| 289 | info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch); | ||||
| 290 | return info; | ||||
| 291 | } | ||||
| 292 | |||||
| 293 | static sctp_assoc_info_t * | ||||
| 294 | add_address(address *vadd, sctp_assoc_info_t *info, uint16_t direction) | ||||
| 295 | { | ||||
| 296 | GList *list; | ||||
| 297 | address *v=NULL((void*)0); | ||||
| 298 | |||||
| 299 | if (direction
| ||||
| 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 | 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) { | ||||
| 770 | info->verification_tag1 = sctp_info->verification_tag; | ||||
| 771 | } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) { | ||||
| 772 | info->verification_tag2 = sctp_info->verification_tag; | ||||
| 773 | } | ||||
| 774 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) || | ||||
| 775 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) || | ||||
| 776 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID0) || | ||||
| 777 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID0x40) || | ||||
| 778 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID3) || | ||||
| 779 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID16) || | ||||
| 780 | ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID0xC0)) | ||||
| 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) { | ||||
| 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; | ||||
| 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) { | ||||
| 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) || | ||||
| 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
| ||||
| 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
| ||||
| 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))) | ||||
| 881 | idx = OTHER_CHUNKS_INDEX0xfe; | ||||
| 882 | info->chunk_count[idx]++; | ||||
| 883 | if (info->direction
| ||||
| 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++) | ||||
| 889 | { | ||||
| 890 | type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); | ||||
| 891 | if (type == IPV4ADDRESS_PARAMETER_ID0x0005) | ||||
| 892 | { | ||||
| 893 | store = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address))); | ||||
| 894 | alloc_address_tvb(NULL((void*)0), store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET((0 + 2) + 2)); | ||||
| 895 | info = add_address(store, info, info->direction); | ||||
| 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) { | ||||
| |||||
| 905 | if (info->dir1->init || info->dir1->initack) { | ||||
| 906 | info->init_collision = true1; | ||||
| 907 | } | ||||
| 908 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) { | ||||
| 909 | info->dir1->init = true1; | ||||
| 910 | info->dir1->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 )); | ||||
| 911 | info->min_tsn1 = info->dir1->init_min_tsn; | ||||
| 912 | info->dir1->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
| 913 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) { | ||||
| 914 | info->dir1->initack = true1; | ||||
| 915 | info->dir1->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 )); | ||||
| 916 | info->min_tsn1 = info->dir1->initack_min_tsn; | ||||
| 917 | info->dir1->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
| 918 | } | ||||
| 919 | } else { | ||||
| 920 | if (info->dir2->init || info->dir2->initack) { | ||||
| 921 | info->init_collision = true1; | ||||
| 922 | } | ||||
| 923 | if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID1) { | ||||
| 924 | info->dir2->init = true1; | ||||
| 925 | info->dir2->init_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 )); | ||||
| 926 | info->min_tsn2 = info->dir2->init_min_tsn; | ||||
| 927 | info->dir2->init_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
| 928 | } else if (tvb_get_uint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID2) { | ||||
| 929 | info->dir2->initack = true1; | ||||
| 930 | info->dir2->initack_min_tsn = tvb_get_ntohl((sctp_info->tvb)[0], INIT_CHUNK_INITIAL_TSN_OFFSET(((((((0 + 1) + 1) + 2) + 4 ) + 4 ) + 2 ) + 2 )); | ||||
| 931 | info->min_tsn2 = info->dir2->initack_min_tsn; | ||||
| 932 | info->dir2->initack_vtag = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET(((0 + 1) + 1) + 2)); | ||||
| 933 | } | ||||
| 934 | } | ||||
| 935 | if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID2) | ||||
| 936 | { | ||||
| 937 | info->initack = true1; | ||||
| 938 | info->initack_dir = info->direction; | ||||
| 939 | } | ||||
| 940 | else if ((tvb_get_uint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID1) | ||||
| 941 | { | ||||
| 942 | info->init = true1; | ||||
| 943 | } | ||||
| 944 | } | ||||
| 945 | else | ||||
| 946 | { | ||||
| 947 | if (((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID2) && | ||||
| 948 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID0) && | ||||
| 949 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID0x40) && | ||||
| 950 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID3) && | ||||
| 951 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID16) && | ||||
| 952 | ((tvb_get_uint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID0xC0)) | ||||
| 953 | { | ||||
| 954 | if (!sack) | ||||
| 955 | sack = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
| 956 | sack->tsns = NULL((void*)0); | ||||
| 957 | sack->first_tsn = 0; | ||||
| 958 | if (!tsn) | ||||
| 959 | tsn = g_new0(tsn_t, 1)((tsn_t *) g_malloc0_n ((1), sizeof (tsn_t))); | ||||
| 960 | tsn->tsns = NULL((void*)0); | ||||
| 961 | tsn->first_tsn = 0; | ||||
| 962 | } | ||||
| 963 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) | ||||
| 964 | { | ||||
| 965 | idx = tvb_get_uint8(sctp_info->tvb[chunk_number],0); | ||||
| 966 | if (!IS_SCTP_CHUNK_TYPE(idx)(((idx) <= 16) || ((idx) == 0x40) || ((idx) == 0xC0) || (( idx) == 0xC1) || ((idx) == 0x80) || ((idx) == 0x81))) | ||||
| 967 | idx = OTHER_CHUNKS_INDEX0xfe; | ||||
| 968 | |||||
| 969 | info->chunk_count[idx]++; | ||||
| 970 | if (info->direction == 1) | ||||
| 971 | info->ep1_chunk_count[idx]++; | ||||
| 972 | else | ||||
| 973 | info->ep2_chunk_count[idx]++; | ||||
| 974 | info = add_chunk_count(&tmp_info.src, info,info->direction, idx); | ||||
| 975 | |||||
| 976 | if ((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) || | ||||
| 977 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID0x40)) | ||||
| 978 | datachunk = true1; | ||||
| 979 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID0xC0) | ||||
| 980 | forwardchunk = true1; | ||||
| 981 | if ((datachunk || forwardchunk) && tsn != NULL((void*)0)) | ||||
| 982 | { | ||||
| 983 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET((((0 + 1) + 1) + 2) + 0)); | ||||
| 984 | if (tsn->first_tsn == 0) | ||||
| 985 | tsn->first_tsn = tsnumber; | ||||
| 986 | if (datachunk) | ||||
| 987 | { | ||||
| 988 | t_s_n = (uint8_t *)g_malloc(16); | ||||
| 989 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, 16); | ||||
| 990 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
| 991 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1))-DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4); | ||||
| 992 | } else { | ||||
| 993 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4); | ||||
| 994 | } | ||||
| 995 | info->n_data_chunks++; | ||||
| 996 | info->n_data_bytes+=length; | ||||
| 997 | } | ||||
| 998 | else | ||||
| 999 | { | ||||
| 1000 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)); | ||||
| 1001 | t_s_n = (uint8_t *)g_malloc(length); | ||||
| 1002 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length); | ||||
| 1003 | info->n_forward_chunks++; | ||||
| 1004 | } | ||||
| 1005 | tsn->tsns = g_list_append(tsn->tsns, t_s_n); | ||||
| 1006 | |||||
| 1007 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort ))); | ||||
| 1008 | tsn_s->tsnumber = tsnumber; | ||||
| 1009 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs; | ||||
| 1010 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000; | ||||
| 1011 | tsn_s->offset = 0; | ||||
| 1012 | tsn_s->framenumber = framenumber; | ||||
| 1013 | tsn_s->length = length; | ||||
| 1014 | |||||
| 1015 | if (tsn->secs < info->min_secs) | ||||
| 1016 | { | ||||
| 1017 | info->min_secs = tsn->secs; | ||||
| 1018 | info->min_usecs = tsn->usecs; | ||||
| 1019 | } | ||||
| 1020 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) | ||||
| 1021 | info->min_usecs = tsn->usecs; | ||||
| 1022 | |||||
| 1023 | if (tsn->secs > info->max_secs) | ||||
| 1024 | { | ||||
| 1025 | info->max_secs = tsn->secs; | ||||
| 1026 | info->max_usecs = tsn->usecs; | ||||
| 1027 | } | ||||
| 1028 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) | ||||
| 1029 | info->max_usecs = tsn->usecs; | ||||
| 1030 | |||||
| 1031 | if (info->direction == 1) | ||||
| 1032 | { | ||||
| 1033 | if (info->firstdata) { | ||||
| 1034 | info->firstdata = false0; | ||||
| 1035 | if (info->init_collision) { | ||||
| 1036 | if (tsnumber != info->min_tsn1) { | ||||
| 1037 | info->min_tsn1 = info->dir1->init_min_tsn; | ||||
| 1038 | } | ||||
| 1039 | info->min_tsn2 = info->dir2->initack_min_tsn; | ||||
| 1040 | } | ||||
| 1041 | } else { | ||||
| 1042 | if(tsnumber < info->min_tsn1) { | ||||
| 1043 | info->min_tsn1 = tsnumber; | ||||
| 1044 | } | ||||
| 1045 | } | ||||
| 1046 | if ((info->init || (info->initack && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1) | ||||
| 1047 | { | ||||
| 1048 | if (datachunk) | ||||
| 1049 | { | ||||
| 1050 | info->n_data_chunks_ep1++; | ||||
| 1051 | info->n_data_bytes_ep1 += length; | ||||
| 1052 | } | ||||
| 1053 | else if (forwardchunk) | ||||
| 1054 | { | ||||
| 1055 | info->n_forward_chunks_ep1++; | ||||
| 1056 | } | ||||
| 1057 | } | ||||
| 1058 | if(tsnumber > info->max_tsn1) | ||||
| 1059 | { | ||||
| 1060 | info->max_tsn1 = tsnumber; | ||||
| 1061 | if (datachunk) | ||||
| 1062 | { | ||||
| 1063 | info->n_data_chunks_ep1++; | ||||
| 1064 | info->n_data_bytes_ep1 += length; | ||||
| 1065 | } | ||||
| 1066 | else if (forwardchunk) | ||||
| 1067 | { | ||||
| 1068 | info->n_forward_chunks_ep1++; | ||||
| 1069 | } | ||||
| 1070 | } | ||||
| 1071 | if (datachunk) | ||||
| 1072 | { | ||||
| 1073 | if (info->init == false0) { | ||||
| 1074 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
| 1075 | if (info->outstream1 < tmp) info->outstream1 = tmp; | ||||
| 1076 | } | ||||
| 1077 | if (info->initack == false0) { | ||||
| 1078 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
| 1079 | if (info->instream2 < tmp) info->instream2 = tmp; | ||||
| 1080 | } | ||||
| 1081 | } | ||||
| 1082 | |||||
| 1083 | g_ptr_array_add(info->sort_tsn1, tsn_s); | ||||
| 1084 | info->n_array_tsn1++; | ||||
| 1085 | } | ||||
| 1086 | else if (info->direction == 2) | ||||
| 1087 | { | ||||
| 1088 | if (info->firstdata) { | ||||
| 1089 | info->firstdata = false0; | ||||
| 1090 | if (info->init_collision) { | ||||
| 1091 | if (tsnumber != info->min_tsn2) { | ||||
| 1092 | info->min_tsn2 = info->dir2->init_min_tsn; | ||||
| 1093 | info->initack_dir = 2; | ||||
| 1094 | } | ||||
| 1095 | info->min_tsn1 = info->dir1->initack_min_tsn; | ||||
| 1096 | } | ||||
| 1097 | } else { | ||||
| 1098 | if(tsnumber < info->min_tsn2) | ||||
| 1099 | info->min_tsn2 = tsnumber; | ||||
| 1100 | } | ||||
| 1101 | |||||
| 1102 | if ((info->initack && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2) | ||||
| 1103 | { | ||||
| 1104 | if (datachunk) | ||||
| 1105 | { | ||||
| 1106 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
| 1107 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4); | ||||
| 1108 | } else { | ||||
| 1109 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4); | ||||
| 1110 | } | ||||
| 1111 | info->n_data_chunks_ep2++; | ||||
| 1112 | info->n_data_bytes_ep2+=length; | ||||
| 1113 | } | ||||
| 1114 | else if (forwardchunk) | ||||
| 1115 | { | ||||
| 1116 | info->n_forward_chunks_ep2++; | ||||
| 1117 | } | ||||
| 1118 | } | ||||
| 1119 | if (tsnumber > info->max_tsn2) | ||||
| 1120 | { | ||||
| 1121 | info->max_tsn2 = tsnumber; | ||||
| 1122 | if (datachunk) | ||||
| 1123 | { | ||||
| 1124 | if (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID0) { | ||||
| 1125 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4); | ||||
| 1126 | } else { | ||||
| 1127 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)) - I_DATA_CHUNK_HEADER_LENGTH((1 + 1 + 2) + 4 + 2 + 2 + 4 + 4); | ||||
| 1128 | } | ||||
| 1129 | info->n_data_chunks_ep2++; | ||||
| 1130 | info->n_data_bytes_ep2+=length; | ||||
| 1131 | } | ||||
| 1132 | else if (forwardchunk) | ||||
| 1133 | { | ||||
| 1134 | info->n_forward_chunks_ep2++; | ||||
| 1135 | } | ||||
| 1136 | } | ||||
| 1137 | if (datachunk) | ||||
| 1138 | { | ||||
| 1139 | if (info->init == false0) { | ||||
| 1140 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
| 1141 | if (info->instream1 < tmp) info->instream1 = tmp; | ||||
| 1142 | } | ||||
| 1143 | if (info->initack == false0) { | ||||
| 1144 | uint16_t tmp = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4))+1; | ||||
| 1145 | if (info->outstream2 < tmp) info->outstream2 = tmp; | ||||
| 1146 | } | ||||
| 1147 | } | ||||
| 1148 | |||||
| 1149 | g_ptr_array_add(info->sort_tsn2, tsn_s); | ||||
| 1150 | info->n_array_tsn2++; | ||||
| 1151 | } | ||||
| 1152 | } | ||||
| 1153 | else if (((tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID3) || | ||||
| 1154 | (tvb_get_uint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID16)) && | ||||
| 1155 | sack != NULL((void*)0)) | ||||
| 1156 | { | ||||
| 1157 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET((((0 + 1) + 1) + 2) + 0)); | ||||
| 1158 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET((0 + 1) + 1)); | ||||
| 1159 | |||||
| 1160 | if (sack->first_tsn == 0) | ||||
| 1161 | sack->first_tsn = tsnumber; | ||||
| 1162 | |||||
| 1163 | t_s_n = (uint8_t *)g_malloc(length); | ||||
| 1164 | tvb_memcpy(sctp_info->tvb[chunk_number], (uint8_t *)(t_s_n),0, length); | ||||
| 1165 | sack->tsns = g_list_append(sack->tsns, t_s_n); | ||||
| 1166 | sackchunk = true1; | ||||
| 1167 | tsn_s = g_new0(struct tsn_sort, 1)((struct tsn_sort *) g_malloc0_n ((1), sizeof (struct tsn_sort ))); | ||||
| 1168 | tsn_s->tsnumber = tsnumber; | ||||
| 1169 | tsn_s->secs = tsn->secs = (uint32_t)pinfo->rel_ts.secs; | ||||
| 1170 | tsn_s->usecs = tsn->usecs = (uint32_t)pinfo->rel_ts.nsecs/1000; | ||||
| 1171 | tsn_s->offset = 0; | ||||
| 1172 | tsn_s->framenumber = framenumber; | ||||
| 1173 | tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET(((((0 + 1) + 1) + 2) + 0) + 4)); | ||||
| 1174 | |||||
| 1175 | if (tsn->secs < info->min_secs) | ||||
| 1176 | { | ||||
| 1177 | info->min_secs = tsn->secs; | ||||
| 1178 | info->min_usecs = tsn->usecs; | ||||
| 1179 | } | ||||
| 1180 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) | ||||
| 1181 | info->min_usecs = tsn->usecs; | ||||
| 1182 | |||||
| 1183 | if (tsn->secs > info->max_secs) | ||||
| 1184 | { | ||||
| 1185 | info->max_secs = tsn->secs; | ||||
| 1186 | info->max_usecs = tsn->usecs; | ||||
| 1187 | } | ||||
| 1188 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) | ||||
| 1189 | info->max_usecs = tsn->usecs; | ||||
| 1190 | |||||
| 1191 | |||||
| 1192 | if (info->direction == 2) | ||||
| 1193 | { | ||||
| 1194 | if(tsnumber < info->min_tsn1) | ||||
| 1195 | info->min_tsn1 = tsnumber; | ||||
| 1196 | if(tsnumber > info->max_tsn1) | ||||
| 1197 | info->max_tsn1 = tsnumber; | ||||
| 1198 | if (tsn_s->length > info->max_window1) | ||||
| 1199 | info->max_window1 = tsn_s->length; | ||||
| 1200 | g_ptr_array_add(info->sort_sack1, tsn_s); | ||||
| 1201 | info->n_sack_chunks_ep1++; | ||||
| 1202 | } | ||||
| 1203 | else if (info->direction == 1) | ||||
| 1204 | { | ||||
| 1205 | if(tsnumber < info->min_tsn2) | ||||
| 1206 | info->min_tsn2 = tsnumber; | ||||
| 1207 | if(tsnumber > info->max_tsn2) | ||||
| 1208 | info->max_tsn2 = tsnumber; | ||||
| 1209 | if (tsn_s->length > info->max_window2) | ||||
| 1210 | info->max_window2 = tsn_s->length; | ||||
| 1211 | g_ptr_array_add(info->sort_sack2, tsn_s); | ||||
| 1212 | info->n_sack_chunks_ep2++; | ||||
| 1213 | } | ||||
| 1214 | } | ||||
| 1215 | } | ||||
| 1216 | } | ||||
| 1217 | |||||
| 1218 | if (datachunk || forwardchunk) | ||||
| 1219 | { | ||||
| 1220 | if (info->direction == 1) | ||||
| 1221 | info->tsn1 = g_list_prepend(info->tsn1, tsn); | ||||
| 1222 | else if (info->direction == 2) | ||||
| 1223 | info->tsn2 = g_list_prepend(info->tsn2, tsn); | ||||
| 1224 | tsn_used = true1; | ||||
| 1225 | } | ||||
| 1226 | if (sackchunk == true1) | ||||
| 1227 | { | ||||
| 1228 | if (info->direction == 1) | ||||
| 1229 | info->sack2 = g_list_prepend(info->sack2, sack); | ||||
| 1230 | else if(info->direction == 2) | ||||
| 1231 | info->sack1 = g_list_prepend(info->sack1, sack); | ||||
| 1232 | sack_used = true1; | ||||
| 1233 | } | ||||
| 1234 | info->n_tvbs += sctp_info->number_of_tvbs; | ||||
| 1235 | sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs; | ||||
| 1236 | info = calc_checksum(sctp_info, info); | ||||
| 1237 | info->n_packets++; | ||||
| 1238 | } | ||||
| 1239 | if (tsn && !tsn_used) | ||||
| 1240 | tsn_free(tsn); | ||||
| 1241 | if (sack && !sack_used) | ||||
| 1242 | tsn_free(sack); | ||||
| 1243 | free_address(&tmp_info.src); | ||||
| 1244 | free_address(&tmp_info.dst); | ||||
| 1245 | return TAP_PACKET_REDRAW; | ||||
| 1246 | } | ||||
| 1247 | |||||
| 1248 | |||||
| 1249 | /****************************************************************************/ | ||||
| 1250 | void | ||||
| 1251 | remove_tap_listener_sctp_stat(void) | ||||
| 1252 | { | ||||
| 1253 | if (sctp_tapinfo_struct.is_registered) { | ||||
| 1254 | remove_tap_listener(&sctp_tapinfo_struct); | ||||
| 1255 | sctp_tapinfo_struct.is_registered = false0; | ||||
| 1256 | } | ||||
| 1257 | } | ||||
| 1258 | |||||
| 1259 | |||||
| 1260 | void | ||||
| 1261 | sctp_stat_scan(void) | ||||
| 1262 | { | ||||
| 1263 | if (!sctp_tapinfo_struct.is_registered) { | ||||
| 1264 | register_tap_listener_sctp_stat(); | ||||
| 1265 | } | ||||
| 1266 | } | ||||
| 1267 | |||||
| 1268 | const sctp_allassocs_info_t * | ||||
| 1269 | sctp_stat_get_info(void) | ||||
| 1270 | { | ||||
| 1271 | return &sctp_tapinfo_struct; | ||||
| 1272 | } | ||||
| 1273 | |||||
| 1274 | const sctp_assoc_info_t * | ||||
| 1275 | get_sctp_assoc_info(uint16_t assoc_id) | ||||
| 1276 | { | ||||
| 1277 | sctp_tmp_info_t needle = { .assoc_id = assoc_id }; | ||||
| 1278 | return find_assoc(&needle); | ||||
| 1279 | } | ||||
| 1280 | |||||
| 1281 | void | ||||
| 1282 | register_tap_listener_sctp_stat(void) | ||||
| 1283 | { | ||||
| 1284 | GString *error_string; | ||||
| 1285 | |||||
| 1286 | if (!sctp_tapinfo_struct.is_registered) | ||||
| 1287 | { | ||||
| 1288 | if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL((void*)0), 0, reset, packet, NULL((void*)0), NULL((void*)0)))) { | ||||
| 1289 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", error_string->str); | ||||
| 1290 | g_string_free(error_string, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (error_string), ((!(0)))) : g_string_free_and_steal (error_string )) : (g_string_free) ((error_string), ((!(0))))); | ||||
| 1291 | return; | ||||
| 1292 | } | ||||
| 1293 | sctp_tapinfo_struct.is_registered=true1; | ||||
| 1294 | } | ||||
| 1295 | } |
| 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 | 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 | |||||
| 58 | typedef 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 | |||||
| 70 | static inline void | ||||
| 71 | clear_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 | */ | ||||
| 87 | static inline void | ||||
| 88 | set_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 | |||||
| 104 | static inline void | ||||
| 105 | set_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 | |||||
| 113 | static inline void | ||||
| 114 | set_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 | */ | ||||
| 133 | static inline void | ||||
| 134 | set_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 | */ | ||||
| 156 | static inline void | ||||
| 157 | alloc_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); | ||||
| 160 | clear_address(addr); | ||||
| 161 | addr->type = addr_type; | ||||
| 162 | if (addr_len
| ||||
| 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); | ||||
| 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); | ||||
| 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 | */ | ||||
| 188 | static inline void | ||||
| 189 | alloc_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); | ||||
| 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 | */ | ||||
| 205 | static inline int | ||||
| 206 | cmp_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 | */ | ||||
| 233 | static inline bool_Bool | ||||
| 234 | addresses_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 | */ | ||||
| 259 | static inline bool_Bool | ||||
| 260 | addresses_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 | */ | ||||
| 276 | static inline void | ||||
| 277 | copy_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 | */ | ||||
| 288 | static inline void | ||||
| 289 | copy_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 | */ | ||||
| 298 | static inline void | ||||
| 299 | copy_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 | */ | ||||
| 308 | static inline void | ||||
| 309 | free_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 | */ | ||||
| 324 | static inline void | ||||
| 325 | free_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 | */ | ||||
| 335 | static inline unsigned | ||||
| 336 | add_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 | */ | ||||
| 355 | static inline uint64_t | ||||
| 356 | add_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 | |||||
| 368 | WS_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. */ | ||||
| 371 | typedef 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 | */ |