From Harald Welte:
[obnox/wireshark/wip.git] / epan / tvbparse.h
index b2e982f17b26369d6f7239f68427d00fff6c2388..c4560f1d014e8fe946d2427add663d3c2ce24143 100644 (file)
@@ -1,26 +1,25 @@
-
 /* tvbparse.h
 *
 * an API for text tvb parsers
 *
-* Copyright 2005, Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
+* Copyright 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
 *
 * $Id$
 *
-* Ethereal - Network traffic analyzer
-* By Gerald Combs <gerald@ethereal.com>
+* Wireshark - Network traffic analyzer
+* By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
-* 
+*
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
-* 
+*
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 /*
  The intention behind this is to ease the writing of dissectors that have to
  parse text without the need of writing into buffers.
+
  It was originally written to avoid using lex and yacc for the xml dissector.
+
  the parser is able to look for wanted elements these can be:
+
  simple tokens:
  - a char out of a string of needles
  - a char not belonging to a string of needles
  - a string
  - a caseless string
  - all the characters up to a certain wanted element (included or excluded)
+
  composed elements:
  - one of a given group of wanted elements
  - a sequence of wanted elements
  - some (at least one) instances of a wanted element
+
  Once a wanted element is successfully extracted, by either tvbparse_get or
- tvbparse_find, the parser will invoke a given callback 
+ tvbparse_find, the parser will invoke a given callback
  before and another one after every of its component's subelement's callbacks
  are being called.
+
  If tvbparse_get or tvbparse_find fail to extract the wanted element the
  subelements callbacks are not going to be invoked.
+
  The wanted elements are instantiated once by the proto_register_xxx function.
- The parser is isntantiated for every packet and it mantains its state.
+
+ The parser is instantiated for every packet and it mantains its state.
+
  The element's data is destroyed before the next packet is dissected.
  */
 
 #include <epan/tvbuff.h>
 #include <glib.h>
 
-/* a definition of something we want to look for */
+typedef struct _tvbparse_elem_t tvbparse_elem_t;
 typedef struct _tvbparse_wanted_t tvbparse_wanted_t;
-
-/* an instance of a per packet parser */
 typedef struct _tvbparse_t tvbparse_t;
 
-/* a matching token returned by either tvbparser_get or tvb_parser_find */
-typedef struct _tvbparse_elem_t {
-       int id;
-       
-       tvbuff_t* tvb;
-       int offset;
-       int len;
-       
-       void* data;
-       
-       struct _tvbparse_elem_t* sub;
-       
-       struct _tvbparse_elem_t* next;
-       struct _tvbparse_elem_t* last;
-       
-       const tvbparse_wanted_t* wanted;
-} tvbparse_elem_t;
 
 /*
  * a callback function to be called before or after an element has been
@@ -107,6 +87,89 @@ typedef struct _tvbparse_elem_t {
  */
 typedef void (*tvbparse_action_t)(void* tvbparse_data, const void* wanted_data, struct _tvbparse_elem_t* elem);
 
