Wireshark 4.5.0
The Wireshark network protocol analyzer
Loading...
Searching...
No Matches
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
24extern "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 */
56typedef 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 */
73typedef void (*uat_post_update_cb_t)(void);
74
75
76/********
77 * Callbacks dealing with records (these deal with entire records)
78 ********/
79
87typedef void* (*uat_copy_cb_t)(void *dest, const void *source, size_t len);
88
97typedef void (*uat_free_cb_t)(void *record);
98
105typedef void (*uat_reset_cb_t)(void);
106
125typedef 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 */
145typedef 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 */
154typedef 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 */
163typedef 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
173typedef 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 */
234typedef 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;
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
291WS_DLL_PUBLIC
292uat_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
310WS_DLL_PUBLIC
311void uat_destroy(uat_t *uat);
312
316void uat_cleanup(void);
317
326WS_DLL_PUBLIC
327bool uat_load(uat_t* uat_in, const char *filename, char** err);
328
338bool uat_load_str(uat_t* uat_in, const char* entry, char** err);
339
346uat_t *uat_find(char *name);
347
348WS_DLL_PUBLIC
349uat_t* uat_get_table_by_name(const char* name);
350
364WS_DLL_PUBLIC
365void uat_set_default_values(uat_t *uat_in, const char *default_values[]);
366
367/*
368 * Some common uat_fld_chk_cbs
369 */
370WS_DLL_PUBLIC
371bool uat_fld_chk_str(void*, const char*, unsigned, const void*, const void*, char** err);
372bool uat_fld_chk_oid(void*, const char*, unsigned, const void*, const void*, char** err);
373WS_DLL_PUBLIC
374bool uat_fld_chk_proto(void*, const char*, unsigned, const void*, const void*, char** err);
375WS_DLL_PUBLIC
376bool uat_fld_chk_num_dec(void*, const char*, unsigned, const void*, const void*, char** err);
377WS_DLL_PUBLIC
378bool uat_fld_chk_num_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
379WS_DLL_PUBLIC
380bool uat_fld_chk_num_hex(void*, const char*, unsigned, const void*, const void*, char** err);
381WS_DLL_PUBLIC
382bool uat_fld_chk_num_hex64(void*, const char*, unsigned, const void*, const void*, char** err);
383WS_DLL_PUBLIC
384bool uat_fld_chk_num_signed_dec(void*, const char*, unsigned, const void*, const void*, char** err);
385WS_DLL_PUBLIC
386bool uat_fld_chk_num_signed_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
387WS_DLL_PUBLIC
388bool uat_fld_chk_bool(void*, const char*, unsigned, const void*, const void*, char** err);
389WS_DLL_PUBLIC
390bool uat_fld_chk_enum(void*, const char*, unsigned, const void*, const void*, char**);
391WS_DLL_PUBLIC
392bool uat_fld_chk_range(void*, const char*, unsigned, const void*, const void*, char**);
393WS_DLL_PUBLIC
394bool uat_fld_chk_color(void*, const char*, unsigned, const void*, const void*, char**);
395
396typedef void (*uat_cb_t)(void* uat,void* user_data);
397WS_DLL_PUBLIC
398void uat_foreach_table(uat_cb_t cb,void* user_data);
399void uat_unload_all(void);
400
401char* uat_undquote(const char* si, unsigned in_len, unsigned* len_p);
402char* uat_unbinstring(const char* si, unsigned in_len, unsigned* len_p);
403char* uat_unesc(const char* si, unsigned in_len, unsigned* len_p);
404char* uat_esc(const char* buf, unsigned len);
405
406/* Some strings entirely made of ... already declared */
407
408WS_DLL_PUBLIC
409bool uat_fld_chk_str_isprint(void*, const char*, unsigned, const void*, const void*, char**);
410
411WS_DLL_PUBLIC
412bool uat_fld_chk_str_isalpha(void*, const char*, unsigned, const void*, const void*, char**);
413
414WS_DLL_PUBLIC
415bool uat_fld_chk_str_isalnum(void*, const char*, unsigned, const void*, const void*, char**);
416
417WS_DLL_PUBLIC
418bool uat_fld_chk_str_isdigit(void*, const char*, unsigned, const void*, const void*, char**);
419
420WS_DLL_PUBLIC
421bool 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) \
441static 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; } \
445static 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) \
515static 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; } \
519static 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) \
538static 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; } \
543static 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) \
556static 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); } \
560static 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) \
571static 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); } \
575static 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) \
586static 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); } \
590static 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) \
601static 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); } \
605static 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) \
621static 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); } \
625static 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) \
637static 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); } \
641static 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) \
656static 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); } \
663static 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) \
678static 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); } \
691static 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) \
704static 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);} \
717static 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) \
733static 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); } \
741static 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) \
754static 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 } } \
763static 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#define UAT_FLD_DISSECTOR_OTHER(basename,field_name,title,chk,desc) \
776 {#field_name, title, PT_TXTMOD_DISSECTOR,{chk,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
777
778/*
779 * RANGE macros
780 */
781
782#define UAT_RANGE_CB_DEF(basename,field_name,rec_t) \
783static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* u2) {\
784 char* rng = g_strndup(buf,len);\
785 range_convert_str(NULL, &(((rec_t*)rec)->field_name), rng,GPOINTER_TO_UINT(u2)); \
786 g_free(rng); \
787 } \
788static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
789 if ( ((rec_t*)rec)->field_name ) { \
790 *out_ptr = range_convert_range(NULL, ((rec_t*)rec)->field_name); \
791 *out_len = (unsigned)strlen(*out_ptr); \
792 } else { \
793 *out_ptr = g_strdup(""); *out_len = 0; \
794 } }
795
796
797#define UAT_FLD_RANGE(basename,field_name,title,max,desc) \
798 {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_range,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},\
799 {0,0,0},GUINT_TO_POINTER(max),desc,FLDFILL}
800
801#ifdef __cplusplus
802}
803#endif /* __cplusplus */
804
805#endif /* __UAT_H__ */
806
807/*
808 * Editor modelines
809 *
810 * Local Variables:
811 * c-basic-offset: 4
812 * tab-width: 8
813 * indent-tabs-mode: nil
814 * End:
815 *
816 * ex: set shiftwidth=4 tabstop=8 expandtab:
817 * :indentSize=4:tabSize=8:noTabs=true:
818 */
Definition uat-int.h:34
Definition uat.h:234
Definition uat-int.h:40
void *(* uat_copy_cb_t)(void *dest, const void *source, size_t len)
Definition uat.h:87
WS_DLL_PUBLIC void uat_set_default_values(uat_t *uat_in, const char *default_values[])
Definition uat.c:283
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
void(* uat_free_cb_t)(void *record)
Definition uat.h:97
void uat_cleanup(void)
Definition uat.c:574
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)
uat_t * uat_find(char *name)
Definition uat.c:505
WS_DLL_PUBLIC void uat_destroy(uat_t *uat)
Definition uat.c:586