Wireshark  4.3.0
The Wireshark network protocol analyzer
uat.h
Go to the documentation of this file.
1 
15 #ifndef __UAT_H__
16 #define __UAT_H__
17 
18 #include <stdlib.h>
19 
20 #include "ws_symbol_export.h"
21 #include <wsutil/strtoi.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 
125 typedef bool (*uat_update_cb_t)(void *record, char **error);
126 
127 
128 /*******
129  * Callbacks for single fields (these deal with single values)
130  * the caller should provide one of these for every field!
131  ********/
132 
133 /*
134  * Check CB
135  * chk(record, ptr, len, chk_data, fld_data, &error)
136  *
137  * given an input string (ptr, len) checks if the value is OK for a field in the record.
138  * it will return true if OK or else
139  * it will return false and set *error to inform the user on what's
140  * wrong with the given input
141  * The error string must be allocated with g_malloc() or
142  * a routine that calls it.
143  * optional, if not given any input is considered OK and the set cb will be called
144  */
145 typedef bool (*uat_fld_chk_cb_t)(void *record, const char *ptr, unsigned len, const void *chk_data, const void *fld_data, char **error);
146 
147 /*
148  * Set Field CB
149  * set(record, ptr, len, set_data, fld_data)
150  *
151  * given an input string (ptr, len) sets the value of a field in the record,
152  * it is mandatory
153  */
154 typedef void (*uat_fld_set_cb_t)(void *record, const char *ptr, unsigned len, const void *set_data, const void *fld_data);
155 
156 /*
157  * Convert-to-string CB
158  * tostr(record, &out_ptr, &out_len, tostr_data, fld_data)
159  *
160  * given a record returns a string representation of the field
161  * mandatory
162  */
163 typedef void (*uat_fld_tostr_cb_t)(void *record, char **out_ptr, unsigned *out_len, const void *tostr_data, const void *fld_data);
164 
165 /***********
166  * Text Mode
167  *
168  * used for file and dialog representation of fields in columns,
169  * when the file is read it modifies the way the value is passed back to the fld_set_cb
170  * (see definition bellow for description)
171  ***********/
172 
173 typedef enum _uat_text_mode_t {
174  PT_TXTMOD_NONE,
175  /* not used */
176 
177  PT_TXTMOD_STRING,
178  /*
179  file:
180  reads:
181  ,"\x20\x00\x30", as " \00",3 ("space nil zero" of length 3)
182  ,"", as "",0
183  ,, as NULL,0
184  writes:
185  ,"\x20\x30\x00\x20", for " 0\0 ",4
186  ,"", for *, 0
187  ,, for NULL, *
188  dialog:
189  accepts \x?? and other escapes
190  gets "",0 on empty string
191  */
192  PT_TXTMOD_HEXBYTES,
193  /*
194  file:
195  reads:
196  ,A1b2C3d4, as "\xa1\xb2\xc3\xd4",4
197  ,, as NULL,0
198  writes:
199  ,, on NULL, *
200  ,a1b2c3d4, on "\xa1\xb2\xc3\xd4",4
201  dialog:
202  interprets the following input ... as ...:
203  "a1b2c3d4" as "\xa1\xb2\xc3\xd4",4
204  "a1 b2:c3d4" as "\xa1\xb2\xc3\xd4",4
205  "" as NULL,0
206  "invalid" as NULL,3
207  "a1b" as NULL, 1
208  */
209  PT_TXTMOD_ENUM,
210  /* Read/Writes/displays the string value (not number!) */
211  PT_TXTMOD_DISSECTOR,
212  /* Shows a combobox of dissectors */
213 
214  PT_TXTMOD_COLOR,
215  /* Reads/Writes/display color in #RRGGBB format */
216 
217  PT_TXTMOD_FILENAME,
218  /* processed like a PT_TXTMOD_STRING, but shows a filename dialog */
219  PT_TXTMOD_DIRECTORYNAME,
220  /* processed like a PT_TXTMOD_STRING, but shows a directory dialog */
221  PT_TXTMOD_DISPLAY_FILTER,
222  /* processed like a PT_TXTMOD_STRING, but verifies display filter */
223  PT_TXTMOD_PROTO_FIELD,
224  /* processed like a PT_TXTMOD_STRING, but verifies protocol field name (e.g tcp.flags.syn) */
225  PT_TXTMOD_BOOL
226  /* Displays a checkbox for value */
227 } uat_text_mode_t;
228 
229 /*
230  * Fields
231  *
232  *
233  */
234 typedef struct _uat_field_t {
235  const char* name;
236  const char* title;
237  uat_text_mode_t mode;
238 
239  struct {
240  uat_fld_chk_cb_t chk;
241  uat_fld_set_cb_t set;
242  uat_fld_tostr_cb_t tostr;
243  } cb;
244 
245  struct {
246  const void* chk;
247  const void* set;
248  const void* tostr;
249  } cbdata;
250 
251  const void* fld_data;
252 
253  const char* desc;
254  struct _fld_data_t* priv;
255 } uat_field_t;
256 
257 #define FLDFILL NULL
258 #define UAT_END_FIELDS {NULL,NULL,PT_TXTMOD_NONE,{0,0,0},{0,0,0},0,0,FLDFILL}
259 
260 /*
261  * Flags to indicate what the settings in this UAT affect.
262  * This is used when UATs are changed interactively, to indicate what needs
263  * to be redone when the UAT is changed.
264  *
265  * UAT_AFFECTS_FIELDS does *not* trigger a redissection, so usually one
266  * will also want UAT_AFFECTS_DISSECTION. A rare exception is changing
267  * the defined dfilter macros.
268  */
269 #define UAT_AFFECTS_DISSECTION 0x00000001 /* affects packet dissection */
270 #define UAT_AFFECTS_FIELDS 0x00000002 /* affects what named fields exist */
271 
291 WS_DLL_PUBLIC
292 uat_t* uat_new(const char* name,
293  size_t size,
294  const char* filename,
295  bool from_profile,
296  void* data_ptr,
297  unsigned* num_items_ptr,
298  unsigned flags,
299  const char* help,
300  uat_copy_cb_t copy_cb,
301  uat_update_cb_t update_cb,
302  uat_free_cb_t free_cb,
303  uat_post_update_cb_t post_update_cb,
304  uat_reset_cb_t reset_cb,
305  uat_field_t* flds_array);
306 
310 WS_DLL_PUBLIC
311 void uat_destroy(uat_t *uat);
312 
316 void uat_cleanup(void);
317 
326 WS_DLL_PUBLIC
327 bool uat_load(uat_t* uat_in, const char *filename, char** err);
328 
338 bool uat_load_str(uat_t* uat_in, const char* entry, char** err);
339 
346 uat_t *uat_find(char *name);
347 
348 WS_DLL_PUBLIC
349 uat_t* uat_get_table_by_name(const char* name);
350 
364 WS_DLL_PUBLIC
365 void uat_set_default_values(uat_t *uat_in, const char *default_values[]);
366 
367 /*
368  * Some common uat_fld_chk_cbs
369  */
370 WS_DLL_PUBLIC
371 bool uat_fld_chk_str(void*, const char*, unsigned, const void*, const void*, char** err);
372 bool uat_fld_chk_oid(void*, const char*, unsigned, const void*, const void*, char** err);
373 WS_DLL_PUBLIC
374 bool uat_fld_chk_proto(void*, const char*, unsigned, const void*, const void*, char** err);
375 WS_DLL_PUBLIC
376 bool uat_fld_chk_num_dec(void*, const char*, unsigned, const void*, const void*, char** err);
377 WS_DLL_PUBLIC
378 bool uat_fld_chk_num_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
379 WS_DLL_PUBLIC
380 bool uat_fld_chk_num_hex(void*, const char*, unsigned, const void*, const void*, char** err);
381 WS_DLL_PUBLIC
382 bool uat_fld_chk_num_hex64(void*, const char*, unsigned, const void*, const void*, char** err);
383 WS_DLL_PUBLIC
384 bool uat_fld_chk_num_signed_dec(void*, const char*, unsigned, const void*, const void*, char** err);
385 WS_DLL_PUBLIC
386 bool uat_fld_chk_num_signed_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
387 WS_DLL_PUBLIC
388 bool uat_fld_chk_bool(void*, const char*, unsigned, const void*, const void*, char** err);
389 WS_DLL_PUBLIC
390 bool uat_fld_chk_enum(void*, const char*, unsigned, const void*, const void*, char**);
391 WS_DLL_PUBLIC
392 bool uat_fld_chk_range(void*, const char*, unsigned, const void*, const void*, char**);
393 WS_DLL_PUBLIC
394 bool uat_fld_chk_color(void*, const char*, unsigned, const void*, const void*, char**);
395 
396 typedef void (*uat_cb_t)(void* uat,void* user_data);
397 WS_DLL_PUBLIC
398 void uat_foreach_table(uat_cb_t cb,void* user_data);
399 void uat_unload_all(void);
400 
401 char* uat_undquote(const char* si, unsigned in_len, unsigned* len_p);
402 char* uat_unbinstring(const char* si, unsigned in_len, unsigned* len_p);
403 char* uat_unesc(const char* si, unsigned in_len, unsigned* len_p);
404 char* uat_esc(const char* buf, unsigned len);
405 
406 /* Some strings entirely made of ... already declared */
407 
408 WS_DLL_PUBLIC
409 bool uat_fld_chk_str_isprint(void*, const char*, unsigned, const void*, const void*, char**);
410 
411 WS_DLL_PUBLIC
412 bool uat_fld_chk_str_isalpha(void*, const char*, unsigned, const void*, const void*, char**);
413 
414 WS_DLL_PUBLIC
415 bool uat_fld_chk_str_isalnum(void*, const char*, unsigned, const void*, const void*, char**);
416 
417 WS_DLL_PUBLIC
418 bool uat_fld_chk_str_isdigit(void*, const char*, unsigned, const void*, const void*, char**);
419 
420 WS_DLL_PUBLIC
421 bool uat_fld_chk_str_isxdigit(void*, const char*, unsigned, const void*, const void*, char**);
422 
423 
424 /*
425  * Macros
426  * to define basic uat_fld_set_cbs, uat_fld_tostr_cbs
427  * for those elements in uat_field_t array
428  */
429 
430 #ifdef __cplusplus
431 #define UNUSED_PARAMETER(n)
432 #else
433 #define UNUSED_PARAMETER(n) n _U_
434 #endif
435 
436 /*
437  * CSTRING macros,
438  * a simple c-string contained in (((rec_t*)rec)->(field_name))
439  */
440 #define UAT_CSTRING_CB_DEF(basename,field_name,rec_t) \
441 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
442  char* new_buf = g_strndup(buf,len); \
443  g_free((((rec_t*)rec)->field_name)); \
444  (((rec_t*)rec)->field_name) = new_buf; } \
445 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)) {\
446  if (((rec_t*)rec)->field_name ) { \
447  *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
448  *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
449  } else { \
450  *out_ptr = g_strdup(""); *out_len = 0; \
451  } }
452 
453 #define UAT_FLD_CSTRING(basename,field_name,title,desc) \
454  {#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}
455 
456 #define UAT_FLD_CSTRING_ISPRINT(basename,field_name,title,desc) \
457  {#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}
458 
459 #define UAT_FLD_CSTRING_OTHER(basename,field_name,title,chk,desc) \
460  {#field_name, title, PT_TXTMOD_STRING,{ chk ,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
461 
462 /*
463  * FILENAME and DIRECTORYNAME,
464  * a simple c-string contained in (((rec_t*)rec)->(field_name))
465  */
466 #define UAT_FILENAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
467 
468 /* XXX UAT_FLD_FILENAME is currently unused. */
469 #define UAT_FLD_FILENAME(basename,field_name,title,desc) \
470  {#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}
471 
472 /*
473  * Both the Qt and GTK+ UIs assume that we're opening a preexisting
474  * file. We might want to split the ..._FILENAME defines into
475  * ..._FILE_OPEN and ..._FILE_SAVE if we ever need to specify a
476  * file that we're creating.
477  */
478 #define UAT_FLD_FILENAME_OTHER(basename,field_name,title,chk,desc) \
479  {#field_name, title, PT_TXTMOD_FILENAME,{chk,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
480 
481 #define UAT_DIRECTORYNAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
482 
483 #define UAT_FLD_DIRECTORYNAME(basename,field_name,title,desc) \
484  {#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}
485 
486 /*
487  * DISPLAY_FILTER,
488  * a simple c-string contained in (((rec_t*)rec)->(field_name))
489  */
490 #define UAT_DISPLAY_FILTER_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
491 
492 #define UAT_FLD_DISPLAY_FILTER(basename,field_name,title,desc) \
493  {#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}
494 
495 /*
496  * PROTO_FIELD,
497  * a simple c-string contained in (((rec_t*)rec)->(field_name))
498  */
499 #define UAT_PROTO_FIELD_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
500 
501 #define UAT_FLD_PROTO_FIELD(basename,field_name,title,desc) \
502  {#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}
503 
504 /*
505  * OID - just a CSTRING with a specific check routine
506  */
507 #define UAT_FLD_OID(basename,field_name,title,desc) \
508  {#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}
509 
510 
511 /*
512  * LSTRING MACROS
513  */
514 #define UAT_LSTRING_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
515 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
516  char* new_val = uat_unesc(buf,len,&(((rec_t*)rec)->len_element)); \
517  g_free((((rec_t*)rec)->ptr_element)); \
518  (((rec_t*)rec)->ptr_element) = new_val; } \
519 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)) {\
520  if (((rec_t*)rec)->ptr_element ) { \
521  *out_ptr = uat_esc(((rec_t*)rec)->ptr_element, (((rec_t*)rec)->len_element)); \
522  *out_len = (unsigned)strlen(*out_ptr); \
523  } else { \
524  *out_ptr = g_strdup(""); \
525  *out_len = 0; \
526  } }
527 
528 #define UAT_FLD_LSTRING(basename,field_name,title, desc) \
529 {#field_name, title, PT_TXTMOD_STRING,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
530 
531 
532 /*
533  * BUFFER macros,
534  * a buffer_ptr contained in (((rec_t*)rec)->(field_name))
535  * and its len in (((rec_t*)rec)->(len_name))
536  */
537 #define UAT_BUFFER_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
538 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
539  unsigned char* new_buf = len ? (unsigned char *)g_memdup2(buf,len) : NULL; \
540  g_free((((rec_t*)rec)->ptr_element)); \
541  (((rec_t*)rec)->ptr_element) = new_buf; \
542  (((rec_t*)rec)->len_element) = len; } \
543 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)) {\
544  *out_ptr = ((rec_t*)rec)->ptr_element ? (char*)g_memdup2(((rec_t*)rec)->ptr_element,((rec_t*)rec)->len_element) : g_strdup(""); \
545  *out_len = ((rec_t*)rec)->len_element; }
546 
547 #define UAT_FLD_BUFFER(basename,field_name,title,desc) \
548  {#field_name, title, PT_TXTMOD_HEXBYTES,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
549 
550 
551 /*
552  * DEC Macros,
553  * an unsigned decimal number contained in (((rec_t*)rec)->(field_name))
554  */
555 #define UAT_DEC_CB_DEF(basename,field_name,rec_t) \
556 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
557  char* tmp_str = g_strndup(buf,len); \
558  ws_strtou32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
559  g_free(tmp_str); } \
560 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)) {\
561  *out_ptr = ws_strdup_printf("%u",((rec_t*)rec)->field_name); \
562  *out_len = (unsigned)strlen(*out_ptr); }
563 
564 #define UAT_FLD_DEC(basename,field_name,title,desc) \
565  {#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}
566 
567  /*
568  * an unsigned 64bit decimal number contained in (((rec_t*)rec)->(field_name))
569  */
570 #define UAT_DEC64_CB_DEF(basename,field_name,rec_t) \
571 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
572  char* tmp_str = g_strndup(buf,len); \
573  ws_strtou64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
574  g_free(tmp_str); } \
575 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)) {\
576  *out_ptr = ws_strdup_printf("%" PRIu64,((rec_t*)rec)->field_name); \
577  *out_len = (unsigned)strlen(*out_ptr); }
578 
579 #define UAT_FLD_DEC64(basename,field_name,title,desc) \
580  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_dec64,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
581 
582 /*
583  * a *signed* decimal number contained in (((rec_t*)rec)->(field_name))
584  */
585 #define UAT_SIGNED_DEC_CB_DEF(basename,field_name,rec_t) \
586 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
587  char* tmp_str = g_strndup(buf,len); \
588  ws_strtoi32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
589  g_free(tmp_str); } \
590 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)) {\
591  *out_ptr = ws_strdup_printf("%d",((rec_t*)rec)->field_name); \
592  *out_len = (unsigned)strlen(*out_ptr); }
593 
594 #define UAT_FLD_SIGNED_DEC(basename,field_name,title,desc) \
595  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_signed_dec,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
596 
597  /*
598  * and a *signed* 64bit decimal number contained in (((rec_t*)rec)->(field_name))
599  */
600 #define UAT_SIGNED_DEC64_CB_DEF(basename,field_name,rec_t) \
601 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
602  char* tmp_str = g_strndup(buf,len); \
603  ws_strtoi64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
604  g_free(tmp_str); } \
605 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)) {\
606  *out_ptr = ws_strdup_printf("%" PRId64,((rec_t*)rec)->field_name); \
607  *out_len = (unsigned)strlen(*out_ptr); }
608 
609 #define UAT_FLD_SIGNED_DEC64(basename,field_name,title,desc) \
610  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_signed_dec64,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
611 
612 #define UAT_FLD_NONE(basename,field_name,title,desc) \
613  {#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}
614 
615 
616 /*
617  * HEX Macros,
618  * an unsigned hexadecimal number contained in (((rec_t*)rec)->(field_name))
619  */
620 #define UAT_HEX_CB_DEF(basename,field_name,rec_t) \
621 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
622  char* tmp_str = g_strndup(buf,len); \
623  ws_hexstrtou32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
624  g_free(tmp_str); } \
625 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)) {\
626  *out_ptr = ws_strdup_printf("%x",((rec_t*)rec)->field_name); \
627  *out_len = (unsigned)strlen(*out_ptr); }
628 
629 #define UAT_FLD_HEX(basename,field_name,title,desc) \
630 {#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}
631 
632  /*
633  * HEX Macros for 64bit,
634  * an unsigned long long hexadecimal number contained in (((rec_t*)rec)->(field_name))
635  */
636 #define UAT_HEX64_CB_DEF(basename,field_name,rec_t) \
637 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
638  char* tmp_str = g_strndup(buf,len); \
639  ws_hexstrtou64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
640  g_free(tmp_str); } \
641 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)) {\
642  *out_ptr = ws_strdup_printf("%" PRIx64,((rec_t*)rec)->field_name); \
643  *out_len = (unsigned)strlen(*out_ptr); }
644 
645 #define UAT_FLD_HEX64(basename,field_name,title,desc) \
646 {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_num_hex64,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
647 
648 /*
649  * BOOL Macros,
650  * an boolean value contained in (((rec_t*)rec)->(field_name))
651  *
652  * Write "TRUE" or "FALSE" for backwards compatibility with pre-4.4
653  * versions that expect that capitalization.
654  */
655 #define UAT_BOOL_CB_DEF(basename,field_name,rec_t) \
656 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
657  char* tmp_str = g_strndup(buf,len); \
658  if (tmp_str && g_ascii_strcasecmp(tmp_str, "true") == 0) \
659  ((rec_t*)rec)->field_name = 1; \
660  else \
661  ((rec_t*)rec)->field_name = 0; \
662  g_free(tmp_str); } \
663 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)) {\
664  *out_ptr = ws_strdup_printf("%s",((rec_t*)rec)->field_name ? "TRUE" : "FALSE"); \
665  *out_len = (unsigned)strlen(*out_ptr); }
666 
667 #define UAT_FLD_BOOL(basename,field_name,title,desc) \
668 {#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}
669 
670 /*
671  * ENUM macros
672  * enum_t: name = ((enum_t*)ptr)->strptr
673  * value = ((enum_t*)ptr)->value
674  * rec_t:
675  * value
676  */
677 #define UAT_VS_DEF(basename,field_name,rec_t,default_t,default_val,default_str) \
678 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
679  unsigned i; \
680  char* str = g_strndup(buf,len); \
681  const char* cstr; \
682  ((rec_t*)rec)->field_name = default_val; \
683  for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
684  if (g_str_equal(cstr,str)) { \
685  ((rec_t*)rec)->field_name = (default_t)((const value_string*)vs)[i].value; \
686  g_free(str); \
687  return; \
688  } \
689  } \
690  g_free(str); } \
691 static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
692  unsigned i; \
693  for(i=0;((const value_string*)vs)[i].strptr;i++) { \
694  if ( ((const value_string*)vs)[i].value == ((rec_t*)rec)->field_name ) { \
695  *out_ptr = g_strdup(((const value_string*)vs)[i].strptr); \
696  *out_len = (unsigned)strlen(*out_ptr); \
697  return; \
698  } \
699  } \
700  *out_ptr = g_strdup(default_str); \
701  *out_len = (unsigned)strlen(default_str); }
702 
703 #define UAT_VS_CSTRING_DEF(basename,field_name,rec_t,default_val,default_str) \
704 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
705  unsigned i; \
706  char* str = g_strndup(buf,len); \
707  const char* cstr; \
708  ((rec_t*)rec)->field_name = default_val; \
709  for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
710  if (g_str_equal(cstr,str)) { \
711  ((rec_t*)rec)->field_name = g_strdup(((const value_string*)vs)[i].strptr); \
712  g_free(str); \
713  return; \
714  } \
715  } \
716  g_free(str);} \
717 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)) {\
718  if (((rec_t*)rec)->field_name ) { \
719  *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
720  *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
721  } else { \
722  *out_ptr = g_strdup(""); *out_len = 0; } }
723 
724 #define UAT_FLD_VS(basename,field_name,title,enum,desc) \
725  {#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}
726 
727 
728 /*
729  * Color Macros,
730  * an #RRGGBB color value contained in (((rec_t*)rec)->(field_name))
731  */
732 #define UAT_COLOR_CB_DEF(basename,field_name,rec_t) \
733 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
734  if (len < 1) { \
735  ((rec_t*)rec)->field_name = 0; \
736  return; \
737  } \
738  char* tmp_str = g_strndup(buf+1,len-1); \
739  ((rec_t*)rec)->field_name = (unsigned)strtol(tmp_str,NULL,16); \
740  g_free(tmp_str); } \
741 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)) {\
742  *out_ptr = ws_strdup_printf("#%06X",((rec_t*)rec)->field_name); \
743  *out_len = (unsigned)strlen(*out_ptr); }
744 
745 #define UAT_FLD_COLOR(basename,field_name,title,desc) \
746 {#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}
747 
748 
749 /*
750  * DISSECTOR macros
751  */
752 
753 #define UAT_DISSECTOR_DEF(basename, field_name, dissector_field, name_field, rec_t) \
754 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
755  if (len) { \
756  ((rec_t*)rec)->name_field = g_strndup(buf, len); \
757  g_strstrip(((rec_t*)rec)->name_field); \
758  ((rec_t*)rec)->dissector_field = find_dissector(((rec_t*)rec)->name_field); \
759  } else { \
760  ((rec_t*)rec)->dissector_field = find_dissector("data"); \
761  ((rec_t*)rec)->name_field = NULL; \
762  } } \
763 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)) {\
764  if ( ((rec_t*)rec)->name_field ) { \
765  *out_ptr = g_strdup((((rec_t*)rec)->name_field)); \
766  *out_len = (unsigned)strlen(*out_ptr); \
767  } else { \
768  *out_ptr = g_strdup(""); *out_len = 0; \
769  } }
770 
771 
772 #define UAT_FLD_DISSECTOR(basename,field_name,title,desc) \
773  {#field_name, title, PT_TXTMOD_DISSECTOR,{uat_fld_chk_proto,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
774 
775 /*
776  * RANGE macros
777  */
778 
779 #define UAT_RANGE_CB_DEF(basename,field_name,rec_t) \
780 static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* u2) {\
781  char* rng = g_strndup(buf,len);\
782  range_convert_str(NULL, &(((rec_t*)rec)->field_name), rng,GPOINTER_TO_UINT(u2)); \
783  g_free(rng); \
784  } \
785 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)) {\
786  if ( ((rec_t*)rec)->field_name ) { \
787  *out_ptr = range_convert_range(NULL, ((rec_t*)rec)->field_name); \
788  *out_len = (unsigned)strlen(*out_ptr); \
789  } else { \
790  *out_ptr = g_strdup(""); *out_len = 0; \
791  } }
792 
793 
794 #define UAT_FLD_RANGE(basename,field_name,title,max,desc) \
795  {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_range,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},\
796  {0,0,0},GUINT_TO_POINTER(max),desc,FLDFILL}
797 
798 #ifdef __cplusplus
799 }
800 #endif /* __cplusplus */
801 
802 #endif /* __UAT_H__ */
803 
804 /*
805  * Editor modelines
806  *
807  * Local Variables:
808  * c-basic-offset: 4
809  * tab-width: 8
810  * indent-tabs-mode: nil
811  * End:
812  *
813  * ex: set shiftwidth=4 tabstop=8 expandtab:
814  * :indentSize=4:tabSize=8:noTabs=true:
815  */
Definition: uat-int.h:34
Definition: uat.h:234
Definition: uat-int.h:40
WS_DLL_PUBLIC void uat_set_default_values(uat_t *uat_in, const char *default_values[])
Definition: uat.c:265
uat_t * uat_find(char *name)
Definition: uat.c:444
void *(* uat_copy_cb_t)(void *dest, const void *source, size_t len)
Definition: uat.h:87
void(* uat_free_cb_t)(void *record)
Definition: uat.h:97
void uat_cleanup(void)
Definition: uat.c:513
WS_DLL_PUBLIC uat_t * uat_new(const char *name, size_t size, const char *filename, bool from_profile, void *data_ptr, unsigned *num_items_ptr, unsigned flags, const char *help, uat_copy_cb_t copy_cb, uat_update_cb_t update_cb, uat_free_cb_t free_cb, uat_post_update_cb_t post_update_cb, uat_reset_cb_t reset_cb, uat_field_t *flds_array)
Definition: uat.c:43
WS_DLL_PUBLIC bool uat_load(uat_t *uat_in, const char *filename, char **err)
bool(* uat_update_cb_t)(void *record, char **error)
Definition: uat.h:125
void(* uat_reset_cb_t)(void)
Definition: uat.h:105
bool uat_load_str(uat_t *uat_in, const char *entry, char **err)
WS_DLL_PUBLIC void uat_destroy(uat_t *uat)
Definition: uat.c:525