Fix some Dead Store (Dead assignement/Dead increment) Warning found by Clang
[obnox/wireshark/wip.git] / epan / tvbparse.h
1 /* tvbparse.h
2 *
3 * an API for text tvb parsers
4 *
5 * Copyright 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
6 *
7 * $Id$
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*
29  The intention behind this is to ease the writing of dissectors that have to
30  parse text without the need of writing into buffers.
31
32  It was originally written to avoid using lex and yacc for the xml dissector.
33
34  the parser is able to look for wanted elements these can be:
35
36  simple tokens:
37  - a char out of a string of needles
38  - a char not belonging to a string of needles
39  - a sequence of chars that belong to a set of chars
40  - a sequence of chars that do not belong to a set of chars
41  - a string
42  - a caseless string
43  - all the characters up to a certain wanted element (included or excluded)
44
45  composed elements:
46  - one of a given group of wanted elements
47  - a sequence of wanted elements
48  - some (at least one) instances of a wanted element
49
50  Once a wanted element is successfully extracted, by either tvbparse_get or
51  tvbparse_find, the parser will invoke a given callback
52  before and another one after every of its component's subelement's callbacks
53  are being called.
54
55  If tvbparse_get or tvbparse_find fail to extract the wanted element the
56  subelements callbacks are not going to be invoked.
57
58  The wanted elements are instantiated once by the proto_register_xxx function.
59
60  The parser is instantiated for every packet and it mantains its state.
61
62  The element's data is destroyed before the next packet is dissected.
63  */
64
65 #ifndef _TVB_PARSE_H_
66 #define _TVB_PARSE_H_
67
68 #include <epan/tvbuff.h>
69 #include <glib.h>
70
71 typedef struct _tvbparse_elem_t tvbparse_elem_t;
72 typedef struct _tvbparse_wanted_t tvbparse_wanted_t;
73 typedef struct _tvbparse_t tvbparse_t;
74
75
76 /*
77  * a callback function to be called before or after an element has been
78  * successfuly extracted.
79  *
80  * Note that if the token belongs to a composed token the callbacks of the
81  * components won't be called unless the composed token is successfully
82  * extracted.
83  *
84  * tvbparse_data: the private data of the parser
85  * wanted_data: the private data of the wanted element
86  * elem: the extracted element
87  */
88 typedef void (*tvbparse_action_t)(void* tvbparse_data, const void* wanted_data, struct _tvbparse_elem_t* elem);
89
90 typedef int (*tvbparse_condition_t)
91 (tvbparse_t*, const int,
92  const tvbparse_wanted_t*,
93  tvbparse_elem_t**);
94
95
96 typedef enum  {
97     TP_UNTIL_INCLUDE, /* last elem is included, its span is spent by the parser */
98     TP_UNTIL_SPEND, /* last elem is not included, but its span is spent by the parser */
99     TP_UNTIL_LEAVE /* last elem is not included, neither its span is spent by the parser */
100 } until_mode_t;
101
102
103 struct _tvbparse_wanted_t {
104         int id;
105         tvbparse_condition_t condition;
106
107         union {
108                 const gchar* str;
109                 struct _tvbparse_wanted_t** handle;
110                 struct {
111                         union {
112                                 gint64 i;
113                                 guint64 u;
114                                 gdouble f;
115                         } value;
116                         gboolean (*comp)(void*,const void*);
117                         void* (*extract)(tvbuff_t*,guint);
118                 } number;
119                 enum ftenum ftenum;
120                 struct {
121                         until_mode_t mode;
122                         const tvbparse_wanted_t* subelem;
123                 } until;
124                 struct {
125                         GHashTable* table;
126                         struct _tvbparse_wanted_t* key;
127                         struct _tvbparse_wanted_t* other;
128                 } hash;
129                 GPtrArray* elems;
130                 const tvbparse_wanted_t* subelem;
131                 void* p;
132         } control;
133
134         int len;
135
136         guint min;
137         guint max;
138
139         const void* data;
140
141         tvbparse_action_t before;
142         tvbparse_action_t after;
143 };
144
145 /* an instance of a per packet parser */
146 struct _tvbparse_t {
147         tvbuff_t* tvb;
148         int offset;
149         int end_offset;
150         void* data;
151         const tvbparse_wanted_t* ignore;
152 };
153
154
155 /* a matching token returned by either tvbparser_get or tvb_parser_find */
156 struct _tvbparse_elem_t {
157         int id;
158
159         tvbuff_t* tvb;
160         int offset;
161         int len;
162
163         void* data;
164
165         struct _tvbparse_elem_t* sub;
166
167         struct _tvbparse_elem_t* next;
168         struct _tvbparse_elem_t* last;
169
170         const tvbparse_wanted_t* wanted;
171 };
172
173
174 /*
175  * definition of wanted token types
176  *
177  * the following functions define the tokens we will be able to look for in a tvb
178  * common parameters are:
179  *
180  * id: an arbitrary id that will be copied to the eventual token (don't use 0)
181  * private_data: persistent data to be passed to the callback action (wanted_data)
182  * before_cb: an callback function to be called before those of the subelements
183  * after_cb: an callback function to be called after those of the subelements
184  */
185
186
187 /*
188  * a char element.
189  *
190  * When looked for it returns a simple element one character long if the char
191  * at the current offset matches one of the the needles.
192  */
193 tvbparse_wanted_t* tvbparse_char(const int id,
194                                                                  const gchar* needles,
195                                                                  const void* private_data,
196                                                                  tvbparse_action_t before_cb,
197                                                                  tvbparse_action_t after_cb);
198
199 /*
200  * a not_char element.
201  *
202  * When looked for it returns a simple element one character long if the char
203  * at the current offset does not match one of the the needles.
204  */
205 tvbparse_wanted_t* tvbparse_not_char(const int id,
206                                                                          const gchar* needle,
207                                                                          const void* private_data,
208                                                                          tvbparse_action_t before_cb,
209                                                                          tvbparse_action_t after_cb);
210
211 /*
212  * a chars element
213  *
214  * When looked for it returns a simple element one or more characters long if
215  * one or more char(s) starting from the current offset match one of the needles.
216  * An element will be returned if at least min_len chars are given (1 if it's 0)
217  * It will get at most max_len chars or as much as it can if max_len is 0.
218  */
219 tvbparse_wanted_t* tvbparse_chars(const int id,
220                                                                   const guint min_len,
221                                                                   const guint max_len,
222                                                                   const gchar* needles,
223                                                                   const void* private_data,
224                                                                   tvbparse_action_t before_cb,
225                                                                   tvbparse_action_t after_cb);
226
227 /*
228  * a not_chars element
229  *
230  * When looked for it returns a simple element one or more characters long if
231  * one or more char(s) starting from the current offset do not match one of the
232  * needles.
233  * An element will be returned if at least min_len chars are given (1 if it's 0)
234  * It will get at most max_len chars or as much as it can if max_len is 0.
235  */
236 tvbparse_wanted_t* tvbparse_not_chars(const int id,
237                                                                           const guint min_len,
238                                                                           const guint max_len,
239                                                                           const gchar* needles,
240                                                                           const void* private_data,
241                                                                           tvbparse_action_t before_cb,
242                                                                           tvbparse_action_t after_cb);
243
244 /*
245  * a string element
246  *
247  * When looked for it returns a simple element if we have the given string at
248  * the current offset
249  */
250 tvbparse_wanted_t* tvbparse_string(const int id,
251                                                                    const gchar* string,
252                                                                    const void* private_data,
253                                                                    tvbparse_action_t before_cb,
254                                                                    tvbparse_action_t after_cb);
255
256 /*
257  * casestring
258  *
259  * When looked for it returns a simple element if we have a matching string at
260  * the current offset
261  */
262 tvbparse_wanted_t* tvbparse_casestring(const int id,
263                                                                            const gchar* str,
264                                                                            const void* data,
265                                                                            tvbparse_action_t before_cb,
266                                                                            tvbparse_action_t after_cb);
267
268 /*
269  * until
270  *
271  * When looked for it returns a simple element containing all the characters
272  * found until the first match of the ending element if the ending element is
273  * found.
274  *
275  * When looking for until elements it calls tvbparse_find so it can be very slow.
276  *
277  * It won't have a subelement, the ending's callbacks won't get called.
278  */
279
280 /*
281  * op_mode values determine how the terminating element and the current offset
282  * of the parser are handled
283  */
284 tvbparse_wanted_t* tvbparse_until(const int id,
285                                                                   const void* private_data,
286                                                                   tvbparse_action_t before_cb,
287                                                                   tvbparse_action_t after_cb,
288                                                                   const tvbparse_wanted_t* ending,
289                                                                   until_mode_t until_mode);
290
291 /*
292  * one_of
293  *
294  * When looked for it will try to match to the given candidates and return a
295  * composed element whose subelement is the first match.
296  *
297  * The list of candidates is terminated with a NULL
298  *
299  */
300 tvbparse_wanted_t* tvbparse_set_oneof(const int id,
301                                                                           const void* private_data,
302                                                                           tvbparse_action_t before_cb,
303                                                                           tvbparse_action_t after_cb,
304                                                                           ...);
305
306 /*
307  * hashed
308  */
309 tvbparse_wanted_t* tvbparse_hashed(const int id,
310                                                                    const void* data,
311                                                                    tvbparse_action_t before_cb,
312                                                                    tvbparse_action_t after_cb,
313                                                                    tvbparse_wanted_t* key,
314                                                                    tvbparse_wanted_t* other,
315                                                                    ...);
316
317 void tvbparse_hashed_add(tvbparse_wanted_t* w, ...);
318
319 /*
320  * sequence
321  *
322  * When looked for it will try to match in order all the given candidates. If
323  * every candidate is found in the given order it will return a composed
324  * element whose subelements are the matcheed elemets.
325  *
326  * The list of candidates is terminated with a NULL.
327  *
328  */
329 tvbparse_wanted_t* tvbparse_set_seq(const int id,
330                                                                         const void* private_data,
331                                                                         tvbparse_action_t before_cb,
332                                                                         tvbparse_action_t after_cb,
333                                                                         ...);
334
335 /*
336  * some
337  *
338  * When looked for it will try to match the given candidate at least min times
339  * and at most max times. If the given candidate is matched at least min times
340  * a composed element is returned.
341  *
342  */
343 tvbparse_wanted_t* tvbparse_some(const int id,
344                                                                  const guint min,
345                                                                  const guint max,
346                                                                  const void* private_data,
347                                                                  tvbparse_action_t before_cb,
348                                                                  tvbparse_action_t after_cb,
349                                                                  const tvbparse_wanted_t* wanted);
350
351 #define tvbparse_one_or_more(id, private_data, before_cb, after_cb, wanted)\
352         tvbparse_some(id, 1, G_MAXINT, private_data, before_cb, after_cb, wanted)
353
354
355 /*
356  * handle
357  *
358  * this is a pointer to a pointer to a wanted element (that might have not
359  * been initialized yet) so that recursive structures
360  */
361 tvbparse_wanted_t* tvbparse_handle(tvbparse_wanted_t** handle);
362
363 #if 0
364
365 enum ft_cmp_op {
366     TVBPARSE_CMP_GT,
367     TVBPARSE_CMP_GE,
368     TVBPARSE_CMP_EQ,
369     TVBPARSE_CMP_NE,
370     TVBPARSE_CMP_LE,
371     TVBPARSE_CMP_LT
372 };
373
374 /* not yet tested */
375 tvbparse_wanted_t* tvbparse_ft(int id,
376                                const void* data,
377                                tvbparse_action_t before_cb,
378                                tvbparse_action_t after_cb,
379                                enum ftenum ftenum);
380
381 /* not yet tested */
382 tvbparse_wanted_t* tvbparse_end_of_buffer(int id,
383                                           const void* data,
384                                           tvbparse_action_t before_cb,
385                                           tvbparse_action_t after_cb);
386 /* not yet tested */
387 tvbparse_wanted_t* tvbparse_ft_numcmp(int id,
388                                       const void* data,
389                                       tvbparse_action_t before_cb,
390                                       tvbparse_action_t after_cb,
391                                       enum ftenum ftenum,
392                                       int little_endian,
393                                       enum ft_cmp_op ft_cmp_op,
394                                       ... );
395
396 #endif
397
398 /*  quoted
399  *  this is a composed candidate, that will try to match a quoted string
400  *  (included the quotes) including into it every escaped quote.
401  *
402  *  C strings are matched with tvbparse_quoted(-1,NULL,NULL,NULL,"\"","\\")
403  */
404 tvbparse_wanted_t* tvbparse_quoted(const int id,
405                                                                    const void* data,
406                                                                    tvbparse_action_t before_cb,
407                                                                    tvbparse_action_t after_cb,
408                                                                    const char quote,
409                                                                    const char escape);
410
411 /*
412  * a helper callback for quoted strings that will shrink the token to contain
413  * only the string andnot the quotes
414  */
415 void tvbparse_shrink_token_cb(void* tvbparse_data,
416                                                           const void* wanted_data,
417                                                           tvbparse_elem_t* tok);
418
419
420
421
422 /* initialize the parser (at every packet)
423  * tvb: what are we parsing?
424  * offset: from where
425  * len: for how many bytes
426  * private_data: will be passed to the action callbacks
427  * ignore: a wanted token type to be ignored (the associated cb WILL be called when it matches)
428  */
429 tvbparse_t* tvbparse_init(tvbuff_t* tvb,
430                                                   const int offset,
431                                                   int len,
432                                                   void* private_data,
433                                                   const tvbparse_wanted_t* ignore);
434
435 /* reset the parser */
436 gboolean tvbparse_reset(tvbparse_t* tt, const int offset, int len);
437
438 guint tvbparse_curr_offset(tvbparse_t* tt);
439 guint tvbparse_len_left(tvbparse_t* tt);
440
441
442
443 /*
444  * This will look for the wanted token at the current offset or after any given
445  * number of ignored tokens returning FALSE if there's no match or TRUE if there
446  * is a match.
447  * The parser will be left in its original state and no callbacks will be called.
448  */
449 gboolean tvbparse_peek(tvbparse_t* tt,
450                                            const tvbparse_wanted_t* wanted);
451
452 /*
453  * This will look for the wanted token at the current offset or after any given
454  * number of ignored tokens returning NULL if there's no match.
455  * if there is a match it will set the offset of the current parser after
456  * the end of the token
457  */
458 tvbparse_elem_t* tvbparse_get(tvbparse_t* tt,
459                                                           const tvbparse_wanted_t* wanted);
460
461 /*
462  * Like tvbparse_get but this will look for a wanted token even beyond the
463  * current offset.
464  * This function is slow.
465  */
466 tvbparse_elem_t* tvbparse_find(tvbparse_t* tt,
467                                                            const tvbparse_wanted_t* wanted);
468
469
470 void tvbparse_tree_add_elem(proto_tree* tree, tvbparse_elem_t* curr);
471
472 #endif