Wireshark  2.9.0-477-g68ec514b
The Wireshark network protocol analyzer
uat.h
1 /*
2  * uat.h
3  *
4  * User Accessible Tables
5  * Maintain an array of user accessible data structures
6  *
7  * (c) 2007, Luis E. Garcia Ontanon <luis@ontanon.org>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 2001 Gerald Combs
12  *
13  * SPDX-License-Identifier: GPL-2.0-or-later
14  */
15 
16 #ifndef __UAT_H__
17 #define __UAT_H__
18 
19 #include <stdlib.h>
20 
21 #include "ws_symbol_export.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif /* __cplusplus */
26 
27 /*
28  * UAT maintains a dynamically allocated table accessible to the user
29  * via a file and/or via GUI preference dialogs.
30  *
31  * The file is read from and written in the personal configuration directory. If
32  * there is no such file, defaults will be loaded from the global data
33  * directory.
34  *
35  * The behaviour of the table is controlled by a series of callbacks which
36  * the caller (e.g. a dissector) must provide.
37  *
38  * BEWARE that the user can change an UAT at (almost) any time (via the GUI).
39  * That is, pointers to records in an UAT are valid only during the call
40  * to the function that obtains them (do not store pointers to these records).
41  * The records contents are only guaranteed to be valid in the post_update_cb
42  * function. (Implementation detail: currently a race condition is possible
43  * where the UAT consumer (dissector code) tries to use the UAT while the GUI
44  * user frees a record resulting in use-after-free. This is not ideal and might
45  * be fixed later.)
46  *
47  * UATs are meant for short tables of user data (passwords and such), there is
48  * no quick access, you must iterate through them each time to fetch the record
49  * you are looking for.
50  *
51  * Only users via GUI or editing the file can add/remove records, your
52  * (dissector) code cannot.
53  */
54 
55 /* obscure data type to handle an uat */
56 typedef struct epan_uat uat_t;
57 /********************************************
58  * Callbacks:
59  * these instruct uat on how to deal with user info and data in records
60  ********************************************/
61 
62 /********
63  * Callbacks dealing with the entire table
64  ********/
65 
66 /*
67  * Post-Update CB
68  *
69  * To be called by the GUI code after to the table has being edited.
70  * Will be called once the user clicks the Apply or OK button
71  * optional
72  */
73 typedef void (*uat_post_update_cb_t)(void);
74 
75 
76 /********
77  * Callbacks dealing with records (these deal with entire records)
78  ********/
79 
87 typedef void* (*uat_copy_cb_t)(void *dest, const void *source, size_t len);
88 
97 typedef void (*uat_free_cb_t)(void *record);
98 
105 typedef void (*uat_reset_cb_t)(void);
106 
119 typedef gboolean (*uat_update_cb_t)(void *record, char **error);
120 
121 
122 /*******
123  * Callbacks for single fields (these deal with single values)
124  * the caller should provide one of these for every field!
125  ********/
126 
127 /*
128  * Check CB
129  * chk(record, ptr, len, chk_data, fld_data, &error)
130  *
131  * given an input string (ptr, len) checks if the value is OK for a field in the record.
132  * it will return TRUE if OK or else
133  * it will return FALSE and set *error to inform the user on what's
134  * wrong with the given input
135  * The error string must be allocated with g_malloc() or
136  * a routine that calls it.
137  * optional, if not given any input is considered OK and the set cb will be called
138  */
139 typedef gboolean (*uat_fld_chk_cb_t)(void *record, const char *ptr, unsigned len, const void *chk_data, const void *fld_data, char **error);
140 
141 /*
142  * Set Field CB
143  * set(record, ptr, len, set_data, fld_data)
144  *
145  * given an input string (ptr, len) sets the value of a field in the record,
146  * it is mandatory
147  */
148 typedef void (*uat_fld_set_cb_t)(void *record, const char *ptr, unsigned len, const void *set_data, const void *fld_data);
149 
150 /*
151  * Convert-to-string CB
152  * tostr(record, &out_ptr, &out_len, tostr_data, fld_data)
153  *
154  * given a record returns a string representation of the field
155  * mandatory
156  */
157 typedef void (*uat_fld_tostr_cb_t)(void *record, char **out_ptr, unsigned *out_len, const void *tostr_data, const void *fld_data);
158 
159 /***********
160  * Text Mode
161  *
162  * used for file and dialog representation of fields in columns,
163  * when the file is read it modifies the way the value is passed back to the fld_set_cb
164  * (see definition bellow for description)
165  ***********/
166 
167 typedef enum _uat_text_mode_t {
168  PT_TXTMOD_NONE,
169  /* not used */
170 
171  PT_TXTMOD_STRING,
172  /*
173  file:
174  reads:
175  ,"\x20\x00\x30", as " \00",3 ("space nil zero" of length 3)
176  ,"", as "",0
177  ,, as NULL,0
178  writes:
179  ,"\x20\x30\x00\x20", for " 0\0 ",4
180  ,"", for *, 0
181  ,, for NULL, *
182  dialog:
183  accepts \x?? and other escapes
184  gets "",0 on empty string
185  */
186  PT_TXTMOD_HEXBYTES,
187  /*
188  file:
189  reads:
190  ,A1b2C3d4, as "\xa1\xb2\xc3\xd4",4
191  ,, as NULL,0
192  writes:
193  ,, on NULL, *
194  ,a1b2c3d4, on "\xa1\xb2\xc3\xd4",4
195  dialog:
196  interprets the following input ... as ...:
197  "a1b2c3d4" as "\xa1\xb2\xc3\xd4",4
198  "a1 b2:c3d4" as "\xa1\xb2\xc3\xd4",4
199  "" as NULL,0
200  "invalid" as NULL,3
201  "a1b" as NULL, 1
202  */
203  PT_TXTMOD_ENUM,
204  /* Read/Writes/displays the string value (not number!) */
205 
206  PT_TXTMOD_COLOR,
207  /* Reads/Writes/display color in #RRGGBB format */
208 
209  PT_TXTMOD_FILENAME,
210  /* processed like a PT_TXTMOD_STRING, but shows a filename dialog */
211  PT_TXTMOD_DIRECTORYNAME,
212  /* processed like a PT_TXTMOD_STRING, but shows a directory dialog */
213  PT_TXTMOD_DISPLAY_FILTER,
214  /* processed like a PT_TXTMOD_STRING, but verifies display filter */
215  PT_TXTMOD_PROTO_FIELD,
216  /* processed like a PT_TXTMOD_STRING, but verifies protocol field name (e.g tcp.flags.syn) */
217  PT_TXTMOD_BOOL
218  /* Displays a checkbox for value */
219 } uat_text_mode_t;
220 
221 /*
222  * Fields
223  *
224  *
225  */
226 typedef struct _uat_field_t {
227  const char* name;
228  const char* title;
229  uat_text_mode_t mode;
230 
231  struct {
232  uat_fld_chk_cb_t chk;
233  uat_fld_set_cb_t set;
234  uat_fld_tostr_cb_t tostr;
235  } cb;
236 
237  struct {
238  const void* chk;
239  const void* set;
240  const void* tostr;
241  } cbdata;
242 
243  const void* fld_data;
244 
245  const char* desc;
246  struct _fld_data_t* priv;
247 } uat_field_t;
248 
249 #define FLDFILL NULL
250 #define UAT_END_FIELDS {NULL,NULL,PT_TXTMOD_NONE,{0,0,0},{0,0,0},0,0,FLDFILL}
251 
252 /*
253  * Flags to indicate what the settings in this UAT affect.
254  * This is used when UATs are changed interactively, to indicate what needs
255  * to be redone when the UAT is changed.
256  */
257 #define UAT_AFFECTS_DISSECTION 0x00000001 /* affects packet dissection */
258 #define UAT_AFFECTS_FIELDS 0x00000002 /* affects what named fields exist */
259 
279 WS_DLL_PUBLIC
280 uat_t* uat_new(const char* name,
281  size_t size,
282  const char* filename,
283  gboolean from_profile,
284  void* data_ptr,
285  guint* num_items_ptr,
286  guint flags,
287  const char* help,
288  uat_copy_cb_t copy_cb,
289  uat_update_cb_t update_cb,
290  uat_free_cb_t free_cb,
291  uat_post_update_cb_t post_update_cb,
292  uat_reset_cb_t reset_cb,
293  uat_field_t* flds_array);
294 
298 void uat_cleanup(void);
299 
307 WS_DLL_PUBLIC
308 gboolean uat_load(uat_t* uat_in, char** err);
309 
319 gboolean uat_load_str(uat_t* uat_in, char* entry, char** err);
320 
327 uat_t *uat_find(gchar *name);
328 
329 WS_DLL_PUBLIC
330 uat_t* uat_get_table_by_name(const char* name);
331 
332 /*
333  * Some common uat_fld_chk_cbs
334  */
335 WS_DLL_PUBLIC
336 gboolean uat_fld_chk_str(void*, const char*, unsigned, const void*, const void*, char** err);
337 gboolean uat_fld_chk_oid(void*, const char*, unsigned, const void*, const void*, char** err);
338 WS_DLL_PUBLIC
339 gboolean uat_fld_chk_proto(void*, const char*, unsigned, const void*, const void*, char** err);
340 WS_DLL_PUBLIC
341 gboolean uat_fld_chk_num_dec(void*, const char*, unsigned, const void*, const void*, char** err);
342 WS_DLL_PUBLIC
343 gboolean uat_fld_chk_num_hex(void*, const char*, unsigned, const void*, const void*, char** err);
344 WS_DLL_PUBLIC
345 gboolean uat_fld_chk_bool(void*, const char*, unsigned, const void*, const void*, char** err);
346 WS_DLL_PUBLIC
347 gboolean uat_fld_chk_enum(void*, const char*, unsigned, const void*, const void*, char**);
348 WS_DLL_PUBLIC
349 gboolean uat_fld_chk_range(void*, const char*, unsigned, const void*, const void*, char**);
350 WS_DLL_PUBLIC
351 gboolean uat_fld_chk_color(void*, const char*, unsigned, const void*, const void*, char**);
352 
353 typedef void (*uat_cb_t)(void* uat,void* user_data);
354 WS_DLL_PUBLIC
355 void uat_foreach_table(uat_cb_t cb,void* user_data);
356 void uat_unload_all(void);
357 
358 char* uat_undquote(const char* si, guint in_len, guint* len_p);
359 char* uat_unbinstring(const char* si, guint in_len, guint* len_p);
360 char* uat_unesc(const char* si, guint in_len, guint* len_p);
361 char* uat_esc(const char* buf, guint len);
362 
363 /* Some strings entirely made of ... already declared */
364 
365 WS_DLL_PUBLIC
366 gboolean uat_fld_chk_str_isprint(void*, const char*, unsigned, const void*, const void*, char**);
367 
368 WS_DLL_PUBLIC
369 gboolean uat_fld_chk_str_isalpha(void*, const char*, unsigned, const void*, const void*, char**);
370 
371 WS_DLL_PUBLIC
372 gboolean uat_fld_chk_str_isalnum(void*, const char*, unsigned, const void*, const void*, char**);
373 
374 WS_DLL_PUBLIC
375 gboolean uat_fld_chk_str_isdigit(void*, const char*, unsigned, const void*, const void*, char**);
376 
377 WS_DLL_PUBLIC
378 gboolean uat_fld_chk_str_isxdigit(void*, const char*, unsigned, const void*, const void*, char**);
379 
380 
381 /*
382  * Macros
383  * to define basic uat_fld_set_cbs, uat_fld_tostr_cbs
384  * for those elements in uat_field_t array
385  */
386 
387 #ifdef __cplusplus
388 #define UNUSED_PARAMETER(n)
389 #else
390 #define UNUSED_PARAMETER(n) n _U_
391 #endif
392 
393 /*
394  * CSTRING macros,
395  * a simple c-string contained in (((rec_t*)rec)->(field_name))
396  */
397 #define UAT_CSTRING_CB_DEF(basename,field_name,rec_t) \
398 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
399  char* new_buf = g_strndup(buf,len); \
400  g_free((((rec_t*)rec)->field_name)); \
401  (((rec_t*)rec)->field_name) = new_buf; } \
402 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
403  if (((rec_t*)rec)->field_name ) { \
404  *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
405  *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
406  } else { \
407  *out_ptr = g_strdup(""); *out_len = 0; } }
408 
409 #define UAT_FLD_CSTRING(basename,field_name,title,desc) \
410  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
411 
412 #define UAT_FLD_CSTRING_ISPRINT(basename,field_name,title,desc) \
413  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_str_isprint,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
414 
415 #define UAT_FLD_CSTRING_OTHER(basename,field_name,title,chk,desc) \
416  {#field_name, title, PT_TXTMOD_STRING,{ chk ,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
417 
418 /*
419  * FILENAME and DIRECTORYNAME,
420  * a simple c-string contained in (((rec_t*)rec)->(field_name))
421  */
422 #define UAT_FILENAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
423 
424 /* XXX UAT_FLD_FILENAME is currently unused. */
425 #define UAT_FLD_FILENAME(basename,field_name,title,desc) \
426  {#field_name, title, PT_TXTMOD_FILENAME,{uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
427 
428 /*
429  * Both the Qt and GTK+ UIs assume that we're opening a preexisting
430  * file. We might want to split the ..._FILENAME defines into
431  * ..._FILE_OPEN and ..._FILE_SAVE if we ever need to specify a
432  * file that we're creating.
433  */
434 #define UAT_FLD_FILENAME_OTHER(basename,field_name,title,chk,desc) \
435  {#field_name, title, PT_TXTMOD_FILENAME,{chk,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
436 
437 #define UAT_DIRECTORYNAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
438 
439 #define UAT_FLD_DIRECTORYNAME(basename,field_name,title,desc) \
440  {#field_name, title, PT_TXTMOD_DIRECTORYNAME,{uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
441 
442 /*
443  * DISPLAY_FILTER,
444  * a simple c-string contained in (((rec_t*)rec)->(field_name))
445  */
446 #define UAT_DISPLAY_FILTER_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
447 
448 #define UAT_FLD_DISPLAY_FILTER(basename,field_name,title,desc) \
449  {#field_name, title, PT_TXTMOD_DISPLAY_FILTER, {uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
450 
451 /*
452  * PROTO_FIELD,
453  * a simple c-string contained in (((rec_t*)rec)->(field_name))
454  */
455 #define UAT_PROTO_FIELD_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
456 
457 #define UAT_FLD_PROTO_FIELD(basename,field_name,title,desc) \
458  {#field_name, title, PT_TXTMOD_PROTO_FIELD, {uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
459 
460 /*
461  * OID - just a CSTRING with a specific check routine
462  */
463 #define UAT_FLD_OID(basename,field_name,title,desc) \
464  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_oid,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
465 
466 
467 /*
468  * LSTRING MACROS
469  */
470 #define UAT_LSTRING_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
471 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
472  char* new_val = uat_unesc(buf,len,&(((rec_t*)rec)->len_element)); \
473  g_free((((rec_t*)rec)->ptr_element)); \
474  (((rec_t*)rec)->ptr_element) = new_val; }\
475 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
476  if (((rec_t*)rec)->ptr_element ) { \
477  *out_ptr = uat_esc(((rec_t*)rec)->ptr_element, (((rec_t*)rec)->len_element)); \
478  *out_len = (unsigned)strlen(*out_ptr); \
479  } else { \
480  *out_ptr = g_strdup(""); \
481  *out_len = 0; \
482  } \
483 }
484 
485 #define UAT_FLD_LSTRING(basename,field_name,title, desc) \
486 {#field_name, title, PT_TXTMOD_STRING,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
487 
488 
489 /*
490  * BUFFER macros,
491  * a buffer_ptr contained in (((rec_t*)rec)->(field_name))
492  * and its len in (((rec_t*)rec)->(len_name))
493  */
494 #define UAT_BUFFER_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
495 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
496  char* new_buf = len ? (char *)g_memdup(buf,len) : NULL; \
497  g_free((((rec_t*)rec)->ptr_element)); \
498  (((rec_t*)rec)->ptr_element) = new_buf; \
499  (((rec_t*)rec)->len_element) = len; } \
500 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
501  *out_ptr = ((rec_t*)rec)->ptr_element ? (char*)g_memdup(((rec_t*)rec)->ptr_element,((rec_t*)rec)->len_element) : g_strdup(""); \
502  *out_len = ((rec_t*)rec)->len_element; }
503 
504 #define UAT_FLD_BUFFER(basename,field_name,title,desc) \
505  {#field_name, title, PT_TXTMOD_HEXBYTES,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
506 
507 
508 /*
509  * DEC Macros,
510  * a decimal number contained in
511  */
512 #define UAT_DEC_CB_DEF(basename,field_name,rec_t) \
513 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
514  char* tmp_str = g_strndup(buf,len); \
515  ((rec_t*)rec)->field_name = (guint)strtol(tmp_str,NULL,10); \
516  g_free(tmp_str); } \
517 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
518  *out_ptr = g_strdup_printf("%d",((rec_t*)rec)->field_name); \
519  *out_len = (unsigned)strlen(*out_ptr); }
520 
521 #define UAT_FLD_DEC(basename,field_name,title,desc) \
522  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
523 
524 #define UAT_FLD_NONE(basename,field_name,title,desc) \
525  {#field_name, title, PT_TXTMOD_NONE,{uat_fld_chk_num_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
526 
527 
528 /*
529  * HEX Macros,
530  * an hexadecimal number contained in
531  */
532 #define UAT_HEX_CB_DEF(basename,field_name,rec_t) \
533 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
534  char* tmp_str = g_strndup(buf,len); \
535  ((rec_t*)rec)->field_name = (guint)strtol(tmp_str,NULL,16); \
536  g_free(tmp_str); } \
537 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
538  *out_ptr = g_strdup_printf("%x",((rec_t*)rec)->field_name); \
539  *out_len = (unsigned)strlen(*out_ptr); }
540 
541 #define UAT_FLD_HEX(basename,field_name,title,desc) \
542 {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_hex,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
543 
544 /*
545  * BOOL Macros,
546  * an boolean value contained in
547  */
548 #define UAT_BOOL_CB_DEF(basename,field_name,rec_t) \
549 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
550  char* tmp_str = g_strndup(buf,len); \
551  if (g_strcmp0(tmp_str, "TRUE") == 0) \
552  ((rec_t*)rec)->field_name = 1; \
553  else \
554  ((rec_t*)rec)->field_name = 0; \
555  g_free(tmp_str); } \
556 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
557  *out_ptr = g_strdup_printf("%s",((rec_t*)rec)->field_name ? "TRUE" : "FALSE"); \
558  *out_len = (unsigned)strlen(*out_ptr); }
559 
560 #define UAT_FLD_BOOL(basename,field_name,title,desc) \
561 {#field_name, title, PT_TXTMOD_BOOL,{uat_fld_chk_bool,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
562 
563 /*
564  * ENUM macros
565  * enum_t: name = ((enum_t*)ptr)->strptr
566  * value = ((enum_t*)ptr)->value
567  * rec_t:
568  * value
569  */
570 #define UAT_VS_DEF(basename,field_name,rec_t,default_t,default_val,default_str) \
571 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
572  guint i; \
573  char* str = g_strndup(buf,len); \
574  const char* cstr; \
575  ((rec_t*)rec)->field_name = default_val; \
576  for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
577  if (g_str_equal(cstr,str)) { \
578  ((rec_t*)rec)->field_name = (default_t)((const value_string*)vs)[i].value; \
579  g_free(str); \
580  return; \
581  } \
582  } \
583  g_free(str); } \
584 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
585  guint i; \
586  for(i=0;((const value_string*)vs)[i].strptr;i++) { \
587  if ( ((const value_string*)vs)[i].value == ((rec_t*)rec)->field_name ) { \
588  *out_ptr = g_strdup(((const value_string*)vs)[i].strptr); \
589  *out_len = (unsigned)strlen(*out_ptr); \
590  return; \
591  } \
592  } \
593  *out_ptr = g_strdup(default_str); \
594  *out_len = (unsigned)strlen(default_str); }
595 
596 #define UAT_VS_CSTRING_DEF(basename,field_name,rec_t,default_val,default_str) \
597 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
598  guint i; \
599  char* str = g_strndup(buf,len); \
600  const char* cstr; \
601  ((rec_t*)rec)->field_name = default_val; \
602  for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
603  if (g_str_equal(cstr,str)) { \
604  ((rec_t*)rec)->field_name = g_strdup(((const value_string*)vs)[i].strptr); \
605  g_free(str); \
606  return; \
607  } \
608  } \
609  g_free(str);} \
610 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(vs), const void* UNUSED_PARAMETER(u2)) {\
611  if (((rec_t*)rec)->field_name ) { \
612  *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
613  *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
614  } else { \
615  *out_ptr = g_strdup(""); *out_len = 0; } }
616 
617 #define UAT_FLD_VS(basename,field_name,title,enum,desc) \
618  {#field_name, title, PT_TXTMOD_ENUM,{uat_fld_chk_enum,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{&(enum),&(enum),&(enum)},&(enum),desc,FLDFILL}
619 
620 
621 /*
622  * Color Macros,
623  * an #RRGGBB color value contained in
624  */
625 #define UAT_COLOR_CB_DEF(basename,field_name,rec_t) \
626 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
627  if (len < 1) { \
628  ((rec_t*)rec)->field_name = 0; \
629  return; \
630  } \
631  char* tmp_str = g_strndup(buf+1,len-1); \
632  ((rec_t*)rec)->field_name = (guint)strtol(tmp_str,NULL,16); \
633  g_free(tmp_str); } \
634 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
635  *out_ptr = g_strdup_printf("#%06X",((rec_t*)rec)->field_name); \
636  *out_len = (unsigned)strlen(*out_ptr); }
637 
638 #define UAT_FLD_COLOR(basename,field_name,title,desc) \
639 {#field_name, title, PT_TXTMOD_COLOR,{uat_fld_chk_color,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
640 
641 
642 /*
643  * PROTO macros
644  */
645 
646 #define UAT_PROTO_DEF(basename, field_name, dissector_field, name_field, rec_t) \
647 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
648  if (len) { \
649  gchar *tmp = g_strndup(buf,len); \
650  ((rec_t*)rec)->name_field = g_ascii_strdown(tmp, -1); \
651  g_free(tmp); \
652  g_strchug(((rec_t*)rec)->name_field); \
653  ((rec_t*)rec)->dissector_field = find_dissector(((rec_t*)rec)->name_field); \
654  } else { \
655  ((rec_t*)rec)->dissector_field = find_dissector("data"); \
656  ((rec_t*)rec)->name_field = NULL; \
657  } } \
658 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
659  if ( ((rec_t*)rec)->name_field ) { \
660  *out_ptr = g_strdup((((rec_t*)rec)->name_field)); \
661  *out_len = (unsigned)strlen(*out_ptr); \
662  } else { \
663  *out_ptr = g_strdup(""); *out_len = 0; } }
664 
665 
666 #define UAT_FLD_PROTO(basename,field_name,title,desc) \
667  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_proto,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
668 
669 /*
670  * RANGE macros
671  */
672 
673 #define UAT_RANGE_CB_DEF(basename,field_name,rec_t) \
674 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* u2) {\
675  char* rng = g_strndup(buf,len);\
676  range_convert_str(NULL, &(((rec_t*)rec)->field_name), rng,GPOINTER_TO_UINT(u2)); \
677  g_free(rng); \
678  } \
679 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
680  if ( ((rec_t*)rec)->field_name ) { \
681  *out_ptr = range_convert_range(NULL, ((rec_t*)rec)->field_name); \
682  *out_len = (unsigned)strlen(*out_ptr); \
683  } else { \
684  *out_ptr = g_strdup(""); *out_len = 0; } }
685 
686 
687 #define UAT_FLD_RANGE(basename,field_name,title,max,desc) \
688  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_range,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},\
689  {0,0,0},GUINT_TO_POINTER(max),desc,FLDFILL}
690 
691 #ifdef __cplusplus
692 }
693 #endif /* __cplusplus */
694 
695 #endif /* __UAT_H__ */
Definition: uat.h:226
Definition: uat-int.h:33
Definition: uat-int.h:39