Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / packet_range.c
blob5167927a6123fda1e2b5d139293f996b13f6b48d
1 /* packet_range.c
2 * Packet range routines (save, print, ...)
4 * Dick Gooris <gooris@lucent.com>
5 * Ulf Lamping <ulf.lamping@web.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <string.h>
18 #include <glib.h>
20 #include <epan/frame_data.h>
22 #include "packet_range.h"
24 #include <wsutil/ws_assert.h>
26 static void
27 depended_frames_add(GHashTable* depended_table, frame_data_sequence *frames, frame_data *frame)
29 if (g_hash_table_add(depended_table, GUINT_TO_POINTER(frame->num)) && frame->dependent_frames) {
30 GHashTableIter iter;
31 void *key;
32 frame_data *depended_fd;
33 g_hash_table_iter_init(&iter, frame->dependent_frames);
34 while (g_hash_table_iter_next(&iter, &key, NULL)) {
35 depended_fd = frame_data_sequence_find(frames, GPOINTER_TO_UINT(key));
36 depended_frames_add(depended_table, frames, depended_fd);
41 /* (re-)calculate the packet counts (except the user specified range) */
42 static void packet_range_calc(packet_range_t *range) {
43 uint32_t framenum;
44 uint32_t mark_low;
45 uint32_t mark_high;
46 uint32_t displayed_mark_low;
47 uint32_t displayed_mark_high;
48 frame_data *packet;
52 mark_low = 0;
53 mark_high = 0;
54 range->mark_range_cnt = 0;
55 range->ignored_cnt = 0;
56 range->ignored_selection_range_cnt = 0;
57 range->ignored_marked_cnt = 0;
58 range->ignored_mark_range_cnt = 0;
59 range->ignored_user_range_cnt = 0;
61 displayed_mark_low = 0;
62 displayed_mark_high = 0;
64 range->displayed_cnt = 0;
65 range->displayed_marked_cnt = 0;
66 range->displayed_mark_range_cnt = 0;
67 range->displayed_plus_dependents_cnt = 0;
68 range->displayed_mark_range_plus_depends_cnt = 0;
69 range->displayed_ignored_cnt = 0;
70 range->displayed_ignored_selection_range_cnt = 0;
71 range->displayed_ignored_marked_cnt = 0;
72 range->displayed_ignored_mark_range_cnt = 0;
73 range->displayed_ignored_user_range_cnt = 0;
75 ws_assert(range->cf != NULL);
77 /* XXX - this doesn't work unless you have a full set of frame_data
78 * structures for all packets in the capture, which is not,
79 * for example, the case when TShark is doing a one-pass
80 * read of a file or a live capture.
82 * It's also horribly slow on large captures, causing it to
83 * take a long time for the Save As dialog to pop up, for
84 * example. We should really keep these statistics in
85 * the capture_file structure, updating them whenever we
86 * filter the display, etc..
88 if (range->cf->provider.frames != NULL) {
89 /* The next for-loop is used to obtain the amount of packets
90 * to be processed and is used to present the information in
91 * the Save/Print As widget.
92 * We have different types of ranges: All the packets, the number
93 * of packets of a marked range, a single packet, and a user specified
94 * packet range. The last one is not calculated here since this
95 * data must be entered in the widget by the user.
98 for(framenum = 1; framenum <= range->cf->count; framenum++) {
99 packet = frame_data_sequence_find(range->cf->provider.frames, framenum);
101 if (range->cf->current_frame == packet && range->selection_range == NULL ) {
102 range_add_value(NULL, &(range->selection_range), framenum);
104 if (packet->passed_dfilter) {
105 range->displayed_cnt++;
107 if (packet->passed_dfilter ||
108 packet->dependent_of_displayed) {
109 range->displayed_plus_dependents_cnt++;
111 if (packet->marked) {
112 if (packet->ignored) {
113 range->ignored_marked_cnt++;
115 if (packet->passed_dfilter) {
116 range->displayed_marked_cnt++;
117 if (packet->ignored) {
118 range->displayed_ignored_marked_cnt++;
120 if (displayed_mark_low == 0) {
121 displayed_mark_low = framenum;
123 if (framenum > displayed_mark_high) {
124 displayed_mark_high = framenum;
126 depended_frames_add(range->displayed_marked_plus_depends, range->cf->provider.frames, packet);
129 if (mark_low == 0) {
130 mark_low = framenum;
132 if (framenum > mark_high) {
133 mark_high = framenum;
135 depended_frames_add(range->marked_plus_depends, range->cf->provider.frames, packet);
137 if (packet->ignored) {
138 range->ignored_cnt++;
139 if (packet->passed_dfilter) {
140 range->displayed_ignored_cnt++;
145 for(framenum = 1; framenum <= range->cf->count; framenum++) {
146 packet = frame_data_sequence_find(range->cf->provider.frames, framenum);
148 if (framenum >= mark_low &&
149 framenum <= mark_high)
151 range->mark_range_cnt++;
152 if (packet->ignored) {
153 range->ignored_mark_range_cnt++;
155 depended_frames_add(range->mark_range_plus_depends, range->cf->provider.frames, packet);
158 if (framenum >= displayed_mark_low &&
159 framenum <= displayed_mark_high)
161 if (packet->passed_dfilter) {
162 range->displayed_mark_range_cnt++;
163 if (packet->ignored) {
164 range->displayed_ignored_mark_range_cnt++;
167 depended_frames_add(range->displayed_mark_range_plus_depends, range->cf->provider.frames, packet);
170 range->marked_plus_depends_cnt = g_hash_table_size(range->marked_plus_depends);
171 range->displayed_marked_plus_depends_cnt = g_hash_table_size(range->displayed_marked_plus_depends);
172 range->mark_range_plus_depends_cnt = g_hash_table_size(range->mark_range_plus_depends);
173 range->displayed_mark_range_plus_depends_cnt = g_hash_table_size(range->displayed_mark_range_plus_depends);
178 /* (re-)calculate the user specified packet range counts */
179 static void packet_range_calc_user(packet_range_t *range) {
180 uint32_t framenum;
181 frame_data *packet;
183 range->user_range_cnt = 0;
184 range->ignored_user_range_cnt = 0;
185 range->displayed_user_range_cnt = 0;
186 range->displayed_user_range_plus_depends_cnt = 0;
187 range->displayed_ignored_user_range_cnt = 0;
189 ws_assert(range->cf != NULL);
191 /* XXX - this doesn't work unless you have a full set of frame_data
192 * structures for all packets in the capture, which is not,
193 * for example, the case when TShark is doing a one-pass
194 * read of a file or a live capture.
196 * It's also horribly slow on large captures, causing it to
197 * take a long time for the Save As dialog to pop up, for
198 * example. This obviously can't be kept in the capture_file
199 * structure and recalculated whenever we filter the display
200 * or mark frames as ignored, as the results of this depend
201 * on what the user specifies. In some cases, limiting the
202 * frame_data structures at which we look to the ones specified
203 * by the user might help, but if most of the frames are in
204 * the range, that won't help. In that case, if we could
205 * examine the *complement* of the range, and *subtract* them
206 * from the statistics for the capture as a whole, that might
207 * help, but if the user specified about *half* the packets in
208 * the range, that won't help, either.
210 if (range->cf->provider.frames != NULL) {
211 for(framenum = 1; framenum <= range->cf->count; framenum++) {
212 packet = frame_data_sequence_find(range->cf->provider.frames, framenum);
214 if (value_is_in_range(range->user_range, framenum)) {
215 range->user_range_cnt++;
216 if (packet->ignored) {
217 range->ignored_user_range_cnt++;
219 depended_frames_add(range->user_range_plus_depends, range->cf->provider.frames, packet);
220 if (packet->passed_dfilter) {
221 range->displayed_user_range_cnt++;
222 if (packet->ignored) {
223 range->displayed_ignored_user_range_cnt++;
225 depended_frames_add(range->displayed_user_range_plus_depends, range->cf->provider.frames, packet);
229 range->user_range_plus_depends_cnt = g_hash_table_size(range->user_range_plus_depends);
230 range->displayed_user_range_plus_depends_cnt = g_hash_table_size(range->displayed_user_range_plus_depends);
234 static void packet_range_calc_selection(packet_range_t *range) {
235 uint32_t framenum;
236 frame_data *packet;
238 range->selection_range_cnt = 0;
239 range->ignored_selection_range_cnt = 0;
240 range->displayed_selection_range_cnt = 0;
241 range->displayed_ignored_selection_range_cnt = 0;
243 ws_assert(range->cf != NULL);
245 if (range->cf->provider.frames != NULL) {
246 for (framenum = 1; framenum <= range->cf->count; framenum++) {
247 packet = frame_data_sequence_find(range->cf->provider.frames, framenum);
249 if (value_is_in_range(range->selection_range, framenum)) {
250 range->selection_range_cnt++;
251 if (packet->ignored) {
252 range->ignored_selection_range_cnt++;
254 depended_frames_add(range->selected_plus_depends, range->cf->provider.frames, packet);
255 if (packet->passed_dfilter) {
256 range->displayed_selection_range_cnt++;
257 if (packet->ignored) {
258 range->displayed_ignored_selection_range_cnt++;
260 depended_frames_add(range->displayed_selected_plus_depends, range->cf->provider.frames, packet);
264 range->selected_plus_depends_cnt = g_hash_table_size(range->selected_plus_depends);
265 range->displayed_selected_plus_depends_cnt = g_hash_table_size(range->displayed_selected_plus_depends);
270 /* init the range struct */
271 void packet_range_init(packet_range_t *range, capture_file *cf) {
273 memset(range, 0, sizeof(packet_range_t));
274 range->process = range_process_all;
275 range->user_range = NULL;
276 range->selection_range = NULL;
277 range->cf = cf;
278 range->marked_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
279 range->displayed_marked_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
280 range->mark_range_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
281 range->displayed_mark_range_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
282 range->user_range_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
283 range->displayed_user_range_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
284 range->selected_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
285 range->displayed_selected_plus_depends = g_hash_table_new(g_direct_hash, g_direct_equal);
287 /* calculate all packet range counters */
288 packet_range_calc(range);
289 packet_range_calc_user(range);
290 packet_range_calc_selection(range);
293 void packet_range_cleanup(packet_range_t *range) {
294 wmem_free(NULL, range->user_range);
295 wmem_free(NULL, range->selection_range);
296 g_hash_table_destroy(range->marked_plus_depends);
297 g_hash_table_destroy(range->displayed_marked_plus_depends);
298 g_hash_table_destroy(range->mark_range_plus_depends);
299 g_hash_table_destroy(range->displayed_mark_range_plus_depends);
300 g_hash_table_destroy(range->user_range_plus_depends);
301 g_hash_table_destroy(range->displayed_user_range_plus_depends);
302 g_hash_table_destroy(range->selected_plus_depends);
303 g_hash_table_destroy(range->displayed_selected_plus_depends);
306 /* check whether the packet range is OK */
307 convert_ret_t packet_range_check(packet_range_t *range) {
308 if (range->process == range_process_user_range && range->user_range == NULL) {
309 /* Not valid - return the error. */
310 return range->user_range_status;
312 if (range->process == range_process_selected && range->selection_range == NULL) {
313 return range->selection_range_status;
316 return CVT_NO_ERROR;
319 /* init the processing run */
320 void packet_range_process_init(packet_range_t *range) {
321 /* Check that, if an explicit range was selected, it's valid. */
322 /* "enumeration" values */
323 range->marked_range_active = false;
325 if (range->process_filtered == false) {
326 range->marked_range_left = range->mark_range_cnt;
327 } else {
328 range->marked_range_left = range->displayed_mark_range_cnt;
330 /* XXX: We could set the count to whichever case is active so we
331 * could decrement it and return finished.
335 /* do we have to process all packets? */
336 bool packet_range_process_all(packet_range_t *range) {
337 return range->process == range_process_all && !range->process_filtered && !range->remove_ignored;
340 static range_process_e
341 packet_range_process_packet_include_depends(packet_range_t *range, frame_data *fdata) {
343 switch(range->process) {
344 case(range_process_all):
345 if (range->process_filtered) {
346 if ((fdata->passed_dfilter || fdata->dependent_of_displayed) == false) {
347 return range_process_next;
350 break;
351 case(range_process_selected):
352 if (range->process_filtered) {
353 if (!g_hash_table_contains(range->displayed_selected_plus_depends, GUINT_TO_POINTER(fdata->num))) {
354 return range_process_next;
356 } else {
357 if (!g_hash_table_contains(range->selected_plus_depends, GUINT_TO_POINTER(fdata->num))) {
358 return range_process_next;
361 break;
362 case(range_process_marked):
363 if (range->process_filtered) {
364 if (!g_hash_table_contains(range->displayed_marked_plus_depends, GUINT_TO_POINTER(fdata->num))) {
365 return range_process_next;
367 } else {
368 if (!g_hash_table_contains(range->marked_plus_depends, GUINT_TO_POINTER(fdata->num))) {
369 return range_process_next;
372 break;
373 case(range_process_marked_range):
374 if (range->process_filtered) {
375 if (!g_hash_table_contains(range->displayed_mark_range_plus_depends, GUINT_TO_POINTER(fdata->num))) {
376 return range_process_next;
378 } else {
379 if (!g_hash_table_contains(range->mark_range_plus_depends, GUINT_TO_POINTER(fdata->num))) {
380 return range_process_next;
383 break;
384 case(range_process_user_range):
385 if (range->process_filtered) {
386 if (!g_hash_table_contains(range->displayed_user_range_plus_depends, GUINT_TO_POINTER(fdata->num))) {
387 return range_process_next;
389 } else {
390 if (!g_hash_table_contains(range->user_range_plus_depends, GUINT_TO_POINTER(fdata->num))) {
391 return range_process_next;
394 break;
395 default:
396 ws_assert_not_reached();
399 /* We fell through the conditions above, so we accept this packet */
400 return range_process_this;
403 /* do we have to process this packet? */
404 range_process_e packet_range_process_packet(packet_range_t *range, frame_data *fdata) {
406 /* For ignored packets, since we don't dissect them, we don't know
407 * anything about packets they depend upon, which is helpful as we
408 * don't have to calculate more counts based on interaction terms. If
409 * someone wants to include those, then don't ignore the packet.
411 if (range->remove_ignored && fdata->ignored) {
412 return range_process_next;
415 ws_assert(range->cf != NULL);
417 if (range->include_dependents) {
418 return packet_range_process_packet_include_depends(range, fdata);
421 switch(range->process) {
422 case(range_process_all):
423 break;
424 case(range_process_selected):
425 if (value_is_in_range(range->selection_range, fdata->num) == false) {
426 return range_process_next;
428 break;
429 case(range_process_marked):
430 if (fdata->marked == false) {
431 return range_process_next;
433 break;
434 case(range_process_marked_range):
435 if (range->marked_range_left == 0) {
436 return range_processing_finished;
438 if (fdata->marked == true) {
439 range->marked_range_active = true;
441 if (range->marked_range_active == false ) {
442 return range_process_next;
444 if (!range->process_filtered ||
445 (range->process_filtered && fdata->passed_dfilter == true))
447 range->marked_range_left--;
449 break;
450 case(range_process_user_range):
451 if (value_is_in_range(range->user_range, fdata->num) == false) {
452 return range_process_next;
454 break;
455 default:
456 ws_assert_not_reached();
459 /* This packet has to pass the display filter but didn't?
460 * Try next (if we're including dependent packets we called the
461 * other function above).
463 if ((range->process_filtered && fdata->passed_dfilter == false)) {
464 return range_process_next;
467 /* We fell through the conditions above, so we accept this packet */
468 return range_process_this;
472 /******************** Range Entry Parser *********************************/
474 /* Converts a range string to a user range.
475 * The parameter 'es' points to the string to be converted, and is defined in
476 * the Save/Print-As widget.
479 void packet_range_convert_str(packet_range_t *range, const char *es)
481 range_t *new_range;
482 convert_ret_t ret;
484 if (range->user_range != NULL)
485 wmem_free(NULL, range->user_range);
487 ws_assert(range->cf != NULL);
489 ret = range_convert_str(NULL, &new_range, es, range->cf->count);
490 if (ret != CVT_NO_ERROR) {
491 /* range isn't valid */
492 range->user_range = NULL;
493 range->user_range_status = ret;
494 range->user_range_cnt = 0;
495 range->user_range_plus_depends_cnt = 0;
496 range->ignored_user_range_cnt = 0;
497 range->displayed_user_range_cnt = 0;
498 range->displayed_ignored_user_range_cnt = 0;
499 range->displayed_user_range_plus_depends_cnt = 0;
500 return;
502 range->user_range = new_range;
503 g_hash_table_remove_all(range->user_range_plus_depends);
504 g_hash_table_remove_all(range->displayed_user_range_plus_depends);
506 /* calculate new user specified packet range counts */
507 packet_range_calc_user(range);
508 } /* packet_range_convert_str */
510 void packet_range_convert_selection_str(packet_range_t *range, const char *es)
512 range_t *new_range;
513 convert_ret_t ret;
515 if (range->selection_range != NULL)
516 wmem_free(NULL, range->selection_range);
518 ws_assert(range->cf != NULL);
520 ret = range_convert_str(NULL, &new_range, es, range->cf->count);
521 if (ret != CVT_NO_ERROR) {
522 /* range isn't valid */
523 range->selection_range = NULL;
524 range->selection_range_status = ret;
525 range->selection_range_cnt = 0;
526 range->selected_plus_depends_cnt = 0;
527 range->ignored_selection_range_cnt = 0;
528 range->displayed_selection_range_cnt = 0;
529 range->displayed_selected_plus_depends_cnt = 0;
530 range->displayed_ignored_selection_range_cnt = 0;
531 return;
533 range->selection_range = new_range;
534 g_hash_table_remove_all(range->selected_plus_depends);
535 g_hash_table_remove_all(range->displayed_selected_plus_depends);
537 /* calculate new user specified packet range counts */
538 packet_range_calc_selection(range);
541 uint32_t packet_range_count(const packet_range_t *range)
543 uint32_t count;
544 switch(range->process) {
545 case(range_process_all):
546 if (range->process_filtered) {
547 if (range->include_dependents) {
548 count = range->displayed_plus_dependents_cnt;
549 } else {
550 count = range->displayed_cnt;
552 if (range->remove_ignored) {
553 count -= range->displayed_ignored_cnt;
555 } else {
556 count = range->cf->count;
557 if (range->remove_ignored) {
558 count -= range->ignored_cnt;
561 break;
562 case(range_process_selected):
563 if (range->process_filtered) {
564 if (range->include_dependents) {
565 count = range->displayed_selected_plus_depends_cnt;
566 } else {
567 count = range->displayed_selection_range_cnt;
569 if (range->remove_ignored) {
570 count -= range->displayed_ignored_selection_range_cnt;
572 } else {
573 if (range->include_dependents) {
574 count = range->selected_plus_depends_cnt;
575 } else {
576 count = range->selection_range_cnt;
578 if (range->remove_ignored) {
579 count -= range->ignored_selection_range_cnt;
582 break;
583 case(range_process_marked):
584 if (range->process_filtered) {
585 if (range->include_dependents) {
586 count = range->displayed_marked_plus_depends_cnt;
587 } else {
588 count = range->displayed_marked_cnt;
590 if (range->remove_ignored) {
591 count -= range->displayed_ignored_marked_cnt;
593 } else {
594 if (range->include_dependents) {
595 count = range->marked_plus_depends_cnt;
596 } else {
597 count = range->cf->marked_count;
599 if (range->remove_ignored) {
600 count -= range->ignored_marked_cnt;
603 break;
604 case(range_process_marked_range):
605 if (range->process_filtered) {
606 if (range->include_dependents) {
607 count = range->displayed_mark_range_plus_depends_cnt;
608 } else {
609 count = range->displayed_mark_range_cnt;
611 if (range->remove_ignored) {
612 count -= range->displayed_ignored_mark_range_cnt;
614 } else {
615 if (range->include_dependents) {
616 count = range->mark_range_plus_depends_cnt;
617 } else {
618 count = range->mark_range_cnt;
620 if (range->remove_ignored) {
621 count -= range->ignored_mark_range_cnt;
624 break;
625 case(range_process_user_range):
626 if (range->process_filtered) {
627 if (range->include_dependents) {
628 count = range->displayed_user_range_plus_depends_cnt;
629 } else {
630 count = range->displayed_user_range_cnt;
632 if (range->remove_ignored) {
633 count -= range->displayed_ignored_user_range_cnt;
635 } else {
636 if (range->include_dependents) {
637 count = range->user_range_plus_depends_cnt;
638 } else {
639 count = range->user_range_cnt;
641 if (range->remove_ignored) {
642 count -= range->ignored_user_range_cnt;
645 break;
646 default:
647 ws_assert_not_reached();
650 return count;