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_field(void*, const char*, unsigned, const void*, const void*, char** err);
377WS_DLL_PUBLIC
378bool uat_fld_chk_num_dec(void*, const char*, unsigned, const void*, const void*, char** err);
379WS_DLL_PUBLIC
380bool uat_fld_chk_num_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
381WS_DLL_PUBLIC
382bool uat_fld_chk_num_hex(void*, const char*, unsigned, const void*, const void*, char** err);
383WS_DLL_PUBLIC
384bool uat_fld_chk_num_hex64(void*, const char*, unsigned, const void*, const void*, char** err);
385WS_DLL_PUBLIC
386bool uat_fld_chk_num_signed_dec(void*, const char*, unsigned, const void*, const void*, char** err);
387WS_DLL_PUBLIC
388bool uat_fld_chk_num_signed_dec64(void*, const char*, unsigned, const void*, const void*, char** err);
389WS_DLL_PUBLIC
390bool uat_fld_chk_bool(void*, const char*, unsigned, const void*, const void*, char** err);
391WS_DLL_PUBLIC
392bool uat_fld_chk_enum(void*, const char*, unsigned, const void*, const void*, char**);
393WS_DLL_PUBLIC
394bool uat_fld_chk_range(void*, const char*, unsigned, const void*, const void*, char**);
395WS_DLL_PUBLIC
396bool uat_fld_chk_color(void*, const char*, unsigned, const void*, const void*, char**);
397
398typedef void (*uat_cb_t)(void* uat,void* user_data);
399WS_DLL_PUBLIC
400void uat_foreach_table(uat_cb_t cb,void* user_data);
401void uat_unload_all(void);
402
403char* uat_undquote(const char* si, unsigned in_len, unsigned* len_p);
404char* uat_unbinstring(const char* si, unsigned in_len, unsigned* len_p);
405char* uat_unesc(const char* si, unsigned in_len, unsigned* len_p);
406char* uat_esc(const char* buf, unsigned len);
407
408/* Some strings entirely made of ... already declared */
409
410WS_DLL_PUBLIC
411bool uat_fld_chk_str_isprint(void*, const char*, unsigned, const void*, const void*, char**);
412
413WS_DLL_PUBLIC
414bool uat_fld_chk_str_isalpha(void*, const char*, unsigned, const void*, const void*, char**);
415
416WS_DLL_PUBLIC
417bool uat_fld_chk_str_isalnum(void*, const char*, unsigned, const void*, const void*, char**);
418
419WS_DLL_PUBLIC
420bool uat_fld_chk_str_isdigit(void*, const char*, unsigned, const void*, const void*, char**);
421
422WS_DLL_PUBLIC
423bool uat_fld_chk_str_isxdigit(void*, const char*, unsigned, const void*, const void*, char**);
424
425
426/*
427 * Macros
428 * to define basic uat_fld_set_cbs, uat_fld_tostr_cbs
429 * for those elements in uat_field_t array
430 */
431
432#ifdef __cplusplus
433#define UNUSED_PARAMETER(n)
434#else
435#define UNUSED_PARAMETER(n) n _U_
436#endif
437
438/*
439 * CSTRING macros,
440 * a simple c-string contained in (((rec_t*)rec)->(field_name))
441 */
442#define UAT_CSTRING_CB_DEF(basename,field_name,rec_t) \
443static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
444 char* new_buf = g_strndup(buf,len); \
445 g_free((((rec_t*)rec)->field_name)); \
446 (((rec_t*)rec)->field_name) = new_buf; } \
447static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
448 if (((rec_t*)rec)->field_name ) { \
449 *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
450 *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
451 } else { \
452 *out_ptr = g_strdup(""); *out_len = 0; \
453 } }
454
455#define UAT_FLD_CSTRING(basename,field_name,title,desc) \
456 {#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}
457
458#define UAT_FLD_CSTRING_ISPRINT(basename,field_name,title,desc) \
459 {#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}
460
461#define UAT_FLD_CSTRING_OTHER(basename,field_name,title,chk,desc) \
462 {#field_name, title, PT_TXTMOD_STRING,{ chk ,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
463
464/*
465 * FILENAME and DIRECTORYNAME,
466 * a simple c-string contained in (((rec_t*)rec)->(field_name))
467 */
468#define UAT_FILENAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
469
470/* XXX UAT_FLD_FILENAME is currently unused. */
471#define UAT_FLD_FILENAME(basename,field_name,title,desc) \
472 {#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}
473
474/*
475 * Both the Qt and GTK+ UIs assume that we're opening a preexisting
476 * file. We might want to split the ..._FILENAME defines into
477 * ..._FILE_OPEN and ..._FILE_SAVE if we ever need to specify a
478 * file that we're creating.
479 */
480#define UAT_FLD_FILENAME_OTHER(basename,field_name,title,chk,desc) \
481 {#field_name, title, PT_TXTMOD_FILENAME,{chk,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
482
483#define UAT_DIRECTORYNAME_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
484
485#define UAT_FLD_DIRECTORYNAME(basename,field_name,title,desc) \
486 {#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}
487
488/*
489 * DISPLAY_FILTER,
490 * a simple c-string contained in (((rec_t*)rec)->(field_name))
491 */
492#define UAT_DISPLAY_FILTER_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
493
494#define UAT_FLD_DISPLAY_FILTER(basename,field_name,title,desc) \
495 {#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}
496
497/*
498 * PROTO_FIELD,
499 * a simple c-string contained in (((rec_t*)rec)->(field_name))
500 */
501#define UAT_PROTO_FIELD_CB_DEF(basename,field_name,rec_t) UAT_CSTRING_CB_DEF(basename,field_name,rec_t)
502
503#define UAT_FLD_PROTO_FIELD(basename,field_name,title,desc) \
504 {#field_name, title, PT_TXTMOD_PROTO_FIELD, {uat_fld_chk_field,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
505
506/*
507 * OID - just a CSTRING with a specific check routine
508 */
509#define UAT_FLD_OID(basename,field_name,title,desc) \
510 {#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}
511
512
513/*
514 * LSTRING MACROS
515 */
516#define UAT_LSTRING_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
517static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
518 char* new_val = uat_unesc(buf,len,&(((rec_t*)rec)->len_element)); \
519 g_free((((rec_t*)rec)->ptr_element)); \
520 (((rec_t*)rec)->ptr_element) = new_val; } \
521static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
522 if (((rec_t*)rec)->ptr_element ) { \
523 *out_ptr = uat_esc(((rec_t*)rec)->ptr_element, (((rec_t*)rec)->len_element)); \
524 *out_len = (unsigned)strlen(*out_ptr); \
525 } else { \
526 *out_ptr = g_strdup(""); \
527 *out_len = 0; \
528 } }
529
530#define UAT_FLD_LSTRING(basename,field_name,title, desc) \
531{#field_name, title, PT_TXTMOD_STRING,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
532
533
534/*
535 * BUFFER macros,
536 * a buffer_ptr contained in (((rec_t*)rec)->(field_name))
537 * and its len in (((rec_t*)rec)->(len_name))
538 */
539#define UAT_BUFFER_CB_DEF(basename,field_name,rec_t,ptr_element,len_element) \
540static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
541 unsigned char* new_buf = len ? (unsigned char *)g_memdup2(buf,len) : NULL; \
542 g_free((((rec_t*)rec)->ptr_element)); \
543 (((rec_t*)rec)->ptr_element) = new_buf; \
544 (((rec_t*)rec)->len_element) = len; } \
545static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
546 *out_ptr = ((rec_t*)rec)->ptr_element ? (char*)g_memdup2(((rec_t*)rec)->ptr_element,((rec_t*)rec)->len_element) : g_strdup(""); \
547 *out_len = ((rec_t*)rec)->len_element; }
548
549#define UAT_FLD_BUFFER(basename,field_name,title,desc) \
550 {#field_name, title, PT_TXTMOD_HEXBYTES,{0,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
551
552
553/*
554 * DEC Macros,
555 * an unsigned decimal number contained in (((rec_t*)rec)->(field_name))
556 */
557#define UAT_DEC_CB_DEF(basename,field_name,rec_t) \
558static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
559 char* tmp_str = g_strndup(buf,len); \
560 ws_strtou32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
561 g_free(tmp_str); } \
562static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
563 *out_ptr = ws_strdup_printf("%u",((rec_t*)rec)->field_name); \
564 *out_len = (unsigned)strlen(*out_ptr); }
565
566#define UAT_FLD_DEC(basename,field_name,title,desc) \
567 {#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}
568
569 /*
570 * an unsigned 64bit decimal number contained in (((rec_t*)rec)->(field_name))
571 */
572#define UAT_DEC64_CB_DEF(basename,field_name,rec_t) \
573static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
574 char* tmp_str = g_strndup(buf,len); \
575 ws_strtou64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
576 g_free(tmp_str); } \
577static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
578 *out_ptr = ws_strdup_printf("%" PRIu64,((rec_t*)rec)->field_name); \
579 *out_len = (unsigned)strlen(*out_ptr); }
580
581#define UAT_FLD_DEC64(basename,field_name,title,desc) \
582 {#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}
583
584/*
585 * a *signed* decimal number contained in (((rec_t*)rec)->(field_name))
586 */
587#define UAT_SIGNED_DEC_CB_DEF(basename,field_name,rec_t) \
588static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
589 char* tmp_str = g_strndup(buf,len); \
590 ws_strtoi32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
591 g_free(tmp_str); } \
592static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
593 *out_ptr = ws_strdup_printf("%d",((rec_t*)rec)->field_name); \
594 *out_len = (unsigned)strlen(*out_ptr); }
595
596#define UAT_FLD_SIGNED_DEC(basename,field_name,title,desc) \
597 {#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}
598
599 /*
600 * and a *signed* 64bit decimal number contained in (((rec_t*)rec)->(field_name))
601 */
602#define UAT_SIGNED_DEC64_CB_DEF(basename,field_name,rec_t) \
603static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
604 char* tmp_str = g_strndup(buf,len); \
605 ws_strtoi64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
606 g_free(tmp_str); } \
607static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
608 *out_ptr = ws_strdup_printf("%" PRId64,((rec_t*)rec)->field_name); \
609 *out_len = (unsigned)strlen(*out_ptr); }
610
611#define UAT_FLD_SIGNED_DEC64(basename,field_name,title,desc) \
612 {#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}
613
614#define UAT_FLD_NONE(basename,field_name,title,desc) \
615 {#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}
616
617
618/*
619 * HEX Macros,
620 * an unsigned hexadecimal number contained in (((rec_t*)rec)->(field_name))
621 */
622#define UAT_HEX_CB_DEF(basename,field_name,rec_t) \
623static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
624 char* tmp_str = g_strndup(buf,len); \
625 ws_hexstrtou32(tmp_str, NULL, &((rec_t*)rec)->field_name); \
626 g_free(tmp_str); } \
627static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
628 *out_ptr = ws_strdup_printf("%x",((rec_t*)rec)->field_name); \
629 *out_len = (unsigned)strlen(*out_ptr); }
630
631#define UAT_FLD_HEX(basename,field_name,title,desc) \
632{#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}
633
634 /*
635 * HEX Macros for 64bit,
636 * an unsigned long long hexadecimal number contained in (((rec_t*)rec)->(field_name))
637 */
638#define UAT_HEX64_CB_DEF(basename,field_name,rec_t) \
639static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
640 char* tmp_str = g_strndup(buf,len); \
641 ws_hexstrtou64(tmp_str, NULL, &((rec_t*)rec)->field_name); \
642 g_free(tmp_str); } \
643static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
644 *out_ptr = ws_strdup_printf("%" PRIx64,((rec_t*)rec)->field_name); \
645 *out_len = (unsigned)strlen(*out_ptr); }
646
647#define UAT_FLD_HEX64(basename,field_name,title,desc) \
648{#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}
649
650/*
651 * BOOL Macros,
652 * an boolean value contained in (((rec_t*)rec)->(field_name))
653 *
654 * Write "TRUE" or "FALSE" for backwards compatibility with pre-4.4
655 * versions that expect that capitalization.
656 */
657#define UAT_BOOL_CB_DEF(basename,field_name,rec_t) \
658static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
659 char* tmp_str = g_strndup(buf,len); \
660 if (tmp_str && g_ascii_strcasecmp(tmp_str, "true") == 0) \
661 ((rec_t*)rec)->field_name = 1; \
662 else \
663 ((rec_t*)rec)->field_name = 0; \
664 g_free(tmp_str); } \
665static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
666 *out_ptr = ws_strdup_printf("%s",((rec_t*)rec)->field_name ? "TRUE" : "FALSE"); \
667 *out_len = (unsigned)strlen(*out_ptr); }
668
669#define UAT_FLD_BOOL(basename,field_name,title,desc) \
670{#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}
671
672/*
673 * ENUM macros
674 * enum_t: name = ((enum_t*)ptr)->strptr
675 * value = ((enum_t*)ptr)->value
676 * rec_t:
677 * value
678 */
679#define UAT_VS_DEF(basename,field_name,rec_t,default_t,default_val,default_str) \
680static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
681 unsigned i; \
682 char* str = g_strndup(buf,len); \
683 const char* cstr; \
684 ((rec_t*)rec)->field_name = default_val; \
685 for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
686 if (g_str_equal(cstr,str)) { \
687 ((rec_t*)rec)->field_name = (default_t)((const value_string*)vs)[i].value; \
688 g_free(str); \
689 return; \
690 } \
691 } \
692 g_free(str); } \
693static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
694 unsigned i; \
695 for(i=0;((const value_string*)vs)[i].strptr;i++) { \
696 if ( ((const value_string*)vs)[i].value == ((rec_t*)rec)->field_name ) { \
697 *out_ptr = g_strdup(((const value_string*)vs)[i].strptr); \
698 *out_len = (unsigned)strlen(*out_ptr); \
699 return; \
700 } \
701 } \
702 *out_ptr = g_strdup(default_str); \
703 *out_len = (unsigned)strlen(default_str); }
704
705#define UAT_VS_CSTRING_DEF(basename,field_name,rec_t,default_val,default_str) \
706static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* vs, const void* UNUSED_PARAMETER(u2)) {\
707 unsigned i; \
708 char* str = g_strndup(buf,len); \
709 const char* cstr; \
710 ((rec_t*)rec)->field_name = default_val; \
711 for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;i++) { \
712 if (g_str_equal(cstr,str)) { \
713 ((rec_t*)rec)->field_name = g_strdup(((const value_string*)vs)[i].strptr); \
714 g_free(str); \
715 return; \
716 } \
717 } \
718 g_free(str);} \
719static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(vs), const void* UNUSED_PARAMETER(u2)) {\
720 if (((rec_t*)rec)->field_name ) { \
721 *out_ptr = g_strdup((((rec_t*)rec)->field_name)); \
722 *out_len = (unsigned)strlen((((rec_t*)rec)->field_name)); \
723 } else { \
724 *out_ptr = g_strdup(""); *out_len = 0; } }
725
726#define UAT_FLD_VS(basename,field_name,title,enum,desc) \
727 {#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}
728
729
730/*
731 * Color Macros,
732 * an #RRGGBB color value contained in (((rec_t*)rec)->(field_name))
733 */
734#define UAT_COLOR_CB_DEF(basename,field_name,rec_t) \
735static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
736 if (len < 1) { \
737 ((rec_t*)rec)->field_name = 0; \
738 return; \
739 } \
740 char* tmp_str = g_strndup(buf+1,len-1); \
741 ((rec_t*)rec)->field_name = (unsigned)strtol(tmp_str,NULL,16); \
742 g_free(tmp_str); } \
743static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
744 *out_ptr = ws_strdup_printf("#%06X",((rec_t*)rec)->field_name); \
745 *out_len = (unsigned)strlen(*out_ptr); }
746
747#define UAT_FLD_COLOR(basename,field_name,title,desc) \
748{#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}
749
750
751/*
752 * DISSECTOR macros
753 */
754
755#define UAT_DISSECTOR_DEF(basename, field_name, dissector_field, name_field, rec_t) \
756static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
757 if (len) { \
758 ((rec_t*)rec)->name_field = g_strndup(buf, len); \
759 g_strstrip(((rec_t*)rec)->name_field); \
760 ((rec_t*)rec)->dissector_field = find_dissector(((rec_t*)rec)->name_field); \
761 } else { \
762 ((rec_t*)rec)->dissector_field = find_dissector("data"); \
763 ((rec_t*)rec)->name_field = NULL; \
764 } } \
765static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
766 if ( ((rec_t*)rec)->name_field ) { \
767 *out_ptr = g_strdup((((rec_t*)rec)->name_field)); \
768 *out_len = (unsigned)strlen(*out_ptr); \
769 } else { \
770 *out_ptr = g_strdup(""); *out_len = 0; \
771 } }
772
773
774#define UAT_FLD_DISSECTOR(basename,field_name,title,desc) \
775 {#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}
776
777#define UAT_FLD_DISSECTOR_OTHER(basename,field_name,title,chk,desc) \
778 {#field_name, title, PT_TXTMOD_DISSECTOR,{chk,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
779
780/*
781 * RANGE macros
782 */
783
784#define UAT_RANGE_CB_DEF(basename,field_name,rec_t) \
785static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* u2) {\
786 char* rng = g_strndup(buf,len);\
787 range_convert_str(NULL, &(((rec_t*)rec)->field_name), rng,GPOINTER_TO_UINT(u2)); \
788 g_free(rng); \
789 } \
790static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
791 if ( ((rec_t*)rec)->field_name ) { \
792 *out_ptr = range_convert_range(NULL, ((rec_t*)rec)->field_name); \
793 *out_len = (unsigned)strlen(*out_ptr); \
794 } else { \
795 *out_ptr = g_strdup(""); *out_len = 0; \
796 } }
797
798
799#define UAT_FLD_RANGE(basename,field_name,title,max,desc) \
800 {#field_name, title, PT_TXTMOD_STRING,{uat_fld_chk_range,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},\
801 {0,0,0},GUINT_TO_POINTER(max),desc,FLDFILL}
802
803#ifdef __cplusplus
804}
805#endif /* __cplusplus */
806
807#endif /* __UAT_H__ */
808
809/*
810 * Editor modelines
811 *
812 * Local Variables:
813 * c-basic-offset: 4
814 * tab-width: 8
815 * indent-tabs-mode: nil
816 * End:
817 *
818 * ex: set shiftwidth=4 tabstop=8 expandtab:
819 * :indentSize=4:tabSize=8:noTabs=true:
820 */
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