+typedef int (*tvbparse_condition_t)
+(tvbparse_t*, const int,
+ const tvbparse_wanted_t*,
+ tvbparse_elem_t**);
+
+
+typedef enum  {
+    TP_UNTIL_INCLUDE, /* last elem is included, its span is spent by the parser */
+    TP_UNTIL_SPEND, /* last elem is not included, but its span is spent by the parser */
+    TP_UNTIL_LEAVE /* last elem is not included, neither its span is spent by the parser */
+} until_mode_t;
+
+
+struct _tvbparse_wanted_t {
+       int id;
+       tvbparse_condition_t condition;
+
+       union {
+               const gchar* str;
+               struct _tvbparse_wanted_t** handle;
+               struct {
+                       union {
+                               gint64 i;
+                               guint64 u;
+                               gdouble f;
+                       } value;
+                       gboolean (*comp)(void*,const void*);
+                       void* (*extract)(tvbuff_t*,guint);
+               } number;
+               enum ftenum ftenum;
+               struct {
+                       until_mode_t mode;
+                       const tvbparse_wanted_t* subelem;
+               } until;
+               struct {
+                       GHashTable* table;
+                       struct _tvbparse_wanted_t* key;
+                       struct _tvbparse_wanted_t* other;
+               } hash;
+               GPtrArray* elems;
+               const tvbparse_wanted_t* subelem;
+               void* p;
+       } control;
+
+       int len;
+
+       guint min;
+       guint max;
+
+       const void* data;
+
+       tvbparse_action_t before;
+       tvbparse_action_t after;
+};
+
+/* an instance of a per packet parser */
+struct _tvbparse_t {
+       tvbuff_t* tvb;
+       int offset;
+       int end_offset;
+       void* data;
+       const tvbparse_wanted_t* ignore;
+};
+
+
+/* a matching token returned by either tvbparser_get or tvb_parser_find */
+struct _tvbparse_elem_t {
+       int id;
+
+       tvbuff_t* tvb;
+       int offset;
+       int len;
+
+       void* data;
+
+       struct _tvbparse_elem_t* sub;
+
+       struct _tvbparse_elem_t* next;
+       struct _tvbparse_elem_t* last;
+
+       const tvbparse_wanted_t* wanted;
+};
+
 
 /*
  * definition of wanted token types
@@ -127,7 +190,7 @@ typedef void (*tvbparse_action_t)(void* tvbparse_data, const void* wanted_data,
  * When looked for it returns a simple element one character long if the char
  * at the current offset matches one of the the needles.
  */
