witness fix for new tvb_get_unicode_string() interface using wmem
[metze/wireshark/wip.git] / echld / echld.h
1 /* echld.h
2  *  epan working child API
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org>
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #ifndef __ECHLD_H
28 #define __ECHLD_H
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include "ws_symbol_export.h"
35
36 #define ECHLD_VERSION "0.0"
37 #define ECHLD_MAJOR_VERSION 0 /* increases when existing things change */
38                                                           /* if this changes an old client may or may not work */
39
40 #define ECHLD_MINOR_VERSION 0 /* increases when new things are added */
41                                                           /* if just this one changes an old client will still work */
42
43 /*
44  * You should take a look to doc/README.epan_child before reading this
45  */
46
47 /* message types */
48 typedef enum _echld_msg_type_t echld_msg_type_t;
49
50 /* error types */
51 typedef enum _echld_error echld_error_t;
52
53 /* return codes */
54  /* 0 is ok, everything else is ko, or timeout where applicable. */
55 typedef int echld_state_t;
56 #define ECHLD_OK 0
57 #define ECHLD_TIMEOUT -222
58
59 /* id for child working processes, a negative value is an error */
60 typedef int echld_chld_id_t;
61
62 /* id of requests, a negative value is an error */
63 typedef int echld_reqh_id_t;
64
65 /* id of message handlers, a negative value is an error */
66 typedef int echld_msgh_id_t;
67
68 /* enc_msg_t is an obscure object for an encoded message (a GbyteArray for now)*/
69 typedef struct _GByteArray enc_msg_t;
70
71 /* sets the codec set by name */
72 typedef enum _echld_encoding {
73         ECHLD_ENCODING_TEXT = 'T',
74         ECHLD_ENCODING_XML  = 'X',
75         ECHLD_ENCODING_JSON = 'J'
76 } echld_encoding_t;
77
78 typedef int echld_bool_t;
79
80 /* typedef for a timeval so that sys/time.h is not required in the client */
81 typedef struct timeval tv_t;
82
83 typedef void (*cleanup_cb_t)(void*);
84 typedef int (*main_t)(int, char**); /* a pointer to main() */
85
86 /* these are called after a new child is created.
87  * chld_id = -1 on error/timeout
88  */
89 typedef void (*echld_new_cb_t)(void* child_data, const char* err);
90
91 /* I will be passed to echld_initialize() */
92 typedef struct _echld_init {
93         echld_encoding_t encoding; /* only JSON for now */
94
95         char* argv0; /* the value of argv[0] */
96         main_t main;
97
98         echld_new_cb_t dispatcher_hello_cb; /* child_data will be a pointer to this echld_init_t */
99
100         cleanup_cb_t after_fork_cb; /* to be called by dispatcher just after fork to free
101                                                                    the child processes from entities of the parent */
102         void* after_fork_cb_data;
103
104         cleanup_cb_t at_term_cb; /* to be called after echld_terminate() is done */
105         void* at_term_cb_data;
106
107         void* user_data; /* free for you to use */
108 } echld_init_t;
109
110 /* will initialize echld forking the dispatcher and registering protocols and taps */
111 WS_DLL_PUBLIC void echld_initialize(echld_init_t*);
112
113 /* cleans up echld and kills the server process(es) */
114 WS_DLL_PUBLIC echld_state_t echld_terminate(void);
115
116
117 /*
118  * returning ECHLD_NO_ERROR means there has being no error
119  *
120  * errstr_ptr is a ptr to  the error message string, will give NULL if no error
121  *    usable only after the last API call, doesn't have to be freed.
122  *
123  * for managing asyncronous errors use a msgh for ECHLD_ERROR
124  * the response cb of reqh might be a ECHLD_ERROR message
125  */
126 WS_DLL_PUBLIC echld_error_t echld_get_error(const char** errstr_ptr);
127
128
129 /*
130  * prototype of message callbacks passed to echld_reqh() and echld_msgh()
131  *
132  * type: for reqh it might be ECHLD_ERROR, ECHLD_TIMEOUT or what you expect,
133  *        in msgh it's always the message for which it was set
134  * msg_buff: the encoded message
135  * cb_data: arbitrary data passed by the user in echld_reqh() or echld_msgh()
136  *
137  * returns TRUE if other potential handlers are to be run, false otherwise
138  */
139 typedef echld_bool_t (*echld_msg_cb_t)(echld_msg_type_t type, enc_msg_t* msg_buff, void* cb_data);
140
141
142 /* encoding and decoding */
143
144
145 /*
146  * encoder
147  * the enc_msg_t will be destroyed internally by the req handler
148  * the resulting enc_msg_t can be used in a reqh just once.
149  */
150
151 typedef struct _parent_out {
152         enc_msg_t* (*error)(int err, const char* text);
153         enc_msg_t* (*get_param)(const char* param);
154         enc_msg_t* (*set_param)(const char* param,  const char* value);
155         enc_msg_t* (*close_child)(int mode);
156         enc_msg_t* (*open_file)(const char* filename);
157         enc_msg_t* (*open_interface)(const char* intf_name, const char* params);
158         enc_msg_t* (*get_sum)(const char* range);
159         enc_msg_t* (*get_tree)(const char* range);
160         enc_msg_t* (*get_bufer)(const char* name);
161         enc_msg_t* (*add_note)(int packet_number, const char* note);
162         enc_msg_t* (*apply_filter)(const char* filter);
163         enc_msg_t* (*save_file)(const char* filename, const char* params);
164 } echld_parent_encoder_t;
165
166
167 WS_DLL_PUBLIC echld_parent_encoder_t* echld_get_encoder(void);
168
169
170 /*
171  * decoder
172  * it returns an allocated string with the decoded response of the message, you free it.
173  * it destroys the enc_msg_t as well.
174  */
175 WS_DLL_PUBLIC char* echld_decode(echld_msg_type_t, enc_msg_t*);
176
177 /*
178  *  Children Management Operations
179  */
180
181 WS_DLL_PUBLIC enc_msg_t* echld_new_child_params(void);
182
183
184
185 /* takes the em, and param=value pairs of strings, NULL to end.
186     echld_new_child_params_add_params(em,param1_str,val1_str,param2_str,val2_str,NULL);  */
187 WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t*, ...);
188
189 WS_DLL_PUBLIC enc_msg_t* echld_new_child_params_merge(enc_msg_t*, enc_msg_t*);
190
191 #define ECHLD_NC_PARAMS_FMT "  %s='%s',\n" /* param='value' */
192 /* truncate takes off last N chars from the last item's fmt or prefix on empty */
193 WS_DLL_PUBLIC char* echld_new_child_params_str(enc_msg_t* em, const char* prefix, const char* postfix, int truncate, const char* fmt);
194
195
196 /* create a new worker process */
197 WS_DLL_PUBLIC echld_chld_id_t echld_new(enc_msg_t* new_child_parameters, echld_new_cb_t cb, void* child_data);
198
199 /* will return NULL on error, if NULL is also ok for you use echld_get_error() */
200 WS_DLL_PUBLIC void* echld_get_data(echld_chld_id_t);
201
202 WS_DLL_PUBLIC echld_state_t echld_set_data(echld_chld_id_t id, void* child_data);
203
204 /* for each child call cb(id,child_data,cb_data) */
205 typedef echld_bool_t (*echld_iter_cb_t)(echld_chld_id_t, void* child_data, void* cb_data);
206 WS_DLL_PUBLIC void echld_foreach_child(echld_iter_cb_t cb, void* cb_data);
207
208 /*
209  *  Request Handlers
210  *
211  */
212
213 /* send a request with an optional response handler
214  *
215  * ba is a enc_msg_t that contains the encoded message
216  * resp_cb is the callback and cb_data the data it is going to be passed if executed
217  *
218  * returns the reqh id */
219 WS_DLL_PUBLIC echld_reqh_id_t echld_reqh(echld_chld_id_t, echld_msg_type_t, int usecs_timeout, enc_msg_t*, echld_msg_cb_t, void*);
220
221 /* get callback data for a live request */
222 WS_DLL_PUBLIC void* echld_reqh_get_data(echld_chld_id_t, echld_reqh_id_t);
223
224 /* get the total timeout time for a live request, -1 is err */
225 WS_DLL_PUBLIC int echld_reqh_get_to(echld_chld_id_t, echld_reqh_id_t);
226
227 /* get the remaining timeout time for a live request, -1 is err */
228 WS_DLL_PUBLIC int echld_reqh_get_remaining_to(echld_chld_id_t, echld_reqh_id_t);
229
230 /* get the callback for a live request */
231 WS_DLL_PUBLIC echld_msg_cb_t echld_reqh_get_cb(echld_chld_id_t, echld_reqh_id_t);
232
233 /* set callback data for a live request */
234 WS_DLL_PUBLIC echld_state_t echld_reqh_set_data(echld_chld_id_t, echld_reqh_id_t, void* );
235
236 /* get the callback for a live request */
237 WS_DLL_PUBLIC echld_state_t echld_reqh_set_cb(echld_chld_id_t, echld_reqh_id_t, echld_msg_cb_t);
238
239 /* stop receiving a live request */
240 WS_DLL_PUBLIC echld_state_t echld_reqh_detach(echld_chld_id_t, echld_reqh_id_t);
241
242
243 /*
244  *  Message Handlers
245  *
246  */
247
248 /* start a message handler */
249 WS_DLL_PUBLIC echld_msgh_id_t echld_msgh(echld_chld_id_t, echld_msg_type_t, echld_msg_cb_t resp_cb, void* msg_data);
250
251 /* stop it */
252 WS_DLL_PUBLIC echld_state_t echld_msgh_detach(echld_chld_id_t, echld_msgh_id_t);
253
254 /* get a msgh's data */
255 WS_DLL_PUBLIC void* echld_msgh_get_data(echld_chld_id_t, echld_msgh_id_t);
256
257 /* get a msgh's cb */
258 WS_DLL_PUBLIC echld_msg_cb_t echld_msgh_get_cb(echld_chld_id_t, echld_msgh_id_t);
259
260 /* get a msgh's type */
261 WS_DLL_PUBLIC echld_msg_type_t echld_msgh_get_type(echld_chld_id_t, echld_msgh_id_t);
262
263 /* get it all from a msgh */
264 WS_DLL_PUBLIC echld_state_t echld_msgh_get_all(echld_chld_id_t, int msgh_id, echld_msg_type_t*, echld_msg_cb_t*, void**);
265
266 /* set a msgh's data */
267 WS_DLL_PUBLIC echld_state_t echld_msgh_set_data(echld_chld_id_t, int msgh_id, void* );
268
269 /* set a msgh's cb */
270 WS_DLL_PUBLIC echld_state_t echld_msgh_set_cb(echld_chld_id_t, int msgh_id, echld_msg_cb_t);
271
272 /* set a msgh's type */
273 WS_DLL_PUBLIC echld_state_t echld_msgh_set_type(echld_chld_id_t, int msgh_id, echld_msg_type_t);
274
275 /* set all elements of a msgh */
276 WS_DLL_PUBLIC echld_state_t echld_msgh_set_all(echld_chld_id_t, int msgh_id, echld_msg_type_t, echld_msg_cb_t, void*);
277
278
279
280
281 /*
282  * Server routines
283  */
284
285 /*
286  * waits until something gets done
287  *
288  * returns ECHLD_TIMEOUT or ECHLD_OK if something was done
289  */
290 WS_DLL_PUBLIC echld_state_t echld_wait(tv_t* timeout);
291
292 #define ECHLD_WAIT() do { struct timeval tv; int rfds,  efds; \
293         echld_select(echld_fdset(&rfds, &efds),&rfds, NULL, &efds, NULL) \
294         && echld_fd_read(&rfds, &efds); } while(0)
295
296 /*
297    to be used in place of select() in the main loop of the parent code
298    it will serve the children pipes and return as if select() was called.
299 */
300 WS_DLL_PUBLIC int echld_select(int nfds, fd_set* rfds, fd_set* wfds, fd_set* efds, tv_t* timeout);
301
302 /* or fit these two in your select loop */
303
304 /* returns nfds set */
305 WS_DLL_PUBLIC int echld_fdset(fd_set* rfds, fd_set* efds);
306
307 WS_DLL_PUBLIC int echld_fd_read(fd_set* rfds, fd_set* efds);
308
309 WS_DLL_PUBLIC void echld_set_parent_dbg_level(int lvl);
310
311
312 #define ECHLD_MAX_CHILDREN 32
313
314 enum _echld_msg_type_t {
315         /*  in = child to parent */
316         /* out = parent to child */
317
318         ECHLD_NULL ='\0',  /* To terminate array */
319         ECHLD_ERROR = '!', /* in: an error has occurred,
320                                                 *       this can be a response to most messages
321                                                 *   some errors are sent asyncronously (some are handled internally, some are then passed)
322                                                 */
323         ECHLD_TIMED_OUT='/', /* in: A reqh has timed out (TO from now on)
324                                                 *       this can be a response to some messages
325                                                 *   some TOs are sent asyncronously (some are handled internally, some are then passed)
326                                                 */
327
328         ECHLD_NEW_CHILD = '*', /* out: creates a new working child  (handled internally)  */
329         ECHLD_HELLO = '@', /* in: the working child has being created (handled internally, then passed to msgh) */
330
331         ECHLD_CHILD_DEAD = '#', /* in: a child has dead (handled internally, then passed to msgh) */
332
333         ECHLD_CLOSE_CHILD = 'Q', /* out: close the child  */
334         ECHLD_CLOSING = 'q', /* in: the child is closing, error otherwise  */
335                                                  /* this handled internally as msgh, if your reqh_cb uses it make sure to return TRUE */
336
337         ECHLD_SET_PARAM = '>', /* out: set a parameter of a child  */
338         ECHLD_GET_PARAM = '<', /* out: set a parameter of a child  */
339         ECHLD_PARAM = 'p', /* in: the parameter's new/current value, error otherwise  */
340
341                                                 /* capture_filter string RO: set at open_capture */
342                                                 /* monitor_mode string RW: use monitor mode if possible, error otherwise */
343                                                 /* inc_pkt_ntfy_timeout number_string RW: timeout in usec after which notification is sent if no maxpackets have arrived yet */
344                                                 /* inc_pkt_ntfy_maxpackets number_string RW: number of packets after which send a notification */
345                                                 /* auto_sum RW: get summaries automatically (without a reqh, as msgh) */
346                                                 /* auto_tree RW: get trees automatically (without a reqh, as msgh)   */
347                                                 /* auto_buffer RW: get buffers automatically (without a reqh, as msgh) */
348                                                 /* cwd RW: the current working directory */
349                                                 /* list_files WO: a file listing of the current dir */
350                                                 /* interfaces RO: the interface listing */
351                                                 /* dfilter RW:  initial display filter*/
352                                                 /* dfilter_chk WO: check a display filter */
353                                                 /* ... */
354
355         ECHLD_PING = '}', /* out: ping the child  */
356         ECHLD_PONG = '{', /* out: ping's response, error or TO otherwise */
357
358         ECHLD_OPEN_FILE = 'O', /* out: open a file  */
359         ECHLD_FILE_OPENED = 'o', /* in: the file has being open, error otherwise */
360
361         ECHLD_OPEN_INTERFACE = 'C',  /* out: request an interface to be open (get ready for capture)  */
362         ECHLD_INTERFACE_OPENED = 'c', /* in: ready to start_capture, error otherwise */
363
364         ECHLD_START_CAPTURE = 'R',  /* out: start capturing */
365         ECHLD_CAPTURE_STARTED = 'r',  /* in: the capture has started, error otherwise */
366
367         ECHLD_NOTIFY = '%', /* in: many things can be notified by the child:
368                                                                 number of packets captured/read
369                                                                 other events in the future (?)
370                                                                 */
371
372         ECHLD_GET_SUM = 'S', /* out: get the summaries of a range of packets (even before they are notify'd) */
373         ECHLD_PACKET_SUM = 's', /* in: a packet's summary (when it arrives for a reqh) (in msgh if auto_sum )*/
374                                                                 /* no timeout, the request hangs until the packets in the range are available */
375                                                                 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
376
377         ECHLD_GET_TREE = 'G', /* out: get the decoded version of the packet  */
378         ECHLD_TREE = 't', /* Child -> Parent */
379                                                                 /* no timeout, the request hangs until the packets in the range are available */
380                                                                 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
381
382
383         ECHLD_GET_BUFFER = 'B', /* out: get the decoded version of the packet  */
384         ECHLD_BUFFER = 'b', /* in: get a buffer (or what we have of it... or the next part... same reqh_id) */
385                                                                 /* no timeout, the request hangs until the packets in the range are available */
386                                                                 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
387
388         ECHLD_EOF = 'z', /* in: will be delivered when a file has being read and all pendin ntfy,sums,trees and buffs have being passed
389                                                         or after capture has stopped and all pending stuff is done */
390
391         ECHLD_STOP_CAPTURE = 'X',  /* out: stop capturing  */
392         ECHLD_CAPTURE_STOPPED = 'x',  /* in: capture has stopped, error otherwise */
393
394         ECHLD_ADD_NOTE = 'N', /* out: add a note to the capture  */
395         ECHLD_NOTE_ADDED = 'n', /* in: a note has being added */
396
397         ECHLD_APPLY_FILTER = 'A', /* in: apply a filter on the open file/capture */
398         ECHLD_PACKET_LIST = 'l', /* out: a packet list, or error or timeout */
399                                                         /*(or what we have of it... or the next part... same reqh_id) */
400
401         ECHLD_SAVE_FILE = 'W', /* out: save the open file/capture  */
402         ECHLD_FILE_SAVED = 'w', /* in: the file was saved */
403
404
405         EC_ACTUAL_ERROR = 0 /* this is not used in the protocol,
406                                 it is returned for an error in calls returning a message type  */
407 };
408
409 enum _echld_error {
410         ECHLD_NO_ERROR = 0,
411         ECHLD_ERR_UNIMPLEMENTED,
412         ECHLD_ERR_WRONG_MSG,
413         ECHLD_ERR_NO_SUCH_CHILD,
414         ECHLD_ERR_CHILD_EXISTS,
415         ECHLD_ERR_UNKNOWN_PID,
416         ECHLD_ERR_CANNOT_FORK,
417         ECHLD_ERR_SET_FILTER,
418         ECHLD_ERR_CANNOT_OPEN_FILE,
419         ECHLD_ERR_CANNOT_OPEN_INTERFACE,
420         ECHLD_ERR_CANNOT_START_CAPTURE,
421         ECHLD_ERR_CANNOT_LIST_INTERFACES,
422         ECHLD_CANNOT_SET_PARAM,
423         ECHLD_CANNOT_GET_PARAM,
424         ECHLD_ERR_CRASHED_CHILD,
425         ECHLD_DECODE_ERROR,
426         ECHLD_ERR_OTHER
427 };
428
429 #ifdef __cplusplus
430 };
431 #endif
432
433 #endif