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