nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Copyright 2004-2013, Irene Ruengeler <i.ruengeler [AT] fh-muenster.de> |
||
3 | * |
||
4 | * Wireshark - Network traffic analyzer |
||
5 | * By Gerald Combs <gerald@wireshark.org> |
||
6 | * Copyright 1998 Gerald Combs |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License |
||
10 | * as published by the Free Software Foundation; either version 2 |
||
11 | * of the License, or (at your option) any later version. |
||
12 | * |
||
13 | * This program is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with this program; if not, write to the Free Software |
||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
21 | */ |
||
22 | |||
23 | #include "config.h" |
||
24 | |||
25 | #include <string.h> |
||
26 | #include <math.h> |
||
27 | |||
28 | #include <glib.h> |
||
29 | |||
30 | #include "epan/packet_info.h" |
||
31 | #include "epan/tap.h" |
||
32 | #include "epan/value_string.h" |
||
33 | |||
34 | #include "ui/tap-sctp-analysis.h" |
||
35 | |||
36 | #include "ui/simple_dialog.h" |
||
37 | |||
38 | #define FORWARD_STREAM 0 |
||
39 | #define BACKWARD_STREAM 1 |
||
40 | #define FORWARD_ADD_FORWARD_VTAG 2 |
||
41 | #define BACKWARD_ADD_FORWARD_VTAG 3 |
||
42 | #define BACKWARD_ADD_BACKWARD_VTAG 4 |
||
43 | #define ADDRESS_FORWARD_STREAM 5 |
||
44 | #define ADDRESS_BACKWARD_STREAM 6 |
||
45 | #define ADDRESS_FORWARD_ADD_FORWARD_VTAG 7 |
||
46 | #define ADDRESS_BACKWARD_ADD_FORWARD_VTAG 8 |
||
47 | #define ADDRESS_BACKWARD_ADD_BACKWARD_VTAG 9 |
||
48 | #define ASSOC_NOT_FOUND 10 |
||
49 | |||
50 | static sctp_allassocs_info_t sctp_tapinfo_struct = {0, NULL, FALSE, NULL}; |
||
51 | |||
52 | static void |
||
53 | free_first(gpointer data, gpointer user_data _U_) |
||
54 | { |
||
55 | g_free(data); |
||
56 | } |
||
57 | |||
58 | static void |
||
59 | tsn_free(gpointer data, gpointer user_data _U_) |
||
60 | { |
||
61 | tsn_t *tsn; |
||
62 | |||
63 | tsn = (tsn_t *) data; |
||
64 | if (tsn->tsns != NULL) |
||
65 | { |
||
66 | g_list_foreach(tsn->tsns, free_first, NULL); |
||
67 | g_list_free(tsn->tsns); |
||
68 | tsn->tsns=NULL; |
||
69 | } |
||
70 | } |
||
71 | |||
72 | |||
73 | static void |
||
74 | reset(void *arg) |
||
75 | { |
||
76 | sctp_allassocs_info_t *tapdata = (sctp_allassocs_info_t *)arg; |
||
77 | GList* list; |
||
78 | sctp_assoc_info_t * info; |
||
79 | |||
80 | list = g_list_first(tapdata->assoc_info_list); |
||
81 | while (list) |
||
82 | { |
||
83 | info = (sctp_assoc_info_t *) (list->data); |
||
84 | |||
85 | if (info->addr1 != NULL) |
||
86 | { |
||
87 | g_list_foreach(info->addr1, free_first, NULL); |
||
88 | g_list_free(info->addr1); |
||
89 | info->addr1 = NULL; |
||
90 | } |
||
91 | |||
92 | if (info->addr2 != NULL) |
||
93 | { |
||
94 | g_list_foreach(info->addr2,free_first, NULL); |
||
95 | g_list_free(info->addr2); |
||
96 | info->addr2 = NULL; |
||
97 | } |
||
98 | |||
99 | if (info->error_info_list != NULL) |
||
100 | { |
||
101 | g_list_foreach(info->error_info_list, free_first, NULL); |
||
102 | g_list_free(info->error_info_list); |
||
103 | info->error_info_list = NULL; |
||
104 | } |
||
105 | |||
106 | if (info->frame_numbers != NULL) |
||
107 | { |
||
108 | g_list_foreach(info->frame_numbers, free_first, NULL); |
||
109 | g_list_free(info->frame_numbers); |
||
110 | info->frame_numbers = NULL; |
||
111 | } |
||
112 | |||
113 | if (info->tsn1 != NULL) |
||
114 | { |
||
115 | g_list_foreach(info->tsn1, tsn_free, NULL); |
||
116 | g_list_free(info->tsn1); |
||
117 | info->tsn1 = NULL; |
||
118 | } |
||
119 | |||
120 | if (info->tsn2 != NULL) |
||
121 | { |
||
122 | g_list_foreach(info->tsn2, tsn_free, NULL); |
||
123 | g_list_free(info->tsn2); |
||
124 | info->tsn2 = NULL; |
||
125 | } |
||
126 | |||
127 | if (info->sack1 != NULL) |
||
128 | { |
||
129 | g_list_foreach(info->sack1, tsn_free, NULL); |
||
130 | g_list_free(info->sack1); |
||
131 | info->sack1 = NULL; |
||
132 | } |
||
133 | |||
134 | if (info->sack2 != NULL) |
||
135 | { |
||
136 | g_list_foreach(info->sack2, tsn_free, NULL); |
||
137 | g_list_free(info->sack2); |
||
138 | info->sack2 = NULL; |
||
139 | } |
||
140 | |||
141 | if (info->sort_tsn1 != NULL) |
||
142 | g_ptr_array_free(info->sort_tsn1, TRUE); |
||
143 | |||
144 | if (info->sort_tsn2 != NULL) |
||
145 | g_ptr_array_free(info->sort_tsn2, TRUE); |
||
146 | |||
147 | if (info->sort_sack1 != NULL) |
||
148 | g_ptr_array_free(info->sort_sack1, TRUE); |
||
149 | |||
150 | if (info->sort_sack2 != NULL) |
||
151 | g_ptr_array_free(info->sort_sack2, TRUE); |
||
152 | |||
153 | if (info->min_max != NULL) |
||
154 | { |
||
155 | g_slist_foreach(info->min_max, free_first, NULL); |
||
156 | info->min_max = NULL; |
||
157 | } |
||
158 | |||
159 | g_free(list->data); |
||
160 | list = g_list_next(list); |
||
161 | } |
||
162 | g_list_free(tapdata->assoc_info_list); |
||
163 | tapdata->sum_tvbs = 0; |
||
164 | tapdata->assoc_info_list = NULL; |
||
165 | } |
||
166 | |||
167 | |||
168 | static sctp_assoc_info_t * |
||
169 | calc_checksum(const struct _sctp_info *check_data, sctp_assoc_info_t *data) |
||
170 | { |
||
171 | gboolean ok = FALSE; |
||
172 | |||
173 | if (check_data->adler32_calculated) |
||
174 | { |
||
175 | data->n_adler32_calculated++; |
||
176 | if (check_data->adler32_correct) |
||
177 | data->n_adler32_correct++; |
||
178 | } |
||
179 | if (check_data->crc32c_calculated) |
||
180 | { |
||
181 | data->n_crc32c_calculated++; |
||
182 | if (check_data->crc32c_correct) |
||
183 | data->n_crc32c_correct++; |
||
184 | } |
||
185 | if (data->n_adler32_calculated > 0) |
||
186 | { |
||
187 | if ((float)(data->n_adler32_correct*1.0/data->n_adler32_calculated) > 0.5) |
||
188 | { |
||
189 | char str[] = "ADLER32"; |
||
190 | g_strlcpy(data->checksum_type, str, strlen(str)); |
||
191 | data->n_checksum_errors=(data->n_adler32_calculated-data->n_adler32_correct); |
||
192 | ok = TRUE; |
||
193 | } |
||
194 | } |
||
195 | |||
196 | if (data->n_crc32c_calculated>0) |
||
197 | { |
||
198 | if ((float)(data->n_crc32c_correct*1.0/data->n_crc32c_calculated) > 0.5) |
||
199 | { |
||
200 | char str[] = "CRC32C"; |
||
201 | g_strlcpy(data->checksum_type, str, strlen(str)); |
||
202 | data->n_checksum_errors=data->n_crc32c_calculated-data->n_crc32c_correct; |
||
203 | ok = TRUE; |
||
204 | } |
||
205 | } |
||
206 | |||
207 | if (!ok) |
||
208 | { |
||
209 | char str[] = "UNKNOWN"; |
||
210 | g_strlcpy(data->checksum_type, str, strlen(str)); |
||
211 | data->n_checksum_errors=0; |
||
212 | } |
||
213 | |||
214 | return(data); |
||
215 | |||
216 | } |
||
217 | |||
218 | |||
219 | static sctp_assoc_info_t * |
||
220 | find_assoc(sctp_tmp_info_t *needle) |
||
221 | { |
||
222 | sctp_allassocs_info_t *assoc_info; |
||
223 | sctp_assoc_info_t *info = NULL; |
||
224 | GList* list; |
||
225 | |||
226 | assoc_info = &sctp_tapinfo_struct; |
||
227 | if ((list = g_list_last(assoc_info->assoc_info_list))!=NULL) |
||
228 | { |
||
229 | while (list) |
||
230 | { |
||
231 | info = (sctp_assoc_info_t*)(list->data); |
||
232 | if (needle->assoc_id == info->assoc_id) |
||
233 | return info; |
||
234 | |||
235 | list = g_list_previous(list); |
||
236 | } |
||
237 | } |
||
238 | return NULL; |
||
239 | } |
||
240 | |||
241 | static sctp_assoc_info_t * |
||
242 | add_chunk_count(address *vadd, sctp_assoc_info_t *info, guint32 direction, guint32 type) |
||
243 | { |
||
244 | GList *list; |
||
245 | address *v=NULL; |
||
246 | sctp_addr_chunk *ch=NULL; |
||
247 | guint8 * dat; |
||
248 | int i; |
||
249 | |||
250 | list = g_list_first(info->addr_chunk_count); |
||
251 | |||
252 | while (list) |
||
253 | { |
||
254 | ch = (sctp_addr_chunk *)(list->data); |
||
255 | if (ch->direction == direction) |
||
256 | { |
||
257 | v = (address *) (ch->addr); |
||
258 | if (addresses_equal(vadd, v)) |
||
259 | { |
||
260 | if (IS_SCTP_CHUNK_TYPE(type)) |
||
261 | ch->addr_count[type]++; |
||
262 | else |
||
263 | ch->addr_count[OTHER_CHUNKS_INDEX]++; |
||
264 | return info; |
||
265 | } |
||
266 | else |
||
267 | { |
||
268 | list = g_list_next(list); |
||
269 | } |
||
270 | } |
||
271 | else |
||
272 | list = g_list_next(list); |
||
273 | } |
||
274 | ch = (sctp_addr_chunk *)g_malloc(sizeof(sctp_addr_chunk)); |
||
275 | ch->direction = direction; |
||
276 | ch->addr = (address *)g_malloc(sizeof(address)); |
||
277 | ch->addr->type = vadd->type; |
||
278 | ch->addr->len = vadd->len; |
||
279 | dat = (guint8 *)g_malloc(vadd->len); |
||
280 | memcpy(dat, vadd->data, vadd->len); |
||
281 | ch->addr->data = dat; |
||
282 | for (i=0; i < NUM_CHUNKS; i++) |
||
283 | ch->addr_count[i] = 0; |
||
284 | |||
285 | if (IS_SCTP_CHUNK_TYPE(type)) |
||
286 | ch->addr_count[type]++; |
||
287 | else |
||
288 | ch->addr_count[OTHER_CHUNKS_INDEX]++; |
||
289 | |||
290 | info->addr_chunk_count = g_list_append(info->addr_chunk_count, ch); |
||
291 | return info; |
||
292 | } |
||
293 | |||
294 | static sctp_assoc_info_t * |
||
295 | add_address(address *vadd, sctp_assoc_info_t *info, guint16 direction) |
||
296 | { |
||
297 | GList *list; |
||
298 | address *v=NULL; |
||
299 | |||
300 | if (direction == 1) |
||
301 | list = g_list_first(info->addr1); |
||
302 | else |
||
303 | list = g_list_first(info->addr2); |
||
304 | |||
305 | while (list) |
||
306 | { |
||
307 | v = (address *) (list->data); |
||
308 | if (addresses_equal(vadd, v)) { |
||
309 | g_free(vadd); |
||
310 | return info; |
||
311 | } |
||
312 | list = g_list_next(list); |
||
313 | } |
||
314 | |||
315 | if (direction == 1) |
||
316 | info->addr1 = g_list_append(info->addr1, vadd); |
||
317 | else if (direction==2) |
||
318 | info->addr2 = g_list_append(info->addr2, vadd); |
||
319 | |||
320 | return info; |
||
321 | } |
||
322 | |||
323 | static gboolean |
||
324 | packet(void *tapdata _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data) |
||
325 | { |
||
326 | const struct _sctp_info *sctp_info = (const struct _sctp_info *)data; |
||
327 | guint32 chunk_number = 0, tsnumber, framenumber; |
||
328 | sctp_tmp_info_t tmp_info; |
||
329 | sctp_assoc_info_t *info = NULL; |
||
330 | sctp_error_info_t *error = NULL; |
||
331 | guint16 type, length = 0; |
||
332 | address *store = NULL; |
||
333 | tsn_t *tsn = NULL; |
||
334 | tsn_t *sack = NULL; |
||
335 | guint8 *t_s_n = NULL; |
||
336 | gboolean sackchunk = FALSE; |
||
337 | gboolean datachunk = FALSE; |
||
338 | gboolean forwardchunk = FALSE; |
||
339 | struct tsn_sort *tsn_s; |
||
340 | guint8* addr = NULL; |
||
341 | int i; |
||
342 | guint8 idx = 0; |
||
343 | |||
344 | framenumber = pinfo->num; |
||
345 | |||
346 | type = sctp_info->ip_src.type; |
||
347 | |||
348 | if (type == AT_IPv4) |
||
349 | { |
||
350 | tmp_info.src.type = AT_IPv4; |
||
351 | tmp_info.src.len = 4; |
||
352 | } |
||
353 | else if (type == AT_IPv6) |
||
354 | { |
||
355 | tmp_info.src.type = AT_IPv6; |
||
356 | tmp_info.src.len = 16; |
||
357 | } |
||
358 | else |
||
359 | { |
||
360 | tmp_info.src.type = AT_NONE; |
||
361 | tmp_info.src.len = 0; |
||
362 | } |
||
363 | |||
364 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
365 | memcpy(addr, sctp_info->ip_src.data, tmp_info.src.len); |
||
366 | tmp_info.src.data = addr; |
||
367 | |||
368 | type = sctp_info->ip_dst.type; |
||
369 | |||
370 | if (type == AT_IPv4) |
||
371 | { |
||
372 | tmp_info.dst.type = AT_IPv4; |
||
373 | tmp_info.dst.len = 4; |
||
374 | } |
||
375 | else if (type == AT_IPv6) |
||
376 | { |
||
377 | tmp_info.dst.type = AT_IPv6; |
||
378 | tmp_info.dst.len = 16; |
||
379 | } |
||
380 | else |
||
381 | { |
||
382 | tmp_info.dst.type = AT_NONE; |
||
383 | tmp_info.dst.len = 0; |
||
384 | } |
||
385 | |||
386 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
387 | memcpy(addr, sctp_info->ip_dst.data, tmp_info.dst.len); |
||
388 | tmp_info.dst.data = addr; |
||
389 | |||
390 | tmp_info.port1 = sctp_info->sport; |
||
391 | tmp_info.port2 = sctp_info->dport; |
||
392 | |||
393 | if (sctp_info->vtag_reflected) |
||
394 | { |
||
395 | tmp_info.verification_tag2 = sctp_info->verification_tag; |
||
396 | tmp_info.verification_tag1 = 0; |
||
397 | } |
||
398 | else |
||
399 | { |
||
400 | tmp_info.verification_tag1 = sctp_info->verification_tag; |
||
401 | tmp_info.verification_tag2 = 0; |
||
402 | } |
||
403 | tmp_info.n_tvbs = 0; |
||
404 | if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) |
||
405 | { |
||
406 | tmp_info.initiate_tag = tvb_get_ntohl(sctp_info->tvb[0], 4); |
||
407 | } |
||
408 | else |
||
409 | { |
||
410 | tmp_info.initiate_tag = 0; |
||
411 | } |
||
412 | |||
413 | tmp_info.direction = sctp_info->direction; |
||
414 | tmp_info.assoc_id = sctp_info->assoc_index; |
||
415 | info = find_assoc(&tmp_info); |
||
416 | if (!info) |
||
417 | { |
||
418 | tmp_info.n_tvbs = sctp_info->number_of_tvbs; |
||
419 | sctp_tapinfo_struct.sum_tvbs+=sctp_info->number_of_tvbs; |
||
420 | |||
421 | if (sctp_info->number_of_tvbs > 0) |
||
422 | { |
||
423 | info = (sctp_assoc_info_t *)g_malloc(sizeof(sctp_assoc_info_t)); |
||
424 | memset(info, 0, sizeof(sctp_assoc_info_t)); |
||
425 | info->assoc_id = sctp_info->assoc_index; |
||
426 | info->src.type = tmp_info.src.type; |
||
427 | info->src.len = tmp_info.src.len; |
||
428 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
429 | memcpy(addr,(tmp_info.src.data), tmp_info.src.len); |
||
430 | info->src.data = addr; |
||
431 | info->dst.type = tmp_info.dst.type; |
||
432 | info->dst.len = tmp_info.dst.len; |
||
433 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
434 | memcpy(addr, (tmp_info.dst.data), tmp_info.dst.len); |
||
435 | info->dst.data = addr; |
||
436 | info->port1 = tmp_info.port1; |
||
437 | info->port2 = tmp_info.port2; |
||
438 | info->verification_tag1 = tmp_info.verification_tag1; |
||
439 | info->verification_tag2 = tmp_info.verification_tag2; |
||
440 | info->initiate_tag = tmp_info.initiate_tag; |
||
441 | info->n_tvbs = tmp_info.n_tvbs; |
||
442 | info->init = FALSE; |
||
443 | info->initack = FALSE; |
||
444 | info->check_address = FALSE; |
||
445 | info->direction = sctp_info->direction; |
||
446 | info = calc_checksum(sctp_info, info); |
||
447 | info->n_packets = 1; |
||
448 | info->error_info_list = NULL; |
||
449 | info->min_secs = 0xffffffff; |
||
450 | info->min_usecs = 0xffffffff; |
||
451 | info->max_secs = 0; |
||
452 | info->max_usecs = 0; |
||
453 | info->min_tsn2 = 0xFFFFFFFF; |
||
454 | info->min_tsn1 = 0xffffffff; |
||
455 | info->max_tsn1 = 0; |
||
456 | info->max_tsn2 = 0; |
||
457 | info->max_bytes1 = 0; |
||
458 | info->max_bytes2 = 0; |
||
459 | info->n_data_chunks = 0; |
||
460 | info->n_data_bytes = 0; |
||
461 | info->n_data_chunks_ep1 = 0; |
||
462 | info->n_data_bytes_ep1 = 0; |
||
463 | info->n_data_chunks_ep2 = 0; |
||
464 | info->n_data_bytes_ep2 = 0; |
||
465 | info->n_sack_chunks_ep1 = 0; |
||
466 | info->n_sack_chunks_ep2 = 0; |
||
467 | info->n_array_tsn1 = 0; |
||
468 | info->n_array_tsn2 = 0; |
||
469 | info->n_forward_chunks = 0; |
||
470 | info->max_window1 = 0; |
||
471 | info->max_window2 = 0; |
||
472 | info->min_max = NULL; |
||
473 | info->sort_tsn1 = g_ptr_array_new(); |
||
474 | info->sort_tsn2 = g_ptr_array_new(); |
||
475 | info->sort_sack1 = g_ptr_array_new(); |
||
476 | info->sort_sack2 = g_ptr_array_new(); |
||
477 | |||
478 | for (i=0; i < NUM_CHUNKS; i++) |
||
479 | { |
||
480 | info->chunk_count[i] = 0; |
||
481 | info->ep1_chunk_count[i] = 0; |
||
482 | info->ep2_chunk_count[i] = 0; |
||
483 | } |
||
484 | info->addr_chunk_count = NULL; |
||
485 | |||
486 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) || |
||
487 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) || |
||
488 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || |
||
489 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || |
||
490 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || |
||
491 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || |
||
492 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) |
||
493 | { |
||
494 | tsn = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
495 | sack = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
496 | tsn->tsns = NULL; |
||
497 | tsn->first_tsn = 0; |
||
498 | sack->tsns = NULL; |
||
499 | sack->first_tsn = 0; |
||
500 | sack->src.type=tsn->src.type = tmp_info.src.type; |
||
501 | sack->src.len=tsn->src.len = tmp_info.src.len; |
||
502 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
503 | memcpy(addr, tmp_info.src.data, tmp_info.src.len); |
||
504 | tsn->src.data = addr; |
||
505 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
506 | memcpy(addr, tmp_info.src.data, tmp_info.src.len); |
||
507 | sack->src.data = addr; |
||
508 | sack->dst.type = tsn->dst.type = tmp_info.dst.type; |
||
509 | sack->dst.len =tsn->dst.len = tmp_info.dst.len; |
||
510 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
511 | memcpy(addr, tmp_info.dst.data, tmp_info.dst.len); |
||
512 | tsn->dst.data = addr; |
||
513 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
514 | memcpy(addr, tmp_info.dst.data, tmp_info.dst.len); |
||
515 | sack->dst.data = addr; |
||
516 | sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
517 | sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
518 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || |
||
519 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || |
||
520 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || |
||
521 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || |
||
522 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) |
||
523 | { |
||
524 | if (tsn->secs < info->min_secs) |
||
525 | { |
||
526 | info->min_secs = tsn->secs; |
||
527 | info->min_usecs = tsn->usecs; |
||
528 | } |
||
529 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
530 | info->min_usecs = tsn->usecs; |
||
531 | |||
532 | if (tsn->secs > info->max_secs) |
||
533 | { |
||
534 | info->max_secs = tsn->secs; |
||
535 | info->max_usecs = tsn->usecs; |
||
536 | } |
||
537 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
538 | info->max_usecs = tsn->usecs; |
||
539 | } |
||
540 | |||
541 | sack->frame_number = tsn->frame_number = pinfo->num; |
||
542 | } |
||
543 | if ((tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) || (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_ACK_CHUNK_ID)) |
||
544 | { |
||
545 | info->min_tsn1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_INITIAL_TSN_OFFSET); |
||
546 | info->verification_tag2 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_INITIATE_TAG_OFFSET); |
||
547 | info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); |
||
548 | info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); |
||
549 | info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0], INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); |
||
550 | for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++) |
||
551 | { |
||
552 | type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); |
||
553 | if (type == IPV4ADDRESS_PARAMETER_ID) |
||
554 | { |
||
555 | store = (address *)g_malloc(sizeof (address)); |
||
556 | alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET); |
||
557 | info = add_address(store, info, info->direction); |
||
558 | } |
||
559 | else if (type == IPV6ADDRESS_PARAMETER_ID) |
||
560 | { |
||
561 | store = (address *)g_malloc(sizeof (address)); |
||
562 | alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET); |
||
563 | info = add_address(store, info, info->direction); |
||
564 | } |
||
565 | } |
||
566 | |||
567 | if (tvb_get_guint8(sctp_info->tvb[0],0) == SCTP_INIT_CHUNK_ID) |
||
568 | { |
||
569 | info->init = TRUE; |
||
570 | } |
||
571 | else |
||
572 | { |
||
573 | info->initack_dir = 1; |
||
574 | info->initack = TRUE; |
||
575 | } |
||
576 | |||
577 | idx = tvb_get_guint8(sctp_info->tvb[0],0); |
||
578 | if (!IS_SCTP_CHUNK_TYPE(idx)) |
||
579 | idx = OTHER_CHUNKS_INDEX; |
||
580 | |||
581 | info->chunk_count[idx]++; |
||
582 | info->ep1_chunk_count[idx]++; |
||
583 | info = add_chunk_count(&tmp_info.src, info, 1, idx); |
||
584 | } |
||
585 | else |
||
586 | { |
||
587 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_CHUNK_ID) && |
||
588 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) && |
||
589 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) && |
||
590 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) && |
||
591 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) && |
||
592 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) && |
||
593 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID)) |
||
594 | { |
||
595 | tsn = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
596 | sack = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
597 | tsn->tsns = NULL; |
||
598 | sack->tsns = NULL; |
||
599 | tsn->first_tsn = 0; |
||
600 | sack->first_tsn = 0; |
||
601 | } |
||
602 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) |
||
603 | { |
||
604 | idx = tvb_get_guint8(sctp_info->tvb[0],0); |
||
605 | if (!IS_SCTP_CHUNK_TYPE(idx)) |
||
606 | idx = OTHER_CHUNKS_INDEX; |
||
607 | |||
608 | info->chunk_count[idx]++; |
||
609 | info->ep1_chunk_count[idx]++; |
||
610 | info = add_chunk_count(&tmp_info.src, info, 1, idx); |
||
611 | |||
612 | if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) || |
||
613 | (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID)) |
||
614 | { |
||
615 | datachunk = TRUE; |
||
616 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { |
||
617 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; |
||
618 | } else { |
||
619 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; |
||
620 | } |
||
621 | info->n_data_chunks++; |
||
622 | info->n_data_bytes+=length; |
||
623 | info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; |
||
624 | } |
||
625 | if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID)) |
||
626 | { |
||
627 | forwardchunk = TRUE; |
||
628 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); |
||
629 | info->n_forward_chunks++; |
||
630 | } |
||
631 | if (datachunk || forwardchunk) |
||
632 | { |
||
633 | |||
634 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET); |
||
635 | if (tsnumber < info->min_tsn1) |
||
636 | info->min_tsn1 = tsnumber; |
||
637 | if (tsnumber > info->max_tsn1) |
||
638 | { |
||
639 | if (datachunk) |
||
640 | { |
||
641 | info->n_data_chunks_ep1++; |
||
642 | info->n_data_bytes_ep1+=length; |
||
643 | } |
||
644 | else |
||
645 | info->n_forward_chunks_ep1++; |
||
646 | info->max_tsn1 = tsnumber; |
||
647 | } |
||
648 | if (tsn->first_tsn == 0) |
||
649 | tsn->first_tsn = tsnumber; |
||
650 | if (datachunk) |
||
651 | { |
||
652 | t_s_n = (guint8 *)g_malloc(16); |
||
653 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16); |
||
654 | } |
||
655 | else |
||
656 | { |
||
657 | t_s_n = (guint8 *)g_malloc(length); |
||
658 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); |
||
659 | } |
||
660 | tsn->tsns = g_list_append(tsn->tsns, t_s_n); |
||
661 | tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort)); |
||
662 | tsn_s->tsnumber = tsnumber; |
||
663 | tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
664 | tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
665 | tsn_s->offset = 0; |
||
666 | tsn_s->framenumber = framenumber; |
||
667 | if (datachunk) |
||
668 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { |
||
669 | tsn_s->length = length - DATA_CHUNK_HEADER_LENGTH; |
||
670 | } else { |
||
671 | tsn_s->length = length - I_DATA_CHUNK_HEADER_LENGTH; |
||
672 | } |
||
673 | else |
||
674 | tsn_s->length = length; |
||
675 | if (tsn->secs < info->min_secs) |
||
676 | { |
||
677 | info->min_secs = tsn->secs; |
||
678 | info->min_usecs = tsn->usecs; |
||
679 | } |
||
680 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
681 | info->min_usecs = tsn->usecs; |
||
682 | |||
683 | if (tsn->secs > info->max_secs) |
||
684 | { |
||
685 | info->max_secs = tsn->secs; |
||
686 | info->max_usecs = tsn->usecs; |
||
687 | } |
||
688 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
689 | info->max_usecs = tsn->usecs; |
||
690 | g_ptr_array_add(info->sort_tsn1, tsn_s); |
||
691 | info->n_array_tsn1++; |
||
692 | } |
||
693 | if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) || |
||
694 | (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID) ) |
||
695 | { |
||
696 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); |
||
697 | if (tsnumber < info->min_tsn2) |
||
698 | info->min_tsn2 = tsnumber; |
||
699 | if (tsnumber > info->max_tsn2) |
||
700 | info->max_tsn2 = tsnumber; |
||
701 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); |
||
702 | if (sack->first_tsn == 0) |
||
703 | sack->first_tsn = tsnumber; |
||
704 | t_s_n = (guint8 *)g_malloc(length); |
||
705 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); |
||
706 | sack->tsns = g_list_append(sack->tsns, t_s_n); |
||
707 | sackchunk = TRUE; |
||
708 | tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort)); |
||
709 | tsn_s->tsnumber = tsnumber; |
||
710 | tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
711 | tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
712 | tsn_s->offset = 0; |
||
713 | tsn_s->framenumber = framenumber; |
||
714 | tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); |
||
715 | if (tsn_s->length > info->max_window1) |
||
716 | info->max_window1 = tsn_s->length; |
||
717 | if (tsn->secs < info->min_secs) |
||
718 | { |
||
719 | info->min_secs = tsn->secs; |
||
720 | info->min_usecs = tsn->usecs; |
||
721 | } |
||
722 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
723 | info->min_usecs = tsn->usecs; |
||
724 | |||
725 | if (tsn->secs > info->max_secs) |
||
726 | { |
||
727 | info->max_secs = tsn->secs; |
||
728 | info->max_usecs = tsn->usecs; |
||
729 | } |
||
730 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
731 | info->max_usecs = tsn->usecs; |
||
732 | g_ptr_array_add(info->sort_sack2, tsn_s); |
||
733 | info->n_sack_chunks_ep2++; |
||
734 | } |
||
735 | } |
||
736 | } |
||
737 | if (info->verification_tag1 != 0 || info->verification_tag2 != 0) |
||
738 | { |
||
739 | guint32 *number; |
||
740 | store = (address *)g_malloc(sizeof (address)); |
||
741 | store->type = tmp_info.src.type; |
||
742 | store->len = tmp_info.src.len; |
||
743 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
744 | memcpy(addr,(tmp_info.src.data),tmp_info.src.len); |
||
745 | store->data = addr; |
||
746 | info = add_address(store, info, info->direction); |
||
747 | store = (address *)g_malloc(sizeof (address)); |
||
748 | store->type = tmp_info.dst.type; |
||
749 | store->len = tmp_info.dst.len; |
||
750 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
751 | memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len); |
||
752 | store->data = addr; |
||
753 | if (info->direction == 1) |
||
754 | info = add_address(store, info, 2); |
||
755 | else |
||
756 | info = add_address(store, info, 1); |
||
757 | number = (guint32 *)g_malloc(sizeof(guint32)); |
||
758 | *number = pinfo->num; |
||
759 | info->frame_numbers=g_list_prepend(info->frame_numbers,number); |
||
760 | if (datachunk || forwardchunk) |
||
761 | info->tsn1 = g_list_prepend(info->tsn1, tsn); |
||
762 | if (sackchunk == TRUE) |
||
763 | info->sack2 = g_list_prepend(info->sack2, sack); |
||
764 | sctp_tapinfo_struct.assoc_info_list = g_list_append(sctp_tapinfo_struct.assoc_info_list, info); |
||
765 | } |
||
766 | else |
||
767 | { |
||
768 | gchar* tmp_str; |
||
769 | error = (sctp_error_info_t *)g_malloc(sizeof(sctp_error_info_t)); |
||
770 | error->frame_number = pinfo->num; |
||
771 | error->chunk_info[0] = '\0'; |
||
772 | if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) |
||
773 | { |
||
774 | tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[0],0),chunk_type_values,"Reserved (%d)"); |
||
775 | g_strlcpy(error->chunk_info, tmp_str, 200); |
||
776 | wmem_free(NULL, tmp_str); |
||
777 | } |
||
778 | else |
||
779 | { |
||
780 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) |
||
781 | { |
||
782 | tmp_str = val_to_str_wmem(NULL, tvb_get_guint8(sctp_info->tvb[chunk_number],0),chunk_type_values,"Reserved (%d)"); |
||
783 | g_strlcat(error->chunk_info, tmp_str, 200); |
||
784 | wmem_free(NULL, tmp_str); |
||
785 | } |
||
786 | } |
||
787 | error->info_text = "INFOS"; |
||
788 | info->error_info_list = g_list_append(info->error_info_list, error); |
||
789 | } |
||
790 | } |
||
791 | } /* endif (!info) */ |
||
792 | else |
||
793 | { |
||
794 | guint32 *number; |
||
795 | info->direction = sctp_info->direction; |
||
796 | |||
797 | if (info->verification_tag1 == 0 && info->verification_tag2 != sctp_info->verification_tag) { |
||
798 | info->verification_tag1 = sctp_info->verification_tag; |
||
799 | } else if (info->verification_tag2 == 0 && info->verification_tag1 != sctp_info->verification_tag) { |
||
800 | info->verification_tag2 = sctp_info->verification_tag; |
||
801 | } |
||
802 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) || |
||
803 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) || |
||
804 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || |
||
805 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || |
||
806 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || |
||
807 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || |
||
808 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) |
||
809 | { |
||
810 | |||
811 | tsn = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
812 | sack = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
813 | tsn->tsns = NULL; |
||
814 | tsn->first_tsn = 0; |
||
815 | sack->tsns = NULL; |
||
816 | sack->first_tsn = 0; |
||
817 | sack->src.type = tsn->src.type = tmp_info.src.type; |
||
818 | sack->src.len = tsn->src.len = tmp_info.src.len; |
||
819 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
820 | memcpy(addr, tmp_info.src.data, tmp_info.src.len); |
||
821 | tsn->src.data = addr; |
||
822 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
823 | memcpy(addr, tmp_info.src.data, tmp_info.src.len); |
||
824 | sack->src.data = addr; |
||
825 | sack->dst.type = tsn->dst.type = tmp_info.dst.type; |
||
826 | sack->dst.len = tsn->dst.len = tmp_info.dst.len; |
||
827 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
828 | memcpy(addr, tmp_info.dst.data, tmp_info.dst.len); |
||
829 | tsn->dst.data = addr; |
||
830 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
831 | memcpy(addr, tmp_info.dst.data, tmp_info.dst.len); |
||
832 | sack->dst.data = addr; |
||
833 | sack->secs=tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
834 | sack->usecs=tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
835 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_DATA_CHUNK_ID) || |
||
836 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_I_DATA_CHUNK_ID) || |
||
837 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_SACK_CHUNK_ID) || |
||
838 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_NR_SACK_CHUNK_ID) || |
||
839 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_FORWARD_TSN_CHUNK_ID)) |
||
840 | { |
||
841 | if (tsn->secs < info->min_secs) |
||
842 | { |
||
843 | info->min_secs = tsn->secs; |
||
844 | info->min_usecs = tsn->usecs; |
||
845 | } |
||
846 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
847 | info->min_usecs = tsn->usecs; |
||
848 | |||
849 | if (tsn->secs > info->max_secs) |
||
850 | { |
||
851 | info->max_secs = tsn->secs; |
||
852 | info->max_usecs = tsn->usecs; |
||
853 | } |
||
854 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
855 | info->max_usecs = tsn->usecs; |
||
856 | } |
||
857 | sack->frame_number = tsn->frame_number = pinfo->num; |
||
858 | } |
||
859 | number = (guint32 *)g_malloc(sizeof(guint32)); |
||
860 | *number = pinfo->num; |
||
861 | info->frame_numbers=g_list_prepend(info->frame_numbers,number); |
||
862 | |||
863 | store = (address *)g_malloc(sizeof (address)); |
||
864 | store->type = tmp_info.src.type; |
||
865 | store->len = tmp_info.src.len; |
||
866 | addr = (guint8 *)g_malloc(tmp_info.src.len); |
||
867 | memcpy(addr,(tmp_info.src.data),tmp_info.src.len); |
||
868 | store->data = addr; |
||
869 | |||
870 | if (info->direction == 1) |
||
871 | info = add_address(store, info, 1); |
||
872 | else if (info->direction == 2) |
||
873 | info = add_address(store, info, 2); |
||
874 | |||
875 | store = (address *)g_malloc(sizeof (address)); |
||
876 | store->type = tmp_info.dst.type; |
||
877 | store->len = tmp_info.dst.len; |
||
878 | addr = (guint8 *)g_malloc(tmp_info.dst.len); |
||
879 | memcpy(addr,(tmp_info.dst.data),tmp_info.dst.len); |
||
880 | store->data = addr; |
||
881 | |||
882 | if (info->direction == 1) |
||
883 | info = add_address(store, info, 2); |
||
884 | else if (info->direction == 2) |
||
885 | info = add_address(store, info, 1); |
||
886 | |||
887 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) || |
||
888 | ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID)) |
||
889 | { |
||
890 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], INIT_CHUNK_INITIAL_TSN_OFFSET); |
||
891 | |||
892 | if (info->direction == 2) |
||
893 | { |
||
894 | if (tsnumber < info->min_tsn2) |
||
895 | info->min_tsn2 = tsnumber; |
||
896 | if (tsnumber > info->max_tsn2) |
||
897 | info->max_tsn2 = tsnumber; |
||
898 | info->instream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); |
||
899 | info->outstream2 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); |
||
900 | info->arwnd2 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); |
||
901 | info->tsn2 = g_list_prepend(info->tsn2, tsn); |
||
902 | } |
||
903 | else if (info->direction == 1) |
||
904 | { |
||
905 | if (tsnumber < info->min_tsn1) |
||
906 | info->min_tsn1 = tsnumber; |
||
907 | if (tsnumber > info->max_tsn1) |
||
908 | info->max_tsn1 = tsnumber; |
||
909 | info->instream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_INBOUND_STREAMS_OFFSET); |
||
910 | info->outstream1 = tvb_get_ntohs(sctp_info->tvb[0],INIT_CHUNK_NUMBER_OF_OUTBOUND_STREAMS_OFFSET); |
||
911 | info->arwnd1 = tvb_get_ntohl(sctp_info->tvb[0],INIT_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); |
||
912 | info->tsn1 = g_list_prepend(info->tsn1, tsn); |
||
913 | } |
||
914 | |||
915 | idx = tvb_get_guint8(sctp_info->tvb[0],0); |
||
916 | if (!IS_SCTP_CHUNK_TYPE(idx)) |
||
917 | idx = OTHER_CHUNKS_INDEX; |
||
918 | info->chunk_count[idx]++; |
||
919 | if (info->direction == 1) |
||
920 | info->ep1_chunk_count[idx]++; |
||
921 | else |
||
922 | info->ep2_chunk_count[idx]++; |
||
923 | info = add_chunk_count(&tmp_info.src, info, info->direction, idx); |
||
924 | for (chunk_number = 1; chunk_number < sctp_info->number_of_tvbs; chunk_number++) |
||
925 | { |
||
926 | type = tvb_get_ntohs(sctp_info->tvb[chunk_number],0); |
||
927 | if (type == IPV4ADDRESS_PARAMETER_ID) |
||
928 | { |
||
929 | store = (address *)g_malloc(sizeof (address)); |
||
930 | alloc_address_tvb(NULL, store, AT_IPv4, 4, sctp_info->tvb[chunk_number], IPV4_ADDRESS_OFFSET); |
||
931 | info = add_address(store, info, info->direction); |
||
932 | } |
||
933 | else if (type == IPV6ADDRESS_PARAMETER_ID) |
||
934 | { |
||
935 | store = (address *)g_malloc(sizeof (address)); |
||
936 | alloc_address_tvb(NULL, store, AT_IPv6, 16, sctp_info->tvb[chunk_number], IPV6_ADDRESS_OFFSET); |
||
937 | info = add_address(store, info, info->direction); |
||
938 | } |
||
939 | } |
||
940 | if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_ACK_CHUNK_ID) |
||
941 | { |
||
942 | info->initack = TRUE; |
||
943 | info->initack_dir = info->direction; |
||
944 | } |
||
945 | else if ((tvb_get_guint8(sctp_info->tvb[0],0)) == SCTP_INIT_CHUNK_ID) |
||
946 | { |
||
947 | info->init = TRUE; |
||
948 | } |
||
949 | } |
||
950 | else |
||
951 | { |
||
952 | if (((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_INIT_ACK_CHUNK_ID) && |
||
953 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_DATA_CHUNK_ID) && |
||
954 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_I_DATA_CHUNK_ID) && |
||
955 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_SACK_CHUNK_ID) && |
||
956 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_NR_SACK_CHUNK_ID) && |
||
957 | ((tvb_get_guint8(sctp_info->tvb[0],0)) != SCTP_FORWARD_TSN_CHUNK_ID)) |
||
958 | { |
||
959 | sack = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
960 | sack->tsns = NULL; |
||
961 | sack->first_tsn = 0; |
||
962 | tsn = (tsn_t *)g_malloc(sizeof(tsn_t)); |
||
963 | tsn->tsns = NULL; |
||
964 | tsn->first_tsn = 0; |
||
965 | } |
||
966 | for (chunk_number = 0; chunk_number < sctp_info->number_of_tvbs; chunk_number++) |
||
967 | { |
||
968 | idx = tvb_get_guint8(sctp_info->tvb[chunk_number],0); |
||
969 | if (!IS_SCTP_CHUNK_TYPE(idx)) |
||
970 | idx = OTHER_CHUNKS_INDEX; |
||
971 | |||
972 | info->chunk_count[idx]++; |
||
973 | if (info->direction == 1) |
||
974 | info->ep1_chunk_count[idx]++; |
||
975 | else |
||
976 | info->ep2_chunk_count[idx]++; |
||
977 | info = add_chunk_count(&tmp_info.src, info,info->direction, idx); |
||
978 | |||
979 | if ((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) || |
||
980 | (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_I_DATA_CHUNK_ID)) |
||
981 | datachunk = TRUE; |
||
982 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_FORWARD_TSN_CHUNK_ID) |
||
983 | forwardchunk = TRUE; |
||
984 | if ((datachunk || forwardchunk) && tsn != NULL) |
||
985 | { |
||
986 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], DATA_CHUNK_TSN_OFFSET); |
||
987 | if (tsn->first_tsn == 0) |
||
988 | tsn->first_tsn = tsnumber; |
||
989 | if (datachunk) |
||
990 | { |
||
991 | t_s_n = (guint8 *)g_malloc(16); |
||
992 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, 16); |
||
993 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { |
||
994 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET)-DATA_CHUNK_HEADER_LENGTH; |
||
995 | } else { |
||
996 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; |
||
997 | } |
||
998 | info->n_data_chunks++; |
||
999 | info->n_data_bytes+=length; |
||
1000 | } |
||
1001 | else |
||
1002 | { |
||
1003 | length=tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); |
||
1004 | t_s_n = (guint8 *)g_malloc(length); |
||
1005 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); |
||
1006 | info->n_forward_chunks++; |
||
1007 | } |
||
1008 | tsn->tsns = g_list_append(tsn->tsns, t_s_n); |
||
1009 | |||
1010 | tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort)); |
||
1011 | tsn_s->tsnumber = tsnumber; |
||
1012 | tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
1013 | tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
1014 | tsn_s->offset = 0; |
||
1015 | tsn_s->framenumber = framenumber; |
||
1016 | tsn_s->length = length; |
||
1017 | |||
1018 | if (tsn->secs < info->min_secs) |
||
1019 | { |
||
1020 | info->min_secs = tsn->secs; |
||
1021 | info->min_usecs = tsn->usecs; |
||
1022 | } |
||
1023 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
1024 | info->min_usecs = tsn->usecs; |
||
1025 | |||
1026 | if (tsn->secs > info->max_secs) |
||
1027 | { |
||
1028 | info->max_secs = tsn->secs; |
||
1029 | info->max_usecs = tsn->usecs; |
||
1030 | } |
||
1031 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
1032 | info->max_usecs = tsn->usecs; |
||
1033 | |||
1034 | if (info->direction == 1) |
||
1035 | { |
||
1036 | if(tsnumber < info->min_tsn1) |
||
1037 | info->min_tsn1 = tsnumber; |
||
1038 | if ((info->init == TRUE || (info->initack == TRUE && info->initack_dir == 1))&& tsnumber >= info->min_tsn1 && tsnumber <= info->max_tsn1) |
||
1039 | { |
||
1040 | if (datachunk) |
||
1041 | { |
||
1042 | info->n_data_chunks_ep1++; |
||
1043 | info->n_data_bytes_ep1 += length; |
||
1044 | } |
||
1045 | else if (forwardchunk) |
||
1046 | { |
||
1047 | info->n_forward_chunks_ep1++; |
||
1048 | } |
||
1049 | } |
||
1050 | if(tsnumber > info->max_tsn1) |
||
1051 | { |
||
1052 | info->max_tsn1 = tsnumber; |
||
1053 | if (datachunk) |
||
1054 | { |
||
1055 | info->n_data_chunks_ep1++; |
||
1056 | info->n_data_bytes_ep1 += length; |
||
1057 | } |
||
1058 | else if (forwardchunk) |
||
1059 | { |
||
1060 | info->n_forward_chunks_ep1++; |
||
1061 | } |
||
1062 | } |
||
1063 | if (datachunk) |
||
1064 | { |
||
1065 | if (info->init == FALSE) |
||
1066 | info->outstream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; |
||
1067 | if (info->initack == FALSE) |
||
1068 | info->instream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; |
||
1069 | } |
||
1070 | |||
1071 | g_ptr_array_add(info->sort_tsn1, tsn_s); |
||
1072 | info->n_array_tsn1++; |
||
1073 | } |
||
1074 | else if (info->direction == 2) |
||
1075 | { |
||
1076 | |||
1077 | if(tsnumber < info->min_tsn2) |
||
1078 | info->min_tsn2 = tsnumber; |
||
1079 | |||
1080 | if ((info->initack == TRUE && info->initack_dir == 2)&& tsnumber >= info->min_tsn2 && tsnumber <= info->max_tsn2) |
||
1081 | { |
||
1082 | if (datachunk) |
||
1083 | { |
||
1084 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { |
||
1085 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; |
||
1086 | } else { |
||
1087 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; |
||
1088 | } |
||
1089 | info->n_data_chunks_ep2++; |
||
1090 | info->n_data_bytes_ep2+=length; |
||
1091 | } |
||
1092 | else if (forwardchunk) |
||
1093 | { |
||
1094 | info->n_forward_chunks_ep2++; |
||
1095 | } |
||
1096 | } |
||
1097 | if (tsnumber > info->max_tsn2) |
||
1098 | { |
||
1099 | info->max_tsn2 = tsnumber; |
||
1100 | if (datachunk) |
||
1101 | { |
||
1102 | if (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_DATA_CHUNK_ID) { |
||
1103 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - DATA_CHUNK_HEADER_LENGTH; |
||
1104 | } else { |
||
1105 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET) - I_DATA_CHUNK_HEADER_LENGTH; |
||
1106 | } |
||
1107 | info->n_data_chunks_ep2++; |
||
1108 | info->n_data_bytes_ep2+=length; |
||
1109 | } |
||
1110 | else if (forwardchunk) |
||
1111 | { |
||
1112 | info->n_forward_chunks_ep2++; |
||
1113 | } |
||
1114 | } |
||
1115 | if (datachunk) |
||
1116 | { |
||
1117 | if (info->init == FALSE) |
||
1118 | info->instream1 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; |
||
1119 | if (info->initack == FALSE) |
||
1120 | info->outstream2 = tvb_get_ntohs((sctp_info->tvb)[chunk_number], DATA_CHUNK_STREAM_ID_OFFSET)+1; |
||
1121 | } |
||
1122 | |||
1123 | g_ptr_array_add(info->sort_tsn2, tsn_s); |
||
1124 | info->n_array_tsn2++; |
||
1125 | } |
||
1126 | } |
||
1127 | else if (((tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_SACK_CHUNK_ID) || |
||
1128 | (tvb_get_guint8(sctp_info->tvb[chunk_number],0) == SCTP_NR_SACK_CHUNK_ID)) && |
||
1129 | sack != NULL) |
||
1130 | { |
||
1131 | tsnumber = tvb_get_ntohl((sctp_info->tvb)[chunk_number], SACK_CHUNK_CUMULATIVE_TSN_ACK_OFFSET); |
||
1132 | length = tvb_get_ntohs(sctp_info->tvb[chunk_number], CHUNK_LENGTH_OFFSET); |
||
1133 | |||
1134 | if (sack->first_tsn == 0) |
||
1135 | sack->first_tsn = tsnumber; |
||
1136 | |||
1137 | t_s_n = (guint8 *)g_malloc(length); |
||
1138 | tvb_memcpy(sctp_info->tvb[chunk_number], (guint8 *)(t_s_n),0, length); |
||
1139 | sack->tsns = g_list_append(sack->tsns, t_s_n); |
||
1140 | sackchunk = TRUE; |
||
1141 | tsn_s = (struct tsn_sort *)g_malloc(sizeof(struct tsn_sort)); |
||
1142 | tsn_s->tsnumber = tsnumber; |
||
1143 | tsn_s->secs = tsn->secs = (guint32)pinfo->rel_ts.secs; |
||
1144 | tsn_s->usecs = tsn->usecs = (guint32)pinfo->rel_ts.nsecs/1000; |
||
1145 | tsn_s->offset = 0; |
||
1146 | tsn_s->framenumber = framenumber; |
||
1147 | tsn_s->length = tvb_get_ntohl(sctp_info->tvb[chunk_number], SACK_CHUNK_ADV_REC_WINDOW_CREDIT_OFFSET); |
||
1148 | |||
1149 | if (tsn->secs < info->min_secs) |
||
1150 | { |
||
1151 | info->min_secs = tsn->secs; |
||
1152 | info->min_usecs = tsn->usecs; |
||
1153 | } |
||
1154 | else if (tsn->secs == info->min_secs && tsn->usecs < info->min_usecs) |
||
1155 | info->min_usecs = tsn->usecs; |
||
1156 | |||
1157 | if (tsn->secs > info->max_secs) |
||
1158 | { |
||
1159 | info->max_secs = tsn->secs; |
||
1160 | info->max_usecs = tsn->usecs; |
||
1161 | } |
||
1162 | else if (tsn->secs == info->max_secs && tsn->usecs > info->max_usecs) |
||
1163 | info->max_usecs = tsn->usecs; |
||
1164 | |||
1165 | |||
1166 | if (info->direction == 2) |
||
1167 | { |
||
1168 | if(tsnumber < info->min_tsn1) |
||
1169 | info->min_tsn1 = tsnumber; |
||
1170 | if(tsnumber > info->max_tsn1) |
||
1171 | info->max_tsn1 = tsnumber; |
||
1172 | if (tsn_s->length > info->max_window1) |
||
1173 | info->max_window1 = tsn_s->length; |
||
1174 | g_ptr_array_add(info->sort_sack1, tsn_s); |
||
1175 | info->n_sack_chunks_ep1++; |
||
1176 | } |
||
1177 | else if (info->direction == 1) |
||
1178 | { |
||
1179 | |||
1180 | if(tsnumber < info->min_tsn2) |
||
1181 | info->min_tsn2 = tsnumber; |
||
1182 | if(tsnumber > info->max_tsn2) |
||
1183 | info->max_tsn2 = tsnumber; |
||
1184 | if (tsn_s->length > info->max_window2) |
||
1185 | info->max_window2 = tsn_s->length; |
||
1186 | g_ptr_array_add(info->sort_sack2, tsn_s); |
||
1187 | info->n_sack_chunks_ep2++; |
||
1188 | } |
||
1189 | |||
1190 | } |
||
1191 | } |
||
1192 | |||
1193 | } |
||
1194 | if (datachunk || forwardchunk) |
||
1195 | { |
||
1196 | if (info->direction == 1) |
||
1197 | info->tsn1 = g_list_prepend(info->tsn1, tsn); |
||
1198 | else if (info->direction == 2) |
||
1199 | info->tsn2 = g_list_prepend(info->tsn2, tsn); |
||
1200 | } |
||
1201 | if (sackchunk == TRUE) |
||
1202 | { |
||
1203 | if (info->direction == 1) |
||
1204 | info->sack2 = g_list_prepend(info->sack2, sack); |
||
1205 | else if(info->direction == 2) |
||
1206 | info->sack1 = g_list_prepend(info->sack1, sack); |
||
1207 | } |
||
1208 | info->n_tvbs += sctp_info->number_of_tvbs; |
||
1209 | sctp_tapinfo_struct.sum_tvbs += sctp_info->number_of_tvbs; |
||
1210 | info = calc_checksum(sctp_info, info); |
||
1211 | info->n_packets++; |
||
1212 | } |
||
1213 | return TRUE; |
||
1214 | } |
||
1215 | |||
1216 | |||
1217 | /****************************************************************************/ |
||
1218 | void |
||
1219 | remove_tap_listener_sctp_stat(void) |
||
1220 | { |
||
1221 | if (sctp_tapinfo_struct.is_registered) { |
||
1222 | remove_tap_listener(&sctp_tapinfo_struct); |
||
1223 | sctp_tapinfo_struct.is_registered = FALSE; |
||
1224 | } |
||
1225 | } |
||
1226 | |||
1227 | |||
1228 | void |
||
1229 | sctp_stat_scan(void) |
||
1230 | { |
||
1231 | if (!sctp_tapinfo_struct.is_registered) |
||
1232 | register_tap_listener_sctp_stat(); |
||
1233 | } |
||
1234 | |||
1235 | const sctp_allassocs_info_t * |
||
1236 | sctp_stat_get_info(void) |
||
1237 | { |
||
1238 | return &sctp_tapinfo_struct; |
||
1239 | } |
||
1240 | |||
1241 | |||
1242 | void |
||
1243 | register_tap_listener_sctp_stat(void) |
||
1244 | { |
||
1245 | GString *error_string; |
||
1246 | |||
1247 | if (!sctp_tapinfo_struct.is_registered) |
||
1248 | { |
||
1249 | if ((error_string = register_tap_listener("sctp", &sctp_tapinfo_struct, NULL, 0, reset, packet, NULL))) { |
||
1250 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str); |
||
1251 | g_string_free(error_string, TRUE); |
||
1252 | return; |
||
1253 | } |
||
1254 | sctp_tapinfo_struct.is_registered=TRUE; |
||
1255 | } |
||
1256 | } |
||
1257 | |||
1258 | /* |
||
1259 | * Editor modelines - http://www.wireshark.org/tools/modelines.html |
||
1260 | * |
||
1261 | * Local variables: |
||
1262 | * c-basic-offset: 8 |
||
1263 | * tab-width: 8 |
||
1264 | * indent-tabs-mode: t |
||
1265 | * End: |
||
1266 | * |
||
1267 | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
||
1268 | * :indentSize=8:tabSize=8:noTabs=false: |
||
1269 | */ |