Ethereal-dev: [Ethereal-dev] some dfilter work
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Ed Warnicke <hagbard@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 Dec 2000 02:31:18 -0500 (EST)
I've attacked implementing some of the changes from last weeks discussion. I haven't extended range types from FT_BYTES to other types. I have changed the way ranges work in the following sense. [i:j] still works the way it always did, [offset:length] [i] will now always choose the element of offset i (length 1). [i-j] will select all element from offset i to offset j and you can string these three forms together with a comma(,) which concatentate the selected bits together [i,j,l:k,m-n] roughly the grammar is bytes_variable = T_FT_BYTES "[" range "]" range = range-element | range-element "," range range-element = NUM ":" NUM | NUM | NUM "-" NUM What I want to know is: Does this seem like an improvement to people? If so I will extend this to the rest of the sequence types as discussed. I've attatched a patch and a tar file containing two new source files ethereal/epan/drange.{c,h} containing these changes. Please try this out and let me know how it works for you. Ed
Attachment:
drange.tar.gz
Description: tar file containing ethereal/epan/drange.{c,h}
? cscope.out ? out ? epan/drange.h ? epan/drange.c ? epan/Makefile.am.new Index: epan/Makefile.am =================================================================== RCS file: /cvsroot/ethereal/epan/Makefile.am,v retrieving revision 1.14 diff -u -r1.14 Makefile.am --- Makefile.am 2000/11/20 16:18:08 1.14 +++ Makefile.am 2000/12/26 06:58:35 @@ -46,6 +46,8 @@ dfilter-scanner.l \ dfilter.c \ dfilter.h \ + drange.c \ + drange.h \ epan.c \ epan.h \ except.c \ Index: epan/dfilter-grammar.y =================================================================== RCS file: /cvsroot/ethereal/epan/dfilter-grammar.y,v retrieving revision 1.2 diff -u -r1.2 dfilter-grammar.y --- dfilter-grammar.y 2000/12/22 12:05:36 1.2 +++ dfilter-grammar.y 2000/12/26 06:58:35 @@ -70,6 +70,7 @@ #endif #include "dfilter-int.h" +#include "drange.h" #ifndef __RESOLV_H__ #include "resolv.h" @@ -91,21 +92,33 @@ static GNode* dfilter_mknode_ipv6_variable(gint id); static GNode* dfilter_mknode_existence(gint id); static GNode* dfilter_mknode_bytes_value(GByteArray *barray); -static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length, gboolean to_the_end); +static GNode* dfilter_mknode_bytes_variable(gint id, drange* range); static GNode* dfilter_mknode_string_value(char *s); static GNode* dfilter_mknode_string_variable(gint id); static guint32 string_to_guint32(char *s, gboolean *success); static double string_to_double(char *s, gboolean *success); static int ether_str_to_guint8_array(const char *s, guint8 *mac); -static guint dfilter_get_bytes_variable_offset(GNode *gnode); static guint dfilter_get_bytes_value_length(GNode* gnode); -static void dfilter_set_bytes_variable_length(GNode *gnode, guint length); -static guint dfilter_get_bytes_variable_length(GNode *gnode); -static gint dfilter_get_bytes_variable_field_registered_length(GNode *gnode); static char* dfilter_get_variable_abbrev(GNode *gnode); -static int check_bytes_variable_sanity(GNode *gnode); +static drange_node* byte_string_to_drange_node(gchar* s, gboolean *success); +static drange_node* string_to_drange_node(gchar* s, gboolean *success); +static gboolean dfilter_is_range_variable(GNode *gnode); +static gboolean dfilter_range_variable_has_total_length(GNode *gnode); +static gint dfilter_get_range_variable_total_length(GNode *gnode); +static int check_range_variable_sanity(GNode *gnode); +static gint dfilter_get_range_variable_field_registered_length(GNode *gnode); +static drange* null_to_drange(drange* range); + +static void check_range_variable_sanity_iterator(gpointer data, gpointer user_data); + +typedef struct _check_range_variable_sanity_iterator_arg{ + gint max_length; + gboolean *success; + gchar* variable_abbrev; +} check_range_variable_sanity_iterator_arg; + /* This is the dfilter we're currently processing. It's how * dfilter_compile communicates with us. */ @@ -125,6 +138,7 @@ gint offset; guint length; } byte_range; + drange* range; } %type <node> statement expression relation @@ -138,6 +152,8 @@ %type <node> variable_name %type <node> bytes_value bytes_variable +%type <range> range + %type <operand> numeric_relation %type <operand> equality_relation %type <operand> bytes_relation @@ -169,6 +185,7 @@ %token <operand> TOK_AND TOK_OR TOK_NOT TOK_XOR %token <operand> TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE +%token <operand> TOK_BRA TOK_KET TOK_COMMA %expect 4 %left TOK_AND @@ -261,20 +278,19 @@ | bytes_variable bytes_relation bytes_value { int a_len, b_len; + gboolean a_has_length; - a_len = dfilter_get_bytes_variable_length($1); + a_len = b_len = 0; + a_has_length = dfilter_range_variable_has_total_length($1); + if(a_has_length) + a_len = dfilter_get_range_variable_total_length($1); b_len = dfilter_get_bytes_value_length($3); - if (a_len == 0) { - dfilter_set_bytes_variable_length($1, b_len); - a_len = b_len; - } - - if (!check_bytes_variable_sanity($1)) { + if (!check_range_variable_sanity($1)) { YYERROR; } - if (a_len != b_len) { + if (a_has_length && a_len != b_len) { dfilter_fail("Field \"%s\" has %u byte%s being compared, but %u byte%s " "%s supplied.", dfilter_get_variable_abbrev($1), @@ -283,25 +299,32 @@ plurality(b_len, "was", "were")); YYERROR; } - $$ = dfilter_mknode_join($1, relation, $2, $3); } | bytes_variable bytes_relation bytes_variable { int a_len, b_len; + gboolean a_has_length; + gboolean b_has_length; - a_len = dfilter_get_bytes_variable_length($1); - b_len = dfilter_get_bytes_variable_length($3); + a_len = b_len = 0; - if (!check_bytes_variable_sanity($1)) { + a_has_length = dfilter_range_variable_has_total_length($1); + b_has_length = dfilter_range_variable_has_total_length($3); + if(a_has_length) + a_len = dfilter_get_range_variable_total_length($1); + if(b_has_length) + b_len = dfilter_get_range_variable_total_length($3); + + if (!check_range_variable_sanity($1)) { YYERROR; } - if (!check_bytes_variable_sanity($3)) { + if (!check_range_variable_sanity($3)) { YYERROR; } - if (a_len != b_len) { + if (a_has_length && b_has_length && a_len != b_len) { dfilter_fail("Fields \"%s\" and \"%s\" are being compared with " "disparate lengths of %u byte%s and %u byte%s.", dfilter_get_variable_abbrev($1), @@ -548,18 +571,74 @@ string_variable: T_FT_STRING { $$ = dfilter_mknode_string_variable($1.id); } ; -bytes_variable: T_FT_BYTES T_VAL_BYTE_RANGE +bytes_variable: T_FT_BYTES TOK_BRA range TOK_KET { - $$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length, FALSE); + $$ = dfilter_mknode_bytes_variable($1.id,$3); } | T_FT_BYTES { - $$ = dfilter_mknode_bytes_variable($1.id, 0, 0, TRUE); + $$ = dfilter_mknode_bytes_variable($1.id, NULL); } ; + +range: T_VAL_BYTE_STRING + { + drange* dr; + drange_node* drnode; + gboolean success; + dr = drange_new(); + drnode = byte_string_to_drange_node($1,&success); + if(success == FALSE){ + dfilter_fail("%s is not a range",$1); + YYERROR; + } + drange_prepend_drange_node(dr,drnode); + $$ = dr; + } + | T_VAL_BYTE_STRING TOK_COMMA range + { + drange_node* drnode; + gboolean success; + drnode = byte_string_to_drange_node($1,&success); + if(success == FALSE){ + dfilter_fail("%s is not a range",$1); + YYERROR; + } + drange_prepend_drange_node($3,drnode); + $$ = $3; + } + | T_VAL_UNQUOTED_STRING + { + drange* dr; + drange_node* drnode; + gboolean success; + + dr = drange_new(); + drnode = string_to_drange_node($1,&success); + if(success == FALSE){ + dfilter_fail("%s is not a range",$1); + YYERROR; + } + drange_prepend_drange_node(dr,drnode); + $$ = dr; + } + | T_VAL_UNQUOTED_STRING TOK_COMMA range + { + drange_node* drnode; + gboolean success; + drnode = string_to_drange_node($1,&success); + if(success == FALSE){ + dfilter_fail("%s is not a range",$1); + YYERROR; + } + drange_prepend_drange_node($3,drnode); + $$ = $3; + } + ; + variable_name: any_variable_type { GNode *variable; @@ -792,10 +871,11 @@ } static GNode* -dfilter_mknode_bytes_variable(gint id, gint offset, guint length, gboolean to_the_end) +dfilter_mknode_bytes_variable(gint id, drange* range) { dfilter_node *node; GNode *gnode; + range = null_to_drange(range); node = g_mem_chunk_alloc(global_df->node_memchunk); node->ntype = variable; @@ -804,62 +884,12 @@ node->fill_array_value_func = NULL; node->check_relation_func = check_relation_bytes; node->value.variable = id; - node->offset = offset; - node->length = length; - node->to_the_end = to_the_end; + node->range = range; gnode = g_node_new(node); - + return gnode; } -/* Gets length of variable represented by node from proto_register */ -static gint -dfilter_get_bytes_variable_field_registered_length(GNode *gnode) -{ - dfilter_node *node = gnode->data; - - /* Is this really a bytes_variable? */ - g_assert(node->fill_array_variable_func == fill_array_bytes_variable); - - return proto_registrar_get_length(node->value.variable); -} - -/* Sets the length of a bytes_variable node */ -static void -dfilter_set_bytes_variable_length(GNode *gnode, guint length) -{ - dfilter_node *node = gnode->data; - - /* Is this really a bytes_variable? */ - g_assert(node->fill_array_variable_func == fill_array_bytes_variable); - - node->length = length; -} - -/* Gets the length of a bytes_variable node */ -static guint -dfilter_get_bytes_variable_length(GNode *gnode) -{ - dfilter_node *node = gnode->data; - - /* Is this really a bytes_variable? */ - g_assert(node->fill_array_variable_func == fill_array_bytes_variable); - - return node->length; -} - -/* Gets the offset of a bytes_variable node */ -static guint -dfilter_get_bytes_variable_offset(GNode *gnode) -{ - dfilter_node *node = gnode->data; - - /* Is this really a bytes_variable? */ - g_assert(node->fill_array_variable_func == fill_array_bytes_variable); - - return node->offset; -} - static char* dfilter_get_variable_abbrev(GNode *gnode) { @@ -1166,26 +1196,184 @@ } +/* We aren't really trying to convert a byte_string into a drange_node, + * but the scanner may have mistaken a range like 23:25 for a + * byte string, so we correct for that here ( as the alternative + * involves a MAJOR overhaul of a lot of other code. + */ +static drange_node* byte_string_to_drange_node(gchar* s, gboolean *success){ + drange_node* drnode; + gint str_len, offset, length; + gboolean is_dash; + offset = 0; + length = 0; + is_dash = FALSE; + str_len = strlen(s); + drnode = NULL; + *success = FALSE; + if(str_len < 6){ /* are we any bigger than xx:yy ? */ + drnode = string_to_drange_node(s,success); + } + return drnode; +} + +/* convert a string like i:j or i-j into a drange_node */ + +static drange_node* string_to_drange_node(gchar* s, gboolean *success){ + + drange_node* drnode; + gchar **str_array,*endptr; + gint str_len, offset, length,split_len; + gboolean is_dash,to_the_end; + offset = 0; + length = 0; + is_dash = FALSE; + to_the_end = FALSE; + + str_len = strlen(s); + drnode = NULL; + *success = FALSE; + + str_array = g_strsplit(s,":",2); + split_len = strlen(str_array[0]); + if( ( str_array[0] != NULL ) && ( split_len != str_len )){ + offset = strtol(str_array[0],&endptr,10); + if( *endptr == '\0'){ + if(str_array[1] != NULL){ + length = strtol(str_array[1],&endptr,10); + if(*endptr == '\0'){ + *success = TRUE; + } + } + } + } + else { + g_strfreev(str_array); + str_array = g_strsplit(s,"-",2); + split_len = strlen(str_array[0]); + if( ( str_array[0] != NULL ) && ( split_len != str_len )){ + is_dash = TRUE; + offset = strtol(str_array[0],&endptr,10); + if( *endptr == '\0'){ + if(str_array[1] != NULL){ + length = strtol(str_array[1],&endptr,10); + if(*endptr == '\0'){ + *success = TRUE; + } + } + else if(s[str_len-1] == '-'){ + to_the_end = TRUE; + *success = TRUE; + is_dash = FALSE; + } + } + } + else { + offset = strtol(str_array[0],&endptr,10); + length = 1; + if( *endptr == '\0'){ + *success = TRUE; + } + } + } + g_strfreev(str_array); + if(is_dash){ + length = (length + 1) - offset; + } + if( *success ) { + drnode = drange_node_new(); + drange_node_set_offset(drnode,offset); + drange_node_set_length(drnode,length); + drange_node_set_to_the_end(drnode,to_the_end); + } + return drnode; +} + +static gboolean dfilter_is_range_variable(GNode *gnode){ + dfilter_node *node = gnode->data; + return (node->fill_array_variable_func == fill_array_bytes_variable); +} + +static gboolean dfilter_range_variable_has_total_length(GNode *gnode){ + dfilter_node *node = gnode->data; + return (drange_has_total_length(node->range)); +} + +static gint dfilter_get_range_variable_total_length(GNode *gnode){ + dfilter_node *node = gnode->data; + return (drange_get_total_length(node->range)); +} + +/* Gets length of variable represented by node from proto_register */ +static gint +dfilter_get_range_variable_field_registered_length(GNode *gnode) +{ + dfilter_node *node = gnode->data; + + /* Is this really a range_variable? */ + g_assert(dfilter_is_range_variable(gnode)); + + return proto_registrar_get_length(node->value.variable); +} + static int -check_bytes_variable_sanity(GNode *gnode) +check_range_variable_sanity(GNode *gnode) { - int a_off, a_len, reg_len, t_off; - a_off = dfilter_get_bytes_variable_offset(gnode); - a_len = dfilter_get_bytes_variable_length(gnode); - reg_len = dfilter_get_bytes_variable_field_registered_length(gnode); - - if (reg_len > 0) { - t_off = a_off >= 0 ? a_off : reg_len + a_off; - if (t_off + a_len > reg_len) { - dfilter_fail("The \"%s\" field is only %u byte%s wide, but " - "%u byte%s %s supplied.", - dfilter_get_variable_abbrev(gnode), - reg_len, plurality(reg_len, "", "s"), - a_len, plurality(a_len, "", "s"), - plurality(a_len, "was", "were")); - return 0; - } - } - return 1; + dfilter_node* node; + gboolean success; + check_range_variable_sanity_iterator_arg* arg; + + arg = g_malloc(sizeof(check_range_variable_sanity_iterator_arg)); + + node = gnode->data; + arg->max_length = dfilter_get_range_variable_field_registered_length(gnode); + success = TRUE; + arg->success = &success; + arg->variable_abbrev = dfilter_get_variable_abbrev(gnode); + drange_foreach_drange_node(node->range,check_range_variable_sanity_iterator, arg); + g_free(arg); + return ( success ); +} + +static void check_range_variable_sanity_iterator(gpointer data, gpointer user_data){ + check_range_variable_sanity_iterator_arg* arg; + drange_node* drnode; + gboolean *success_ptr; + gint a_off, a_len, a_to_the_end,t_off; + arg = (check_range_variable_sanity_iterator_arg*)user_data; + + success_ptr = arg->success; + if(*(success_ptr) == TRUE){ + drnode = (drange_node*)data; + a_off = drange_node_get_offset(drnode); + a_len = drange_node_get_length(drnode); + a_to_the_end = drange_node_get_to_the_end(drnode); + if(arg->max_length > 0){ + t_off = a_off >= 0 ? a_off : arg->max_length + a_off; + if( a_to_the_end == FALSE && ( t_off + a_len > arg->max_length ) ){ + dfilter_fail("The \"%s\" field is only %u byte%s wide, but " + "%u byte%s %s supplied.", + arg->variable_abbrev, + arg->max_length, plurality(arg->max_length, "", "s"), + a_len, plurality(a_len, "", "s"), + plurality(a_len, "was", "were")); + *(success_ptr) = FALSE; + } + } + } +} + +static drange* null_to_drange(drange* range){ + drange* dr; + drange_node* drnode; + dr = range; + if(dr == NULL){ + drnode = drange_node_new(); + drange_node_set_offset(drnode,0); + drange_node_set_to_the_end(drnode,TRUE); + dr = drange_new(); + drange_prepend_drange_node(dr,drnode); + } + return dr; } Index: epan/dfilter-int.h =================================================================== RCS file: /cvsroot/ethereal/epan/dfilter-int.h,v retrieving revision 1.2 diff -u -r1.2 dfilter-int.h --- dfilter-int.h 2000/12/22 12:05:36 1.2 +++ dfilter-int.h 2000/12/26 06:58:35 @@ -31,6 +31,8 @@ #include "ipv4.h" #endif +#include "drange.h" + /* in dfilter-scanner.l */ GByteArray *byte_str_to_guint8_array(const char *s); void dfilter_scanner_text(char*); @@ -140,6 +142,9 @@ /* used to indicate range should go to end of sequence */ gboolean to_the_end; + + /* used to handle many ranges */ + drange* range; } dfilter_node; /* lookup an abbreviation in our token hash, returing the ID # */ Index: epan/dfilter-scanner.l =================================================================== RCS file: /cvsroot/ethereal/epan/dfilter-scanner.l,v retrieving revision 1.1 diff -u -r1.1 dfilter-scanner.l --- dfilter-scanner.l 2000/09/27 04:54:48 1.1 +++ dfilter-scanner.l 2000/12/26 06:58:35 @@ -115,53 +115,9 @@ ge|\>\= { dfilter_lval.operand = TOK_GE; return TOK_GE; } lt|\< { dfilter_lval.operand = TOK_LT; return TOK_LT; } le|\<\= { dfilter_lval.operand = TOK_LE; return TOK_LE; } - -\[{whitespace}*-?[0-9]+{whitespace}*:{whitespace}*[0-9]+{whitespace}*\] { /* range [ x : y ] */ - - char *byterange_string = g_strdup(yytext); - char *s = byterange_string + 1; /* I don't want the first '[' */ - char *p; - - /* Get the offset from the string */ - if ((p = strtok(s, ":"))) { - dfilter_lval.byte_range.offset = strtol(p, NULL, 10); - } - else { - g_free(byterange_string); - return 0; - } - - /* Get the Length from the string */ - if ((p = strtok(NULL, "]"))) { - dfilter_lval.byte_range.length = strtoul(p, NULL, 10); - } - else { - g_free(byterange_string); - return 0; - } - g_free(byterange_string); - return T_VAL_BYTE_RANGE; -} - -\[{whitespace}*-?[0-9]+{whitespace}*\] { /* range [ x ] */ - - char *byterange_string = g_strdup(yytext); - char *s = byterange_string + 1; /* I don't want the first '[' */ - char *p; - - /* Get the offset from the string */ - if ((p = strtok(s, "]"))) { - dfilter_lval.byte_range.offset = strtol(p, NULL, 10); - } - else { - g_free(byterange_string); - return 0; - } - - dfilter_lval.byte_range.length = 0; - g_free(byterange_string); - return T_VAL_BYTE_RANGE; -} +\[ { dfilter_lval.operand = TOK_BRA; return TOK_BRA; } +\] { dfilter_lval.operand = TOK_KET; return TOK_KET; } +\, { dfilter_lval.operand = TOK_COMMA; return TOK_COMMA; } {hex}({hexsep}{hex})+ { /* byte string, any length */ dfilter_lval.string = g_strdup(yytext); Index: epan/dfilter.c =================================================================== RCS file: /cvsroot/ethereal/epan/dfilter.c,v retrieving revision 1.3 diff -u -r1.3 dfilter.c --- dfilter.c 2000/12/22 12:05:36 1.3 +++ dfilter.c 2000/12/26 06:58:36 @@ -44,6 +44,9 @@ #include "dfilter-int.h" #include "dfilter-grammar.h" +/* This should eventually be removed */ +#include "strutil.h" + int dfilter_parse(void); /* yacc entry-point */ #define DFILTER_LEX_ABBREV_OFFSET 2000 @@ -58,6 +61,7 @@ int bytes_offset = 0; int bytes_length = 0; gboolean bytes_to_the_end = FALSE; +drange* current_range = NULL; YYSTYPE yylval; @@ -72,6 +76,14 @@ static GArray* get_values_from_dfilter(dfilter_node *dnode, GNode *gnode); static gboolean check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree); static void clear_byte_array(gpointer data, gpointer user_data); +static void pack_byte_array(gpointer data, gpointer user_data); + +typedef struct _pack_byte_array_arg { + GByteArray* barray; + drange* dr; + field_info* finfo; + const guint8* pd; +} pack_byte_array_arg; /* this is not so pretty. I need my own g_array "function" (macro) to * retreive the pointer to the data stored in an array cell. I need this @@ -139,7 +151,6 @@ { dfilter *df; int retval; - g_assert(dfilter_text != NULL); df = dfilter_new(); @@ -165,7 +176,6 @@ * so treat that as a parse error. */ if (dfilter_error_msg != NULL) retval = 1; - if (retval != 0) { if (dfilter_error_msg == NULL) { snprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf), @@ -174,7 +184,6 @@ dfilter_error_msg = &dfilter_error_msg_buf[0]; } } - /* Set global_df to NULL just to be tidy. */ global_df = NULL; @@ -430,8 +439,7 @@ dfilter_node *node_b = (dfilter_node*) (b->data); GArray *vals_a, *vals_b; gboolean retval; - - + if (node_a->ntype == variable) vals_a = get_values_from_ptree(node_a, ptree, pd); else @@ -455,7 +463,6 @@ g_array_free(vals_a, FALSE); g_array_free(vals_b, FALSE); - return retval; } @@ -489,6 +496,8 @@ bytes_length = dnode->length; bytes_to_the_end = dnode->to_the_end; + current_range = dnode->range; + /* Cull the finfos from the proto_tree */ finfo_array = proto_get_finfo_ptr_array(ptree, dnode->value.variable); if (!finfo_array) { @@ -550,38 +559,15 @@ void fill_array_bytes_variable(field_info *finfo, GArray *array, const guint8 *pd) { - GByteArray *barray; - guint read_start, pkt_end, read_len; - - if (bytes_offset < 0) { - /* Handle negative byte offsets */ - bytes_offset = finfo->length + bytes_offset; - if (bytes_offset < 0) { - return; - } - } - - /* Check to make sure offset exists for this field */ - if (bytes_offset >= finfo->length) { - return; - } - - pkt_end = finfo->start + finfo->length; - read_start = finfo->start + bytes_offset; - if(bytes_to_the_end){ - read_len = pkt_end - read_start;; - } - else { - read_len = bytes_length; - } - /* Check to make sure entire length requested is inside field */ - if (pkt_end < read_start + read_len) { - return; - } - - barray = g_byte_array_new(); - g_byte_array_append(barray, pd + read_start, read_len); - g_array_append_val(array, barray); + pack_byte_array_arg* arg; + arg = g_malloc(sizeof(pack_byte_array_arg)); + arg->barray = g_byte_array_new(); + arg->dr = current_range; + arg->finfo = finfo; + arg->pd = pd; + drange_foreach_drange_node(arg->dr,pack_byte_array,arg); + g_array_append_val(array,arg->barray); + g_free(arg); } static GArray* @@ -985,7 +971,6 @@ len_a = a->len; len_b = b->len; - switch(operand) { case TOK_EQ: for(i = 0; i < len_a; i++) { @@ -1083,4 +1068,47 @@ g_assert_not_reached(); return FALSE; } + +static void pack_byte_array(gpointer data, gpointer user_data){ + pack_byte_array_arg* arg; + drange_node* drnode; + guint read_start, pkt_end, read_len; + gboolean to_the_end; + gint offset, length; + arg = (pack_byte_array_arg*)user_data; + drnode = (drange_node*)data; + + offset = drange_node_get_offset(drnode); + length = drange_node_get_length(drnode); + to_the_end = drange_node_get_to_the_end(drnode); + + if (offset < 0) { + /* Handle negative byte offsets */ + offset = arg->finfo->length + offset; + if (offset < 0) { + return; + } + } + + /* Check to make sure offset exists for this field */ + if (offset >= arg->finfo->length) { + return; + } + + pkt_end = arg->finfo->start + arg->finfo->length; + read_start = arg->finfo->start + offset; + if(to_the_end){ + read_len = pkt_end - read_start;; + } + else { + read_len = length; + } + /* Check to make sure entire length requested is inside field */ + if (pkt_end < read_start + read_len) { + return; + } + + arg->barray = g_byte_array_append(arg->barray, arg->pd + read_start, read_len); + return; +}
- Prev by Date: Re: [Ethereal-dev] (no subject)
- Next by Date: [Ethereal-dev] A query...
- Previous by thread: [Ethereal-dev] Help: compiling ether under win
- Next by thread: [Ethereal-dev] A query...
- Index(es):