/* range.c
* Packet range routines (save, print, ...)
*
- * $Id: range.c,v 1.2 2003/12/30 22:48:14 guy Exp $
+ * $Id: range.c,v 1.9 2004/02/11 09:19:54 guy Exp $
*
* Dick Gooris <gooris@lucent.com>
* Ulf Lamping <ulf.lamping@web.de>
#include "globals.h"
-static gboolean packet_is_in_range(guint32 val);
+static gboolean packet_is_in_range(packet_range_t *range, guint32 val);
-/* Range parser variables */
-#define MaxRange 30
+/* (re-)calculate the packet counts (except the user specified range) */
+void packet_range_calc(packet_range_t *range) {
+ guint32 current_count;
+ guint32 mark_low;
+ guint32 mark_high;
+ guint32 displayed_mark_low;
+ guint32 displayed_mark_high;
+ frame_data *packet;
-struct range_admin {
- guint32 low;
- guint32 high;
-};
-static guint GLnrange=0;
-struct range_admin GLrange[MaxRange];
-static guint32 max_packets;
+ range->selected_packet = 0L;
-void packet_range_init(packet_range_t *range) {
- guint32 current_count;
- guint32 displayed_count;
- guint32 mark_low;
- guint32 mark_high;
- frame_data *packet;
+ mark_low = 0L;
+ mark_high = 0L;
+ range->mark_range_cnt = 0L;
- /* This is needed to calculate the number of packets for each variation
- * like the total amount of packets, the number of marked packets, and
- * the number between the packets. This is for information only
+ displayed_mark_low = 0L;
+ displayed_mark_high = 0L;
+ range->displayed_cnt = 0L;
+ range->displayed_marked_cnt = 0L;
+ range->displayed_mark_range_cnt=0L;
+
+ /* The next for-loop is used to obtain the amount of packets to be processed
+ * and is used to present the information in the Save/Print As widget.
+ * We have different types of ranges: All the packets, the number
+ * of packets of a marked range, a single packet, and a user specified
+ * packet range. The last one is not calculated here since this
+ * data must be entered in the widget by the user.
*/
- /* "enumeration" values */
- range->markers = cfile.marked_count;
- range->range_active = FALSE;
- range->process_curr_done = FALSE;
-
- displayed_count = 0L;
- mark_low = 0L;
- mark_high = 0L;
- range->mark_range = 0L;
-
current_count = 0;
for(packet = cfile.plist; packet != NULL; packet = packet->next) {
current_count++;
range->selected_packet = current_count;
}
if (packet->flags.passed_dfilter) {
- displayed_count++;
+ range->displayed_cnt++;
}
if (packet->flags.marked) {
- if (mark_low == 0) {
- mark_low = current_count;
- }
- if (current_count > mark_high) {
- mark_high = current_count;
- }
+ if (packet->flags.passed_dfilter) {
+ range->displayed_marked_cnt++;
+ if (displayed_mark_low == 0) {
+ displayed_mark_low = current_count;
+ }
+ if (current_count > displayed_mark_high) {
+ displayed_mark_high = current_count;
+ }
+ }
+
+ if (mark_low == 0) {
+ mark_low = current_count;
+ }
+ if (current_count > mark_high) {
+ mark_high = current_count;
+ }
+ }
+ }
+
+ current_count = 0;
+ for(packet = cfile.plist; packet != NULL; packet = packet->next) {
+ current_count++;
+
+ if (current_count >= mark_low &&
+ current_count <= mark_high)
+ {
+ range->mark_range_cnt++;
+ }
+
+ if (current_count >= displayed_mark_low &&
+ current_count <= displayed_mark_high)
+ {
+ if (packet->flags.passed_dfilter) {
+ range->displayed_mark_range_cnt++;
+ }
}
}
+
/* in case we marked just one packet, we add 1. */
- if (cfile.marked_count != 0) {
+ /*if (cfile.marked_count != 0) {
range->mark_range = mark_high - mark_low + 1;
+ }*/
+
+ /* in case we marked just one packet, we add 1. */
+ /*if (range->displayed_marked_cnt != 0) {
+ range->displayed_mark_range = displayed_mark_high - displayed_mark_low + 1;
+ }*/
+}
+
+
+/* (re-)calculate the user specified packet range counts */
+void packet_range_calc_user(packet_range_t *range) {
+ guint32 current_count;
+ frame_data *packet;
+
+ range->user_range_cnt = 0L;
+ range->displayed_user_range_cnt = 0L;
+
+ current_count = 0;
+ for(packet = cfile.plist; packet != NULL; packet = packet->next) {
+ current_count++;
+
+ if (packet_is_in_range(range, current_count)) {
+ range->user_range_cnt++;
+ if (packet->flags.passed_dfilter) {
+ range->displayed_user_range_cnt++;
+ }
+ }
}
- /* make this global, to be used in function conv_str_range() */
- max_packets = cfile.count;
}
+/* init the range struct */
+void packet_range_init(packet_range_t *range) {
+
+ range->process = range_process_all;
+ range->process_filtered = FALSE;
+ range->nranges = 0;
+ range->ranges[range->nranges].low = 0L;
+ range->ranges[range->nranges].high = 0L;
+
+ /* calculate all packet range counters */
+ packet_range_calc(range);
+ packet_range_calc_user(range);
+}
+
+/* init the processing run */
+void packet_range_process_init(packet_range_t *range) {
+ /* "enumeration" values */
+ range->marked_range_active = FALSE;
+ range->selected_done = FALSE;
+
+ if (range->process_filtered == FALSE) {
+ range->marked_range_left = range->mark_range_cnt;
+ } else {
+ range->marked_range_left = range->displayed_mark_range_cnt;
+ }
+}
+
/* do we have to process all packets? */
gboolean packet_range_process_all(packet_range_t *range) {
- return range->process_all && !range->process_filtered;
+ return range->process == range_process_all && !range->process_filtered;
}
/* do we have to process this packet? */
-range_process_e packet_range_process(packet_range_t *range, frame_data *fdata) {
-
- /* do we have to process this packet at all? */
- if (
- (!range->process_filtered && !range->process_marked) ||
- (range->process_filtered && fdata->flags.passed_dfilter && !range->process_marked) ||
- (range->process_marked && fdata->flags.marked && !range->process_filtered) ||
- (range->process_filtered && range->process_marked && fdata->flags.passed_dfilter && fdata->flags.marked) ||
- (range->process_curr) ||
- (range->process_marked_range) ||
- (range->process_manual_range) ||
- (range->range_active)
- ) {
- /* yes, we have to */
- } else {
- return range_process_next;
+range_process_e packet_range_process_packet(packet_range_t *range, frame_data *fdata) {
+
+ switch(range->process) {
+ case(range_process_all):
+ break;
+ case(range_process_selected):
+ if (range->selected_done) {
+ return range_processing_finished;
+ }
+ if (fdata->num != cfile.current_frame->num) {
+ return range_process_next;
+ }
+ range->selected_done = TRUE;
+ break;
+ case(range_process_marked):
+ if (fdata->flags.marked == FALSE) {
+ return range_process_next;
+ }
+ break;
+ case(range_process_marked_range):
+ if (range->marked_range_left == 0) {
+ return range_processing_finished;
+ }
+ if (fdata->flags.marked == TRUE) {
+ range->marked_range_active = TRUE;
+ }
+ if (range->marked_range_active == FALSE ) {
+ return range_process_next;
+ }
+ if (!range->process_filtered ||
+ (range->process_filtered && fdata->flags.passed_dfilter == TRUE))
+ {
+ range->marked_range_left--;
+ }
+ break;
+ case(range_process_user_range):
+ if (packet_is_in_range(range, fdata->num) == FALSE) {
+ return range_process_next;
+ }
+ break;
+ default:
+ g_assert_not_reached();
}
- /* In case we process a manual range, we check the packet number
- * with the range as defined in the array GLrange, see file_dlg.c
- * If a match is found, we process it, otherwise we simply go to check
- * the next packet.
- */
- if (range->process_manual_range) {
- if (range->process_filtered) {
- if (fdata->flags.passed_dfilter == FALSE) {
- return range_process_next;
- }
- }
- if (packet_is_in_range(fdata->num) == FALSE) {
- return range_process_next;
- }
- }
-
- /* For processing a marked range, skip the frames not marked in the first place
- * until the first marked frame comes by. Then continue processing until we found the
- * last marked frame. We set the range_active to FALSE in the first place until
- * a marked frame is found (fdata->flags.marked == TRUE) From now on range_active
- * is TRUE, and the large 'if' statement will pass by any frame. It will stop doing
- * so once the markers count got 0. process_marked_range got set in gtk/file_dlg.c
- */
- if (range->process_marked_range) {
- if (range->markers == 0) {
- return range_processing_finished;
- }
- if (fdata->flags.marked == TRUE) {
- range->range_active = TRUE;
- range->markers--;
- }
- if (range->process_filtered) {
- if (fdata->flags.passed_dfilter == FALSE) {
- return range_process_next;
- }
- }
- if (range->range_active == FALSE ) {
- return range_process_next;
- }
- }
-
- /* Only process the selected frame. If accomplished, finish */
- if (range->process_curr) {
- if (range->process_curr_done) {
- return range_processing_finished;
- }
- if (fdata->num != cfile.current_frame->num) {
- return range_process_next;
- }
- range->process_curr_done = TRUE;
- }
+ /* this packet has to pass the display filter but didn't? -> try next */
+ if (range->process_filtered && fdata->flags.passed_dfilter == FALSE) {
+ return range_process_next;
+ }
+ /* We fell through the conditions above, so we accept this packet */
return range_process_this;
}
-
-
/******************** Range Entry Parser *********************************/
-/* Convert the entry range string in a fast comparable array of ranges.
- * In the first place get rid of spaces, and any other characters than
- * commas, digits, and hyphens. The parameter es points to the string to be processed
+/* Converts a range string to a fast comparable array of ranges.
+ * The parameter 'es' points to the string to be converted, and is defined in
+ * the Save/Print-As widget.
+ *
+ * This function fills the array ranges containing low and high values indexed
+ * by a global variable nranges. After having called this function, the function
+ * packet_is_in_range() determines whether a given (packet) number is within
+ * the range or not.
*
- * This function is only called once when a range string is provided in the Save/Print As
- * widget. This function fills an array of low and high values indexed by a global
- * varaiable GLnrange. After having called this function, the function isin(val)
- * determines whether the value is with the range or not.
+ * In case of a single packet number, we make a range where low is equal to high.
+ * We strip any characters other than commas, digits, or hyphens. We take care
+ * on wrongly entered ranges; opposite order will be taken care of.
+ *
+ * The following syntax is accepted :
+ *
+ * 1-20,30-40 Range from 1 to 20, and packets 30 to 40
+ * -20,30 Range from 1 to 20, and packet 30
+ * 20,30,40- Packet number 20, 30, and the range from 40 to the end
+ * 20-10,30-25 Range from 10 to 20, and from 25 to 30
+ * - All packets
*/
-void packet_range_convert_str(const gchar *es)
+void packet_range_convert_str(packet_range_t *range, const gchar *es)
{
gchar EntryStr[255], OrgStr[255], value[255], p;
- guint i, j=0;
- guint32 tmp, val;
+ guint i, j=0;
+ guint32 tmp, val;
gboolean hyphenseen;
-
+
/* Reset the number of ranges we are going to find */
- GLnrange = 0;
- GLrange[GLnrange].low = 0L;
- GLrange[GLnrange].high = 0L;
+ range->nranges = 0;
+ range->ranges[range->nranges].low = 0L;
+ range->ranges[range->nranges].high = 0L;
/* Make a copy of the string, and check the validity of the input */
- strcpy(OrgStr,es);
+ strcpy(OrgStr,es);
if (strlen(OrgStr) == 0 ) {
return;
}
-
- /* only keep digits, commas, and hyphens. */
+
+ /* Only keep digits, commas, and hyphens. */
for (i=0; i<=strlen(OrgStr); i++) {
- if ( isdigit(OrgStr[i]) || OrgStr[i] == '-' || OrgStr[i] == ',' ) {
- EntryStr[j++] = OrgStr[i];
- }
+ if ( isdigit((guchar)OrgStr[i]) || OrgStr[i] == '-' || OrgStr[i] == ',' ) {
+ EntryStr[j++] = OrgStr[i];
+ }
}
EntryStr[j] = '\0';
-
- /* remove any starting commas */
+
+ /* Remove any starting commas */
strcpy(OrgStr,EntryStr);
i = 0;
while (OrgStr[i] == ',') {
i++;
}
strcpy(EntryStr,OrgStr+i);
-
- /* remove any double commas within the entry string */
+
+ /* Remove any double commas */
strcpy(OrgStr,EntryStr);
p = ',';
j = 0;
for (i=0; i<=strlen(OrgStr); i++) {
if ( OrgStr[i] != ',' || p != ',') {
- EntryStr[j++] = OrgStr[i];
+ EntryStr[j++] = OrgStr[i];
}
- p = OrgStr[i];
+ p = OrgStr[i];
}
EntryStr[j] = '\0';
- /* remove any double hyphens within the entry string */
+ /* Remove any double hyphens */
strcpy(OrgStr,EntryStr);
p = '-';
j = 0;
for (i=0; i<=strlen(OrgStr); i++) {
if (OrgStr[i] != '-' || p != '-' || i == 0) {
- EntryStr[j++] = OrgStr[i];
+ EntryStr[j++] = OrgStr[i];
}
- p = OrgStr[i];
+ p = OrgStr[i];
}
EntryStr[j] = '\0';
-
- /* remove any trailing commas */
+
+ /* Remove any trailing commas */
i = strlen(EntryStr) - 1;
while (EntryStr[i] == ',') {
- EntryStr[i] = '\0';
+ EntryStr[i] = '\0';
i--;
}
-
+
/* The entry string is now filtered, and ready for further parsing */
- /* printf("str=%s\n",EntryStr); */
+ /* printf("Function : packet_range_convert_str EntryStr = %s\n",EntryStr); */
- /* Now we are going to process the ranges separately until we get a comma,
- * or end of string. The following input are interpreted all right :
- *
- * 0-20,30-40 -=> Range from 0 to 20, and packets 30 to 40
- * -20,30 -=> Range from 0 to 20, and packet 30
- * 20,30,40- -=> Packet number 20, 30, and the range from 40 to the end
- * 20-10,30-25 -=> Range from 10 to 20, and from 25 to 30
- * - -=> All packets
+ /* Now we are going to process the ranges separately until we get a comma,
+ * or end of string.
*
- * We build a structure array called GLrange of high and low values. After the
- * following loop, we have the GLnrange variable which tells how many ranges
- * are found.
- * The number of different ranges is limited to 'MaxRanges'
+ * We build a structure array called ranges of high and low values. After the
+ * following loop, we have the nranges variable which tells how many ranges
+ * were found. The number of individual ranges is limited to 'MaxRanges'
*/
- j = 0;
+ j = 0;
hyphenseen = FALSE;
for (i=0; i<=strlen(EntryStr);i++) {
- /* copy the digit string until a no-digit character is seen */
- if (isdigit(EntryStr[i])) {
+ /* Copy the digit string until a no-digit character is seen */
+ if (isdigit((guchar)EntryStr[i])) {
value[j++] = EntryStr[i];
- continue;
+ continue;
}
-
+
/* Terminate the digit string, and convert it */
value[j] = '\0';
val=atol(value);
- j=0;
+ j=0;
- /* treatment in case we see a hyphen */
+ /* In case we see a hyphen, store the value we read in the low part
+ * of ranges. In case it is a trailer hyphen, store the low value, and
+ * set the high value to the maximum of packets captured.
+ */
if (EntryStr[i] == '-') {
- /* if this is a trailer hyphen, then treat it in a different
- * way, then the high value is the maximum number of packets counted
- * and we are ready */
- if (i == strlen(EntryStr)-1) {
- GLrange[GLnrange].low = val;
- GLrange[GLnrange].high = max_packets;
- GLnrange++;
- break;
- } else {
- /* if no digits were actually seen, the outcome of
- * a zeroed string conversion to interger is also 0. */
- GLrange[GLnrange].low = val;
- }
- hyphenseen=TRUE;
- continue;
+ /* If this is a trailer hyphen, then treat it in a different
+ * way, then the high value is the maximum number of packets counted
+ * and we are ready
+ */
+ if (i == strlen(EntryStr)-1) {
+ range->ranges[range->nranges].low = val;
+ range->ranges[range->nranges].high = cfile.count;
+ range->nranges++;
+ break;
+ } else {
+ /* Store the low value of the range */
+ range->ranges[range->nranges].low = val;
+ }
+ hyphenseen=TRUE;
+ continue;
}
-
- /* treatment in case we see a comma, or end of string */
+
+ /* In case we see a comma, or end of string */
if (EntryStr[i] == ',' || i == strlen(EntryStr)) {
- if (hyphenseen) {
- GLrange[GLnrange].high = val;
- } else {
- /* in this case we got a single packet number */
- GLrange[GLnrange].low = val;
- GLrange[GLnrange].high = val;
- }
- hyphenseen=FALSE;
+ if (hyphenseen) {
+ /* Normal treatment: store the high value range in ranges */
+ range->ranges[range->nranges].high = val;
+ } else {
+ /* We did not see a hyphen and we get a comma, then this must
+ * be a single packet number */
+ range->ranges[range->nranges].low = val;
+ range->ranges[range->nranges].high = val;
+ }
+ hyphenseen=FALSE;
}
-
- /* Increase the index for ranges found, and protect
- * against wildly outside array bounds */
- GLnrange++;
- if (GLnrange > MaxRange) {
- GLnrange--;
+
+ /* Increase the index for the number of ranges we found, and protect
+ * against wildly outside array bound jumps */
+ range->nranges++;
+ if (range->nranges > MaxRange) {
+ range->nranges--;
}
}
- GLnrange--;
+ range->nranges--;
/* Now we are going through the low and high values, and check
* whether they are in a proper order. Low should be equal or lower
- * than high. So, go through the loop and swap if needed
+ * than high. So, go through the loop and swap if needed.
*/
- for (i=0; i <= GLnrange; i++) {
- if (GLrange[i].low > GLrange[i].high) {
- tmp = GLrange[i].low;
- GLrange[i].low = GLrange[i].high;
- GLrange[i].high = tmp;
+ for (i=0; i <= range->nranges; i++) {
+ if (range->ranges[i].low > range->ranges[i].high) {
+ tmp = range->ranges[i].low;
+ range->ranges[i].low = range->ranges[i].high;
+ range->ranges[i].high = tmp;
}
}
-
+
/* In case we want to know what the result ranges are :
- *
- * for (i=0; i <= GLnrange; i++) {
- * printf("L=%u\tH=%u\n",GLrange[i].low,GLrange[i].high);
+ *
+ * for (i=0; i <= nranges; i++) {
+ * printf("Function : packet_range_convert_str L=%u \t H=%u\n",ranges[i].low,ranges[i].high);
* }
- *
+ *
*/
-
- /* End of conv_str_range() */
- return;
-}
-
-/* This function returns TRUE is the given value is within the range
- * of the input range entered via (Save/Print As). This is supposed to
- * be a tiny and quick procedure since this is called for every packet
- * to be potentially saved.
+
+ /* calculate new user specified packet range counts */
+ packet_range_calc_user(range);
+} /* packet_range_convert_str */
+
+/* This function returns TRUE if a given value is within one of the ranges
+ * stored in the ranges array.
*/
-static gboolean packet_is_in_range(guint32 val)
+static gboolean packet_is_in_range(packet_range_t *range, guint32 val)
{
guint i;
-
- for (i=0; i <= GLnrange; i++) {
- if (val >= GLrange[i].low && val <= GLrange[i].high)
- return TRUE;
+
+ for (i=0; i <= range->nranges; i++) {
+ if (val >= range->ranges[i].low && val <= range->ranges[i].high)
+ return TRUE;
}
- return(FALSE);
+ return(FALSE);
}
-static void packet_is_in_range_check(guint32 val)
+#if 0
+/* This is a debug function to check the range functionality */
+static void packet_is_in_range_check(packet_range_t *range, guint32 val)
{
- printf("Checking %d\t",val);
- if (packet_is_in_range(val)) {
- printf("TRUE\n");
+
+ /* Print the result for a given value */
+ printf("Function : packet_is_in_range_check Number %u\t",val);
+
+ if (packet_is_in_range(range, val)) {
+ printf("is in range\n");
} else {
- printf("FALSE\n");
+ printf("is not in range\n");
}
}
-
+#endif