Compiles, still incomplete...
[metze/wireshark/wip.git] / echld.h
1 /* echld_child.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 #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 */
33
34 #define ECHLD_MINOR_VERSION 0 /* increases when new things are added */
35                                                           /* if just this one changes an old client will still work */
36
37 /*
38  * You should take a look to doc/README.epan_child before reading this
39  */
40
41 /* message types */
42 typedef enum _echld_msg_type_t echld_msg_type_t;
43
44 /* error types */
45 typedef enum _echld_error echld_error_t;
46
47 /* return codes */
48  /* 0 is ok, everything else is ko, or timeout where applicable. */
49 typedef int echld_state_t;
50 #define ECHLD_OK 0
51 #define ECHLD_TIMEOUT -222
52
53 /* id for child working processes, a negative value is an error */
54 typedef int echld_chld_id_t;
55
56 /* id of requests, a negative value is an error */
57 typedef int echld_reqh_id_t;
58
59 /* id of message handlers, a negative value is an error */
60 typedef int echld_msgh_id_t;
61
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' 
67 } echld_encoding_t;
68
69 typedef int echld_bool_t;
70
71 /* typedef for a timeval so that sys/time.h is not required in the client */
72 typedef struct timeval tv_t;
73
74 /* will initialize epan registering protocols and taps */
75 echld_state_t echld_initialize(echld_encoding_t);
76
77 /* cleans up (?) echld and kills the server process(es) */
78 echld_state_t echld_terminate(void);
79
80 /*
81  * returning ECHLD_NO_ERROR means there has being no error
82  *
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.
85  *
86  * for managing asyncronous errors use a msgh for ECHLD_ERROR
87  * the response cb of reqh might be a ECHLD_ERROR message
88  */
89 echld_error_t echld_get_error(const char** errstr_ptr);
90
91 /*
92  *  Children Management Operations
93  */
94
95 /* create a new worker process */
96 echld_chld_id_t echld_new(void* child_data);
97
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);
100
101 echld_state_t echld_set_data(echld_chld_id_t id, void* child_data);
102
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);
106
107 /* enc_msg_t is an obscure object for an encoded message */
108 typedef struct GByteArray enc_msg_t;
109
110
111 /*
112  * prototype of message callbacks passed to echld_reqh() and echld_msgh()
113  *
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()
118  * 
119  * returns TRUE if other potential handlers are to be run, false otherwise
120  */
121 typedef echld_bool_t (*echld_msg_cb_t)(echld_msg_type_t type, enc_msg_t* msg_buff, void* cb_data);
122
123
124
125 /* encoding and decoding */
126
127
128 /*
129  * encoder
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.
132  */
133  
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;
147
148 echld_parent_encoder_t* echld_get_encoder();
149
150 /*
151  * decoder
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.
154  */
155 char* echld_decode(echld_msg_type_t, enc_msg_t*);
156
157 /*
158  *  Request Handlers
159  *
160  */
161
162 /* send a request with an optional response handler 
163  *
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
166  * 
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*);
169
170 /* get callback data for a live request */
171 void* echld_reqh_get_data(echld_chld_id_t, echld_reqh_id_t);
172
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);
175
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);
178
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);
181
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* );
184
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);
187
188 /* stop receiving a live request */
189 echld_state_t echld_reqh_detach(echld_chld_id_t, echld_reqh_id_t);
190
191
192 /*
193  *  Message Handlers
194  *
195  */
196
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);
199
200 /* stop it */
201 echld_state_t echld_msgh_detach(echld_chld_id_t, echld_msgh_id_t); 
202
203 /* get a msgh's data */
204 void* echld_msgh_get_data(echld_chld_id_t, echld_msgh_id_t);
205
206 /* get a msgh's cb */
207 echld_msg_cb_t echld_msgh_get_cb(echld_chld_id_t, echld_msgh_id_t);
208
209 /* get a msgh's type */
210 echld_msg_type_t echld_msgh_get_type(echld_chld_id_t, echld_msgh_id_t);
211
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**);
214
215 /* set a msgh's data */
216 echld_state_t echld_msgh_set_data(echld_chld_id_t, int msgh_id, void* );
217
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);
220
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);
223
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*);
226
227
228 /*
229  * "Simple" API
230  * these calls require you looping on echld_select() or calling echld_wait() until you get your answer.
231  * see bellow
232  */
233
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);
236
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);
239
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*);
242
243
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);
247
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);
251
252
253 /*
254  * Server routines
255  */
256
257 /*
258  * waits until something gets done
259  *
260  * returns ECHLD_TIMEOUT or ECHLD_OK if something was done
261  */
262 echld_state_t echld_wait(tv_t* timeout);
263
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)
267
268 /*
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.
271 */
272 int echld_select(int nfds, fd_set* rfds, fd_set* wfds, fd_set* efds, tv_t* timeout);
273
274 /* or fit these two in your select loop */
275
276 /* returns nfds set */
277 int echld_fdset(fd_set* rfds, fd_set* efds);
278
279 int echld_fd_read(fd_set* rfds, fd_set* efds);
280
281 void echld_set_parent_dbg_level(int lvl);
282
283
284 #define ECHLD_MAX_CHILDREN 32
285
286 enum _echld_msg_type_t {
287         /*  in = child to parent */
288         /* out = parent to child */
289
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)
293                                                 */
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)
297                                                 */
298
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) */
301         
302         ECHLD_CHILD_DEAD = '#', /* in: a child has dead (handled internally, then passed to msgh) */
303
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 */
307
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  */
311
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*
323                                                 /* ... */
324
325         ECHLD_PING = '}', /* out: ping the child  */
326         ECHLD_PONG = '{', /* out: ping's response, error or TO otherwise */
327         
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 */
330
331         ECHLD_OPEN_FILE = 'O', /* out: open a file  */
332         ECHLD_FILE_OPENED = 'o', /* in: the file has being open, error otherwise */
333
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 */
336
337         ECHLD_START_CAPTURE = 'R',  /* out: start capturing */
338         ECHLD_CAPTURE_STARTED = 'r',  /* in: the capture has started, error otherwise */
339
340         ECHLD_NOTIFY = '%', /* in: many things can be notified by the child:
341                                                                 number of packets captured/read
342                                                                 other events in the future (?)
343                                                                 */
344
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 */
349
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 */
354
355
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 */
360
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 */
363
364         ECHLD_STOP_CAPTURE = 'X',  /* out: stop capturing  */
365         ECHLD_CAPTURE_STOPPED = 'x',  /* in: capture has stopped, error otherwise */
366
367         ECHLD_ADD_NOTE = 'N', /* out: add a note to the capture  */
368         ECHLD_NOTE_ADDED = 'n', /* in: a note has being added */
369         
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) */
373         
374         ECHLD_SAVE_FILE = 'W', /* out: save the open file/capture  */
375         ECHLD_FILE_SAVED = 'w', /* in: the file was saved */
376
377
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  */
380 };
381
382 enum _echld_error {
383         ECHLD_NO_ERROR = 0,
384         ECHLD_ERR_UNIMPLEMENTED,
385         ECHLD_ERR_WRONG_MSG,
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,
397         ECHLD_ERR_OTHER
398 };
399
400
401 #endif