-tvbparse_wanted_t* tvbparse_char(int id,
+tvbparse_wanted_t* tvbparse_char(const int id,
                                                                 const gchar* needles,
                                                                 const void* private_data,
                                                                 tvbparse_action_t before_cb,
@@ -139,7 +202,7 @@ tvbparse_wanted_t* tvbparse_char(int id,
  * When looked for it returns a simple element one character long if the char
  * at the current offset does not match one of the the needles.
  */
-tvbparse_wanted_t* tvbparse_not_char(int id,
+tvbparse_wanted_t* tvbparse_not_char(const int id,
                                                                         const gchar* needle,
                                                                         const void* private_data,
                                                                         tvbparse_action_t before_cb,
@@ -150,12 +213,12 @@ tvbparse_wanted_t* tvbparse_not_char(int id,
  *
  * When looked for it returns a simple element one or more characters long if
  * one or more char(s) starting from the current offset match one of the needles.
- * An element will be returned if at least min_len chars are given (1 if it's 0) 
+ * An element will be returned if at least min_len chars are given (1 if it's 0)
  * It will get at most max_len chars or as much as it can if max_len is 0.
  */
-tvbparse_wanted_t* tvbparse_chars(int id,
-                                                                 guint min_len,
-                                                                 guint max_len,
+tvbparse_wanted_t* tvbparse_chars(const int id,
+                                                                 const guint min_len,
+                                                                 const guint max_len,
                                                                  const gchar* needles,
                                                                  const void* private_data,
                                                                  tvbparse_action_t before_cb,
@@ -167,12 +230,12 @@ tvbparse_wanted_t* tvbparse_chars(int id,
  * When looked for it returns a simple element one or more characters long if
  * one or more char(s) starting from the current offset do not match one of the
  * needles.
- * An element will be returned if at least min_len chars are given (1 if it's 0) 
+ * An element will be returned if at least min_len chars are given (1 if it's 0)
  * It will get at most max_len chars or as much as it can if max_len is 0.
  */
-tvbparse_wanted_t* tvbparse_not_chars(int id,
-                                                                         guint min_len,
-                                                                         guint max_len,
+tvbparse_wanted_t* tvbparse_not_chars(const int id,
+                                                                         const guint min_len,
+                                                                         const guint max_len,
                                                                          const gchar* needles,
                                                                          const void* private_data,
                                                                          tvbparse_action_t before_cb,
@@ -182,9 +245,9 @@ tvbparse_wanted_t* tvbparse_not_chars(int id,
  * a string element
  *
  * When looked for it returns a simple element if we have the given string at
- * the current offset 
+ * the current offset
  */
-tvbparse_wanted_t* tvbparse_string(int id,
+tvbparse_wanted_t* tvbparse_string(const int id,
                                                                   const gchar* string,
                                                                   const void* private_data,
                                                                   tvbparse_action_t before_cb,
@@ -194,9 +257,9 @@ tvbparse_wanted_t* tvbparse_string(int id,
  * casestring
  *
  * When looked for it returns a simple element if we have a matching string at
- * the current offset 
+ * the current offset
  */
-tvbparse_wanted_t* tvbparse_casestring(int id,
+tvbparse_wanted_t* tvbparse_casestring(const int id,
                                                                           const gchar* str,
                                                                           const void* data,
                                                                           tvbparse_action_t before_cb,
@@ -205,21 +268,25 @@ tvbparse_wanted_t* tvbparse_casestring(int id,
 /*
  * until
  *
- * When looked for it returns a simple element containing all the characters 
+ * When looked for it returns a simple element containing all the characters
  * found until the first match of the ending element if the ending element is
  * found.
  *
- * When looking for until elements it calls tvbparse_find so it can be very slow. 
+ * When looking for until elements it calls tvbparse_find so it can be very slow.
  *
  * It won't have a subelement, the ending's callbacks won't get called.
  */
-tvbparse_wanted_t* tvbparse_until(int id,
+
+/*
+ * op_mode values determine how the terminating element and the current offset
+ * of the parser are handled
+ */
+tvbparse_wanted_t* tvbparse_until(const int id,
                                                                  const void* private_data,
                                                                  tvbparse_action_t before_cb,
                                                                  tvbparse_action_t after_cb,
                                                                  const tvbparse_wanted_t* ending,
-                                                                 gboolean include_ending);
-
+                                                                 until_mode_t until_mode);
 
 /*
  * one_of
@@ -230,12 +297,25 @@ tvbparse_wanted_t* tvbparse_until(int id,
  * The list of candidates is terminated with a NULL
  *
  */
-tvbparse_wanted_t* tvbparse_set_oneof(int id,
+tvbparse_wanted_t* tvbparse_set_oneof(const int id,
                                                                          const void* private_data,
                                                                          tvbparse_action_t before_cb,
                                                                          tvbparse_action_t after_cb,
                                                                          ...);
 
+/*
+ * hashed
+ */
+tvbparse_wanted_t* tvbparse_hashed(const int id,
+                                                                  const void* data,
+                                                                  tvbparse_action_t before_cb,
+                                                                  tvbparse_action_t after_cb,
+                                                                  tvbparse_wanted_t* key,
+                                                                  tvbparse_wanted_t* other,
+                                                                  ...);
+
+void tvbparse_hashed_add(tvbparse_wanted_t* w, ...);
+
 /*
  * sequence
  *
@@ -246,11 +326,12 @@ tvbparse_wanted_t* tvbparse_set_oneof(int id,
  * The list of candidates is terminated with a NULL.
  *
  */
-tvbparse_wanted_t* tvbparse_set_seq(int id,
+tvbparse_wanted_t* tvbparse_set_seq(const int id,
                                                                        const void* private_data,
                                                                        tvbparse_action_t before_cb,
                                                                        tvbparse_action_t after_cb,
                                                                        ...);
+
 /*
  * some
  *
@@ -259,9 +340,9 @@ tvbparse_wanted_t* tvbparse_set_seq(int id,
  * a composed element is returned.
  *
  */
-tvbparse_wanted_t* tvbparse_some(int id,
-                                                                guint min,
-                                                                guint max,
+tvbparse_wanted_t* tvbparse_some(const int id,
+                                                                const guint min,
+                                                                const guint max,
                                                                 const void* private_data,
                                                                 tvbparse_action_t before_cb,
                                                                 tvbparse_action_t after_cb,
@@ -270,18 +351,62 @@ tvbparse_wanted_t* tvbparse_some(int id,
 #define tvbparse_one_or_more(id, private_data, before_cb, after_cb, wanted)\
        tvbparse_some(id, 1, G_MAXINT, private_data, before_cb, after_cb, wanted)
 
+
+/*
+ * handle
+ *
+ * this is a pointer to a pointer to a wanted element (that might have not
+ * been initialized yet) so that recursive structures
+ */
+tvbparse_wanted_t* tvbparse_handle(tvbparse_wanted_t** handle);
+
+#if 0
+
+enum ft_cmp_op {
+    TVBPARSE_CMP_GT,
+    TVBPARSE_CMP_GE,
+    TVBPARSE_CMP_EQ,
+    TVBPARSE_CMP_NE,
+    TVBPARSE_CMP_LE,
+    TVBPARSE_CMP_LT
+};
+
+/* not yet tested */
+tvbparse_wanted_t* tvbparse_ft(int id,
+                               const void* data,
+                               tvbparse_action_t before_cb,
+                               tvbparse_action_t after_cb,
+                               enum ftenum ftenum);
+
+/* not yet tested */
+tvbparse_wanted_t* tvbparse_end_of_buffer(int id,
+                                          const void* data,
+                                          tvbparse_action_t before_cb,
+                                          tvbparse_action_t after_cb);
+/* not yet tested */
+tvbparse_wanted_t* tvbparse_ft_numcmp(int id,
+                                      const void* data,
+                                      tvbparse_action_t before_cb,
+                                      tvbparse_action_t after_cb,
+                                      enum ftenum ftenum,
+                                      int little_endian,
+                                      enum ft_cmp_op ft_cmp_op,
+                                      ... );
+
+#endif
+
 /*  quoted
  *  this is a composed candidate, that will try to match a quoted string
  *  (included the quotes) including into it every escaped quote.
  *
  *  C strings are matched with tvbparse_quoted(-1,NULL,NULL,NULL,"\"","\\")
  */
-tvbparse_wanted_t* tvbparse_quoted(int id,
+tvbparse_wanted_t* tvbparse_quoted(const int id,
                                                                   const void* data,
                                                                   tvbparse_action_t before_cb,
                                                                   tvbparse_action_t after_cb,
-                                                                  char quote,
-                                                                  char escape);
+                                                                  const char quote,
+                                                                  const char escape);
 
 /*
  * a helper callback for quoted strings that will shrink the token to contain
@@ -294,30 +419,41 @@ void tvbparse_shrink_token_cb(void* tvbparse_data,
 
 
 
-
-
-
 /* initialize the parser (at every packet)
-* tvb: what are we parsing? 
-* offset: from where
-* len: for how many bytes
-* private_data: will be passed to the action callbacks 
-* ignore: a wanted token type to be ignored (the associated cb WILL be called when it matches)
-*/
+ * tvb: what are we parsing?
+ * offset: from where
+ * len: for how many bytes
+ * private_data: will be passed to the action callbacks
+ * ignore: a wanted token type to be ignored (the associated cb WILL be called when it matches)
+ */
 tvbparse_t* tvbparse_init(tvbuff_t* tvb,
-                                                 int offset,
+                                                 const int offset,
                                                  int len,
                                                  void* private_data,
                                                  const tvbparse_wanted_t* ignore);
 
 /* reset the parser */
-gboolean tvbparse_reset(tvbparse_t* tt, int offset, int len);
+gboolean tvbparse_reset(tvbparse_t* tt, const int offset, int len);
+
+guint tvbparse_curr_offset(tvbparse_t* tt);
+guint tvbparse_len_left(tvbparse_t* tt);
+
+
 
 /*
- * This ill look for the wanted token at the current offset or after any given
+ * This will look for the wanted token at the current offset or after any given
+ * number of ignored tokens returning FALSE if there's no match or TRUE if there
+ * is a match.
+ * The parser will be left in its original state and no callbacks will be called.
+ */
+gboolean tvbparse_peek(tvbparse_t* tt,
+                                          const tvbparse_wanted_t* wanted);
+
+/*
+ * This will look for the wanted token at the current offset or after any given
  * number of ignored tokens returning NULL if there's no match.
  * if there is a match it will set the offset of the current parser after
- * the end of the token 
+ * the end of the token
  */
 tvbparse_elem_t* tvbparse_get(tvbparse_t* tt,
                                                          const tvbparse_wanted_t* wanted);
@@ -327,8 +463,10 @@ tvbparse_elem_t* tvbparse_get(tvbparse_t* tt,
  * current offset.
  * This function is slow.
  */
-
 tvbparse_elem_t* tvbparse_find(tvbparse_t* tt,
                                                           const tvbparse_wanted_t* wanted);
 
+
+void tvbparse_tree_add_elem(proto_tree* tree, tvbparse_elem_t* curr);
+
 #endif