2 * epan working child API
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org>
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.
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.
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.
30 #define ECHLD_VERSION "0.0"
31 #define ECHLD_MAJOR_VERSION 0 /* increases when existing things change */
32 /* if this changes an old client may or may not work */
34 #define ECHLD_MINOR_VERSION 0 /* increases when new things are added */
35 /* if just this one changes an old client will still work */
38 * You should take a look to doc/README.epan_child before reading this
42 typedef enum _echld_msg_type_t echld_msg_type_t;
45 typedef enum _echld_error echld_error_t;
48 /* 0 is ok, everything else is ko, or timeout where applicable. */
49 typedef int echld_state_t;
51 #define ECHLD_TIMEOUT -222
53 /* id for child working processes, a negative value is an error */
54 typedef int echld_chld_id_t;
56 /* id of requests, a negative value is an error */
57 typedef int echld_reqh_id_t;
59 /* id of message handlers, a negative value is an error */
60 typedef int echld_msgh_id_t;
62 /* sets the codec set by name */
63 typedef enum _echld_encoding {
64 ECHLD_ENCODING_TEXT = 'T',
65 ECHLD_ENCODING_XML = 'X',
66 ECHLD_ENCODING_JSON = 'J'
69 typedef int echld_bool_t;
71 /* typedef for a timeval so that sys/time.h is not required in the client */
72 typedef struct timeval tv_t;
74 /* will initialize epan registering protocols and taps */
75 echld_state_t echld_initialize(echld_encoding_t);
77 /* cleans up (?) echld and kills the server process(es) */
78 echld_state_t echld_terminate(void);
81 * returning ECHLD_NO_ERROR means there has being no error
83 * errstr_ptr is a ptr to the error message string, will give NULL if no error
84 * usable only after the last API call, doesn't have to be freed.
86 * for managing asyncronous errors use a msgh for ECHLD_ERROR
87 * the response cb of reqh might be a ECHLD_ERROR message
89 echld_error_t echld_get_error(const char** errstr_ptr);
92 * Children Management Operations
95 /* create a new worker process */
96 echld_chld_id_t echld_new(void* child_data);
98 /* will return NULL on error, if NULL is also ok for you use echld_get_error() */
99 void* echld_get_data(echld_chld_id_t);
101 echld_state_t echld_set_data(echld_chld_id_t id, void* child_data);
103 /* for each child call cb(id,child_data,cb_data) */
104 typedef echld_bool_t (*echld_iter_cb_t)(echld_chld_id_t, void* child_data, void* cb_data);
105 void echld_foreach_child(echld_iter_cb_t cb, void* cb_data);
107 /* enc_msg_t is an obscure object for an encoded message */
108 typedef struct GByteArray enc_msg_t;
112 * prototype of message callbacks passed to echld_reqh() and echld_msgh()
114 * type: for reqh it might be ECHLD_ERROR, ECHLD_TIMEOUT or what you expect,
115 * in msgh it's always the message for which it was set
116 * msg_buff: the encoded message
117 * cb_data: arbitrary data passed by the user in echld_reqh() or echld_msgh()
119 * returns TRUE if other potential handlers are to be run, false otherwise
121 typedef echld_bool_t (*echld_msg_cb_t)(echld_msg_type_t type, enc_msg_t* msg_buff, void* cb_data);
125 /* encoding and decoding */
130 * the enc_msg_t will be destroyed internally by the req handler
131 * the resulting enc_msg_t can be used in a reqh just once.
134 typedef struct _parent_out {
135 enc_msg_t* (*error)(int err, const char* text);
136 enc_msg_t* (*set_param)(const char* param, const char* value);
137 enc_msg_t* (*close_child)(int mode);
138 enc_msg_t* (*open_file)(const char* filename);
139 enc_msg_t* (*open_interface)(const char* intf_name, const char* params);
140 enc_msg_t* (*get_sum)(const char* range);
141 enc_msg_t* (*get_tree)(const char* range);
142 enc_msg_t* (*get_bufer)(const char* name);
143 enc_msg_t* (*add_note)(int packet_number, const char* note);
144 enc_msg_t* (*apply_filter)(const char* filter);
145 enc_msg_t* (*save_file)(const char* filename, const char* params);
146 } echld_parent_encoder_t;
148 echld_parent_encoder_t* echld_get_encoder();
152 * it returns an allocated string with the decoded response of the message, you free it.
153 * it destroys the enc_msg_t as well.
155 char* echld_decode(echld_msg_type_t, enc_msg_t*);
162 /* send a request with an optional response handler
164 * ba is a enc_msg_t that contains the encoded message
165 * resp_cb is the callback and cb_data the data it is going to be passed if executed
167 * returns the reqh id */
168 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*);
170 /* get callback data for a live request */
171 void* echld_reqh_get_data(echld_chld_id_t, echld_reqh_id_t);
173 /* get the total timeout time for a live request, -1 is err */
174 int echld_reqh_get_to(echld_chld_id_t, echld_reqh_id_t);
176 /* get the remaining timeout time for a live request, -1 is err */
177 int echld_reqh_get_remaining_to(echld_chld_id_t, echld_reqh_id_t);
179 /* get the callback for a live request */
180 echld_msg_cb_t echld_reqh_get_cb(echld_chld_id_t, echld_reqh_id_t);
182 /* set callback data for a live request */
183 echld_state_t echld_reqh_set_data(echld_chld_id_t, echld_reqh_id_t, void* );
185 /* get the callback for a live request */
186 echld_state_t echld_reqh_set_cb(echld_chld_id_t, echld_reqh_id_t, echld_msg_cb_t);
188 /* stop receiving a live request */
189 echld_state_t echld_reqh_detach(echld_chld_id_t, echld_reqh_id_t);
197 /* start a message handler */
198 echld_msgh_id_t echld_msgh(echld_chld_id_t, echld_msg_type_t, echld_msg_cb_t resp_cb, void* msg_data);
201 echld_state_t echld_msgh_detach(echld_chld_id_t, echld_msgh_id_t);
203 /* get a msgh's data */
204 void* echld_msgh_get_data(echld_chld_id_t, echld_msgh_id_t);
206 /* get a msgh's cb */
207 echld_msg_cb_t echld_msgh_get_cb(echld_chld_id_t, echld_msgh_id_t);
209 /* get a msgh's type */
210 echld_msg_type_t echld_msgh_get_type(echld_chld_id_t, echld_msgh_id_t);
212 /* get it all from a msgh */
213 echld_state_t echld_msgh_get_all(echld_chld_id_t, int msgh_id, echld_msg_type_t*, echld_msg_cb_t*, void**);
215 /* set a msgh's data */
216 echld_state_t echld_msgh_set_data(echld_chld_id_t, int msgh_id, void* );
218 /* set a msgh's cb */
219 echld_state_t echld_msgh_set_cb(echld_chld_id_t, int msgh_id, echld_msg_cb_t);
221 /* set a msgh's type */
222 echld_state_t echld_msgh_set_type(echld_chld_id_t, int msgh_id, echld_msg_type_t);
224 /* set all elements of a msgh */
225 echld_state_t echld_msgh_set_all(echld_chld_id_t, int msgh_id, echld_msg_type_t, echld_msg_cb_t, void*);
230 * these calls require you looping on echld_select() or calling echld_wait() until you get your answer.
234 typedef void (*echld_ping_cb_t)(int usec, void* data);
235 echld_state_t echld_ping(int child_id, echld_ping_cb_t cb, void* cb_data);
237 typedef void (*echld_list_interface_cb_t)(char* intf_name, char* params, void* cb_data);
238 echld_state_t echld_list_interfaces(int child_id, echld_list_interface_cb_t, void* cb_data);
240 typedef void (*echild_get_packet_summary_cb_t)(char* summary, void* data);
241 echld_state_t echld_open_file(int child_id, const char* filename,echild_get_packet_summary_cb_t,void*);
244 echld_state_t echld_open_interface(int child_id, const char* intf_name, const char* params);
245 echld_state_t echld_start_capture(int child_id, echild_get_packet_summary_cb_t);
246 echld_state_t echld_stop_capture(int child_id);
248 typedef void (*echild_get_packets_cb)(char* tree_text,void* data);
249 typedef void (*echild_get_buffer_cb)(char* buffer_text, void* data);
250 echld_state_t echld_get_packets_range(int child_id, const char* range, echild_get_packets_cb, echild_get_buffer_cb, void* data);
258 * waits until something gets done
260 * returns ECHLD_TIMEOUT or ECHLD_OK if something was done
262 echld_state_t echld_wait(tv_t* timeout);
264 #define ECHLD_WAIT() do { struct timeval tv; int rfds, efds; \
265 echld_select(echld_fdset(&rfds, &efds),&rfds, NULL, &efds, NULL) \
266 && echld_fd_read(&rfds, &efds); } while(0)
269 to be used in place of select() in the main loop of the parent code
270 it will serve the children pipes and return as if select() was called.
272 int echld_select(int nfds, fd_set* rfds, fd_set* wfds, fd_set* efds, tv_t* timeout);
274 /* or fit these two in your select loop */
276 /* returns nfds set */
277 int echld_fdset(fd_set* rfds, fd_set* efds);
279 int echld_fd_read(fd_set* rfds, fd_set* efds);
281 void echld_set_parent_dbg_level(int lvl);
284 #define ECHLD_MAX_CHILDREN 32
286 enum _echld_msg_type_t {
287 /* in = child to parent */
288 /* out = parent to child */
290 ECHLD_ERROR = '!', /* in: an error has occurred,
291 * this can be a response to most messages
292 * some errors are sent asyncronously (some are handled internally, some are then passed)
294 ECHLD_TIMED_OUT='/', /* in: A reqh has timed out (TO from now on)
295 * this can be a response to some messages
296 * some TOs are sent asyncronously (some are handled internally, some are then passed)
299 ECHLD_NEW_CHILD = '*', /* out: creates a new working child (handled internally) */
300 ECHLD_HELLO = '@', /* in: the working child has being created (handled internally, then passed to msgh) */
302 ECHLD_CHILD_DEAD = '#', /* in: a child has dead (handled internally, then passed to msgh) */
304 ECHLD_CLOSE_CHILD = 'Q', /* out: close the child */
305 ECHLD_CLOSING = 'q', /* in: the child is closing, error otherwise */
306 /* this handled internally as msgh, if your reqh_cb uses it make sure to return TRUE */
308 ECHLD_SET_PARAM = '>', /* out: set a parameter of a child */
309 ECHLD_GET_PARAM = '<', /* out: set a parameter of a child */
310 ECHLD_PARAM = 'p', /* in: the parameter's new/current value, error otherwise */
312 /* capture_filter string RO: set at open_capture */
313 /* monitor_mode string RW: use monitor mode if possible, error otherwise */
314 /* inc_pkt_ntfy_timeout number_string RW: timeout in usec after which notification is sent if no maxpackets have arrived yet */
315 /* inc_pkt_ntfy_maxpackets number_string RW: number of packets after which send a notification */
316 /* auto_sum RW: get summaries automatically (without a reqh, as msgh) */
317 /* auto_tree RW: get trees automatically (without a reqh, as msgh) */
318 /* auto_buffer RW: get buffers automatically (without a reqh, as msgh) */
319 /* cwd RW: the current working directory */
320 /* list_files WO: a file listing of the current dir */
321 /* interfaces RO: the interface listing */
322 /* dfilter RW: initial display filter*
325 ECHLD_PING = '}', /* out: ping the child */
326 ECHLD_PONG = '{', /* out: ping's response, error or TO otherwise */
328 ECHLD_CHK_FILTER = 'K', /* out: verify if a (display) filter works */
329 ECHLD_FILTER_CKD = 'k', /* in: yes this filter works, error or TO? otherwise */
331 ECHLD_OPEN_FILE = 'O', /* out: open a file */
332 ECHLD_FILE_OPENED = 'o', /* in: the file has being open, error otherwise */
334 ECHLD_OPEN_INTERFACE = 'C', /* out: request an interface to be open (get ready for capture) */
335 ECHLD_INTERFACE_OPENED = 'c', /* in: ready to start_capture, error otherwise */
337 ECHLD_START_CAPTURE = 'R', /* out: start capturing */
338 ECHLD_CAPTURE_STARTED = 'r', /* in: the capture has started, error otherwise */
340 ECHLD_NOTIFY = '%', /* in: many things can be notified by the child:
341 number of packets captured/read
342 other events in the future (?)
345 ECHLD_GET_SUM = 'S', /* out: get the summaries of a range of packets (even before they are notify'd) */
346 ECHLD_PACKET_SUM = 's', /* in: a packet's summary (when it arrives for a reqh) (in msgh if auto_sum )*/
347 /* no timeout, the request hangs until the packets in the range are available */
348 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
350 ECHLD_GET_TREE = 'G', /* out: get the decoded version of the packet */
351 ECHLD_TREE = 't', /* Child -> Parent */
352 /* no timeout, the request hangs until the packets in the range are available */
353 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
356 ECHLD_GET_BUFFER = 'B', /* out: get the decoded version of the packet */
357 ECHLD_BUFFER = 'b', /* in: get a buffer (or what we have of it... or the next part... same reqh_id) */
358 /* no timeout, the request hangs until the packets in the range are available */
359 /* error at EOF or CAPTURE_STOPPED if the request is still hanging */
361 ECHLD_EOF = 'z', /* in: will be delivered when a file has being read and all pendin ntfy,sums,trees and buffs have being passed
362 or after capture has stopped and all pending stuff is done */
364 ECHLD_STOP_CAPTURE = 'X', /* out: stop capturing */
365 ECHLD_CAPTURE_STOPPED = 'x', /* in: capture has stopped, error otherwise */
367 ECHLD_ADD_NOTE = 'N', /* out: add a note to the capture */
368 ECHLD_NOTE_ADDED = 'n', /* in: a note has being added */
370 ECHLD_APPLY_FILTER = 'A', /* in: apply a filter on the open file/capture */
371 ECHLD_PACKET_LIST = 'l', /* out: a packet list, or error or timeout */
372 /*(or what we have of it... or the next part... same reqh_id) */
374 ECHLD_SAVE_FILE = 'W', /* out: save the open file/capture */
375 ECHLD_FILE_SAVED = 'w', /* in: the file was saved */
378 EC_ACTUAL_ERROR = 0 /* this is not used in the protocol,
379 it is returned for an error in calls returning a message type */
384 ECHLD_ERR_UNIMPLEMENTED,
386 ECHLD_ERR_NO_SUCH_CHILD,
387 ECHLD_ERR_UNKNOWN_PID,
388 ECHLD_ERR_CANNOT_FORK,
389 ECHLD_ERR_SET_FILTER,
390 ECHLD_ERR_CANNOT_OPEN_FILE,
391 ECHLD_ERR_CANNOT_OPEN_INTERFACE,
392 ECHLD_ERR_CANNOT_START_CAPTURE,
393 ECHLD_ERR_CANNOT_LIST_INTERFACES,
394 ECHLD_CANNOT_SET_PARAM,
395 ECHLD_CANNOT_GET_PARAM,
396 ECHLD_ERR_CRASHED_CHILD,