Remove all $Id$ from top of file
[metze/wireshark/wip.git] / echld / common.c
1 /* echld_common.h
2  *  common functions of ECHLD
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "echld-int.h"
26
27 #ifdef DEBUG_BASE
28
29 static int dbg_level = DEBUG_BASE;
30 static FILE* dbg_fp;
31 static const char* dbg_prefix;
32
33 static void common_dbg(int level, const char* fmt, ...) {
34         va_list ap;
35         char str[1024];
36
37         if (level > dbg_level) return;
38
39         va_start(ap,fmt);
40         g_vsnprintf(str,1024,fmt,ap);
41         va_end(ap);
42
43         if (dbg_fp) {
44                 fprintf(dbg_fp,"%s: level=%d msg='%s'\n",dbg_prefix,level,str);
45                 fflush(dbg_fp);
46         }
47 }
48
49 extern void echld_common_set_dbg(int level, FILE* fp, const char* prefix) {
50         dbg_prefix = prefix;
51         dbg_level = level;
52         dbg_fp = fp;
53 }
54 #define DBG(attrs) ( common_dbg attrs )
55 #else
56 #define DBG(attrs)
57 #endif
58
59
60 struct _st_map
61 {
62         child_state_t id;
63         const char* str;
64 };
65
66 static struct _st_map st_map[] = {
67         { FREE, "FREE"},
68         { CREATING, "CREATING"},
69         { IDLE, "IDLE"},
70         { READY, "READY"},
71         { READING, "READING"},
72         { CAPTURING, "CAPTURING"},
73         { DONE, "DONE"},
74         { CLOSING, "CLOSING"},
75         { CLOSED, "CLOSED"},
76         { ERRORED, "ERRORED"},
77         {0,NULL}
78 };
79
80 const char* echld_state_str(child_state_t id) {
81         int i = 0;
82
83         for (;st_map[i].str;i++) {
84                 if (id == st_map[i].id) return st_map[i].str;
85         }
86
87         return "UNKNOWN";
88 }
89
90
91 struct _t_map
92 {
93         echld_msg_type_t type;
94         const char* str;
95 };
96
97 static struct _t_map t_map[] = {
98         {ECHLD_ERROR,"ERROR"},
99         {ECHLD_TIMED_OUT,"TIMED_OUT"},
100         {ECHLD_NEW_CHILD,"NEW_CHILD"},
101         {ECHLD_HELLO,"HELLO"},
102         {ECHLD_CHILD_DEAD,"CHILD_DEAD"},
103         {ECHLD_CLOSE_CHILD,"CLOSE_CHILD"},
104         {ECHLD_CLOSING,"CLOSING"},
105         {ECHLD_SET_PARAM,"SET_PARAM"},
106         {ECHLD_GET_PARAM,"GET_PARAM"},
107         {ECHLD_PARAM,"PARAM"},
108         {ECHLD_PING,"PING"},
109         {ECHLD_PONG,"PONG"},
110         {ECHLD_OPEN_FILE,"OPEN_FILE"},
111         {ECHLD_FILE_OPENED,"FILE_OPENED"},
112         {ECHLD_OPEN_INTERFACE,"OPEN_INTERFACE"},
113         {ECHLD_INTERFACE_OPENED,"INTERFACE_OPENED"},
114         {ECHLD_START_CAPTURE,"START_CAPTURE"},
115         {ECHLD_CAPTURE_STARTED,"CAPTURE_STARTED"},
116         {ECHLD_NOTIFY,"NOTIFY"},
117         {ECHLD_GET_SUM,"GET_SUM"},
118         {ECHLD_PACKET_SUM,"PACKET_SUM"},
119         {ECHLD_GET_TREE,"GET_TREE"},
120         {ECHLD_TREE,"TREE"},
121         {ECHLD_GET_BUFFER,"GET_BUFFER"},
122         {ECHLD_BUFFER,"BUFFER"},
123         {ECHLD_EOF,"EOF"},
124         {ECHLD_STOP_CAPTURE,"STOP_CAPTURE"},
125         {ECHLD_CAPTURE_STOPPED,"CAPTURE_STOPPED"},
126         {ECHLD_ADD_NOTE,"ADD_NOTE"},
127         {ECHLD_NOTE_ADDED,"NOTE_ADDED"},
128         {ECHLD_APPLY_FILTER,"APPLY_FILTER"},
129         {ECHLD_PACKET_LIST,"PACKET_LIST"},
130         {ECHLD_SAVE_FILE,"SAVE_FILE"},
131         {ECHLD_FILE_SAVED,"FILE_SAVED"},
132         {ECHLD_NULL,NULL}
133 };
134
135 const char* echld_msg_type_str(echld_msg_type_t id) {
136         int i = 0;
137
138         for (;t_map[i].str;i++) {
139                 if (id == t_map[i].type) return t_map[i].str;
140         }
141
142         return "UNKNOWN";
143 }
144
145
146 /**
147  the "epan pipe" protocol
148 **/
149
150 typedef void (*reader_realloc_t)(echld_reader_t*, size_t);
151
152 static void child_realloc_buff(echld_reader_t* r, size_t needed) {
153         size_t a = r->actual_len;
154         size_t s = r->len;
155         long rp_off = r->rp - r->data;
156
157         DBG((2,"REALLOC BUFF needed=%d",needed));
158
159         if ( a < (s + needed) ) {
160                 guint8* data = r->data;
161
162                 do {
163                         a *= 2;
164                 } while( a < (s + needed) );
165
166            data = (guint8*)g_realloc(data,a);
167
168            r->actual_len = a;
169            r->len = s;
170            r->data = data;
171            r->wp = data + s;
172            r->rp = data + rp_off;
173         }
174 }
175
176 static reader_realloc_t reader_realloc_buff = child_realloc_buff;
177
178 #ifdef PARENT_THREADS
179 static void parent_realloc_buff(echld_reader_t* b, size_t needed) {
180         // parent thread: obtain malloc mutex
181         child_realloc_buff(b,needed);
182         // parent thread: release malloc mutex
183 }
184 #endif
185
186
187
188 void echld_reset_reader(echld_reader_t* r, int fd, size_t initial) {
189         r->fd = fd;
190         fcntl(fd, F_SETFL, O_NONBLOCK);
191
192         if (r->data == NULL) {
193                 r->actual_len = initial;
194                 r->data =(guint8*) g_malloc0(initial);
195                 r->wp = r->data;
196                 r->rp = r->data;
197                 r->len = 0;
198         } else {
199                 r->wp = r->data;
200                 r->rp = r->data;
201                 r->len = 0;
202         }
203 }
204
205 void echld_init_reader(echld_reader_t* r, int fd, size_t initial) {
206         echld_reset_reader(r,fd,initial);
207 }
208
209
210
211 void free_reader(echld_reader_t* r) {
212         free(r->data);
213 }
214
215 static long reader_readv(echld_reader_t* r, size_t len) {
216         struct iovec iov;
217         long nread;
218
219         DBG((2,"READV needed=%d",len));
220
221         if ( (r->actual_len - r->len) < len )
222                 reader_realloc_buff(r, len);
223
224         iov.iov_base = r->wp;
225         iov.iov_len = len;
226
227         nread = readv(r->fd, &iov, 1);
228
229         DBG((2,"READV nread=%d msg='%s'",nread, (nread<0) ? strerror(errno) : "-" ));
230
231         if (nread >= 0) {
232                 r->wp += nread;
233                 r->len += nread;
234         }
235
236         if (errno == EAGAIN) return 0;
237
238         return nread;
239 };
240
241
242 long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) {
243         DBG((4,"READ = echld_read_frame fd=%d",r->fd));
244
245     // it will use shared memory instead of inband communication
246         do {
247                 hdr_t* h = (hdr_t*)r->rp;
248                 long nread;
249                 size_t fr_len = 0;
250                 size_t missing;
251
252                 DBG((5,"READ reader_len=%d",r->len));
253
254                 if ( r->len < ECHLD_HDR_LEN) {
255                         /* read the header */
256                         goto incomplete_header;
257                 } else if ( ! reader_has_frame(r) ) {
258                         /* read the (rest of) the frame */
259                         goto incomplete_frame;
260                 }
261
262                 DBG((5,"READ we've got a frame! fr_len=%d ch=%d t='%c' rh=%d",fr_len, h->h.chld_id, HDR_TYPE(h), h->h.reqh_id));
263
264
265                 cb( &(r->rp[sizeof(hdr_t)]), HDR_LEN(h), h->h.chld_id, HDR_TYPE(h), h->h.reqh_id, cb_data);
266
267                 r->len = 0;
268                 r->wp = r->data;
269                 r->rp = r->data;
270
271                 DBG((5,"READ consumed frame!"));
272
273                 goto again;
274
275         incomplete_header:
276                 missing = ECHLD_HDR_LEN - (r->len);
277                 DBG((5,"READ incomplete_header missing=%d",missing));
278
279                 nread = reader_readv(r,missing);
280
281
282                 if (nread < 0 && errno != EAGAIN) {
283                         goto kaput; /*XXX*/
284                 } else if (nread < (long)missing) {
285                         goto again;
286                 } else {
287                         goto incomplete_frame;
288                 }
289
290         incomplete_frame:
291                 fr_len = HDR_LEN(h) + ECHLD_HDR_LEN;
292                 missing = fr_len  - r->len;
293
294                 DBG((5,"READ incomplete_frame fr_len=%d missing=%d",fr_len ,missing));
295
296                 if (missing) {
297                         nread = reader_readv(r,missing);
298
299                         if (nread < 0 && errno != EAGAIN) {
300                                 goto kaput; /*XXX*/
301                         } else if (nread < (long)missing) {
302                                 goto again;
303                         }
304                 }
305
306         } while(1);
307
308         DBG((1,"READ incomplete_frame Cannot happen"));
309
310         return 0;
311         again:  return 1;
312         kaput:  return -1;
313 }
314
315 long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data _U_) {
316         hdr_t h;
317         struct iovec iov[2];
318         int iov_cnt = 1;
319
320
321         h.h.type_len  = (type<<24) | ((ba?ba->len:0) & 0x00ffffff) ;
322         h.h.chld_id = chld_id;
323         h.h.reqh_id = reqh_id;
324
325         iov[0].iov_base = &h;
326         iov[0].iov_len = 8;
327
328         if ( ba && ba->len > 0 ) {
329                 iov[1].iov_base = ba->data;
330                 iov[1].iov_len = ba->len;
331                 iov_cnt++;
332         }
333
334         return (long) writev(fd, iov, iov_cnt);
335 }
336
337 /* paramset management */
338
339 param_t* paramset_find (param_t* paramsets, char* name, char** err) {
340         int i;
341         for (i = 0; paramsets[i].name != NULL;i++) {
342                 if (strcmp(name,paramsets[i].name) == 0 ) return &(paramsets[i]);
343         }
344
345         *err = g_strdup_printf("Could not find param='%s'",name);
346         return NULL;
347 }
348
349 echld_bool_t paramset_apply_set (param_t* paramsets, char* name, char* val, char** err) {
350         param_t* p = paramset_find(paramsets,name,err);
351
352         if ( !p ) return FALSE;
353         if ( ! p->set ) {
354                 *err = g_strdup_printf("Cannot set RO param='%s'",name);
355                 return FALSE;
356         }
357
358         return p->set(val,err);
359 }
360
361 char* paramset_apply_get (param_t* paramsets, char* name, char** err) {
362         param_t* p = paramset_find(paramsets,name,err);
363
364         if ( !p ) return NULL;
365
366         if ( ! p->get ) {
367                 *err = g_strdup_printf("Cannot get WO param='%s'",name);
368                 return NULL;
369         }
370
371         return p->get(err);
372 }
373
374 echld_bool_t paramset_apply_em(param_t* paramset, enc_msg_t* em, char** err) {
375         GByteArray* ba = (GByteArray*)em;
376         char* p = (char*) ba->data;
377         int tot_len = ba->len;
378         long rem = tot_len;
379         p[rem-1] = '\0'; /* make sure last char is null */
380
381         while(rem > 2) {
382                 char* param = p;
383                 long param_len = strlen(param)+1;
384                 char* value = p + param_len;
385                 long value_len;
386
387                 rem -= param_len;
388
389                 if (rem < 0) {
390                         *err = g_strdup_printf("Malformed msg param len invalid");
391                         return FALSE;
392                 }
393
394                 value_len = strlen(value)+1;
395
396                 rem -= value_len;
397                 p = value + value_len;
398
399                 if (rem < 0) {
400                         *err = g_strdup_printf("Malformed msg value len invalid");
401                         return FALSE;
402                 }
403
404                 if (! paramset_apply_set(paramset,param,value,err))
405                         return FALSE;
406         }
407
408         return TRUE;
409 }
410
411 char* paramset_get_params_list(param_t* paramsets,const char* fmt) {
412         param_t* p = paramsets;
413         GString* str = g_string_new("");
414         char* s;
415
416         for (;p->name;p++) {
417                 g_string_append_printf(str,fmt,
418                         p->name,
419                         ((p->get && p->set)?"rw":(p->get?"ro":"wo")),
420                         p->desc);
421         }
422
423         s = str->str;
424         g_string_free(str,FALSE);
425         return s;
426 }
427
428
429
430
431 /* encoders and decoders */
432
433
434
435
436
437 /* binary encoders and decoders used for parent->child communication */
438
439 static enc_msg_t* str_enc(const char* s) {
440         GByteArray* ba = g_byte_array_new();
441         g_byte_array_append(ba,s,(guint)(strlen(s)+1));
442         return (enc_msg_t*)ba;
443 }
444
445 static gboolean str_dec(guint8* b, size_t bs, char** text) {
446         guint8* end = b+bs;
447         b[bs-1] = '\0'; /* null terminate the buffer to avoid strlen running */
448         *text = (char*)b;
449         if (b+(strlen(b)+1) > end) return FALSE;
450         return TRUE;
451 }
452
453 static gboolean str_deca(enc_msg_t* ba, char** text) {
454         return str_dec(ba->data,ba->len,text);
455 }
456
457 static enc_msg_t* int_str_enc(int i, const char* s) {
458         GByteArray* ba = g_byte_array_new();
459         g_byte_array_append(ba,(guint8*)&i,sizeof(int));
460         g_byte_array_append(ba,s,(guint)(strlen(s)+1));
461         return (enc_msg_t*)ba;
462 }
463
464 static gboolean int_str_dec(guint8* b, size_t bs, int* ip, char** text) {
465         guint8* end = b+bs;
466         b[bs-1] = '\0'; /* null terminate the buffer to avoid strlen running */
467
468         if ((sizeof(int)) > bs) return FALSE;
469         *ip = *((int*)b);
470         b += (sizeof(int));
471         *text = (char*)b;
472         if ((b += (strlen(b)+1)) > end) return FALSE;
473
474         return TRUE;
475 }
476
477 static gboolean int_str_deca(enc_msg_t* ba, int* ip, char** text) {
478         return int_str_dec(ba->data,ba->len,ip,text);
479 }
480
481 static enc_msg_t* int_enc(int i) {
482         GByteArray* ba = g_byte_array_new();
483         g_byte_array_append(ba,(guint8*)&i,sizeof(int));
484         return (enc_msg_t*)ba;
485 }
486
487 static gboolean int_dec(guint8* b, size_t bs, int* ip) {
488         if ((sizeof(int)) > bs) return FALSE;
489         *ip = *((int*)b);
490         return TRUE;
491 }
492
493 static gboolean int_deca(enc_msg_t* ba, int* ip) {
494         return int_dec(ba->data,ba->len,ip);
495 }
496
497 static enc_msg_t* x2str_enc(const char* s1, const char* s2) {
498         GByteArray* ba = g_byte_array_new();
499         g_byte_array_append(ba,s1,(guint)(strlen(s1)+1));
500         g_byte_array_append(ba,s2,(guint)(strlen(s2)+1));
501         return (enc_msg_t*)ba;
502 }
503
504 static gboolean x2str_dec(guint8* b, size_t blen, char** str1, char** str2) {
505         guint8* end = b+blen;
506         b[blen-1] = '\0'; /* null terminate the buffer to avoid strlen running */
507
508         *str1  = (char*)b;
509         if ((b += (strlen(b)+1)) > end) return FALSE;
510         *str2 = (char*)(b);
511         if ((b += (strlen(b)+1)) > end) return FALSE;
512         return TRUE;
513 }
514
515 static gboolean x2str_deca(enc_msg_t* ba, char** str1, char** str2) {
516         return x2str_dec(ba->data,ba->len,str1,str2);
517 }
518
519 static gboolean int_3str_dec (guint8* b, size_t len, int* i, char** s1, char** s2, char** s3) {
520         guint8* end = b+len;
521         b[len-1] = '\0';
522
523         if ((sizeof(int)) > len) return FALSE;
524         *i = *((int*)b);
525         b += sizeof(int);
526
527         *s1 = (char*)b;
528         if ((b += (strlen(b)+1)) > end) return FALSE;
529         *s2 = (char*)(b);
530         if ((b += (strlen(b)+1)) > end) return FALSE;
531         *s3 = (char*)b;
532         if ((b += (strlen(b)+1)) > end) return FALSE;
533         return TRUE;
534 }
535
536 static enc_msg_t* int_3str_enc(int i,  const char* s1, const char* s2, const char* s3) {
537         GByteArray* ba = g_byte_array_new();
538         g_byte_array_append(ba,(guint8*)&i,sizeof(int));
539         g_byte_array_append(ba,s1,(guint)(strlen(s1)+1));
540         g_byte_array_append(ba,s2,(guint)(strlen(s2)+1));
541         g_byte_array_append(ba,s3,(guint)(strlen(s3)+1));
542         return (enc_msg_t*)ba;
543 }
544
545 static gboolean int_3str_deca (enc_msg_t* e, int* i, char** s1, char** s2, char** s3) {
546         return int_3str_dec(e->data,e->len,i,s1,s2,s3);
547 }
548
549 static gboolean x3str_dec (guint8* b, size_t len, char** s1, char** s2, char** s3) {
550         guint8* end = b+len;
551         b[len-1] = '\0';
552
553
554         *s1 = (char*)b;
555         if ((b += (strlen(b)+1)) > end) return FALSE;
556         *s2 = (char*)(b);
557         if ((b += (strlen(b)+1)) > end) return FALSE;
558         *s3 = (char*)b;
559         if ((b += (strlen(b)+1)) > end) return FALSE;
560         return TRUE;
561 }
562
563 static gboolean x3str_deca (enc_msg_t* e, char** s1, char** s2, char** s3) {
564         return x3str_dec(e->data,e->len,s1,s2,s3);
565 }
566
567
568 static enc_msg_t* x3str_enc(const char* s1, const char* s2, const char* s3) {
569         GByteArray* ba = g_byte_array_new();
570         g_byte_array_append(ba,s1,(guint)(strlen(s1)+1));
571         g_byte_array_append(ba,s2,(guint)(strlen(s2)+1));
572         g_byte_array_append(ba,s3,(guint)(strlen(s3)+1));
573         return (enc_msg_t*)ba;
574 }
575
576 static echld_parent_encoder_t parent_encoder = {
577         int_str_enc,
578         str_enc,
579         x2str_enc,
580         int_enc,
581         str_enc,
582         x2str_enc,
583         str_enc,
584         str_enc,
585         str_enc,
586         int_str_enc,
587         str_enc,
588         x2str_enc
589 };
590
591 echld_parent_encoder_t* echld_get_encoder(void) {
592         return &parent_encoder;
593 }
594
595 static child_decoder_t child_decoder = {
596         int_str_dec,
597         x2str_dec,
598         str_dec,
599         int_dec,
600         str_dec,
601         x2str_dec,
602         str_dec,
603         str_dec,
604         str_dec,
605         int_str_dec,
606         str_dec,
607         x2str_dec
608 };
609
610 static child_encoder_t  child_encoder = {
611         int_str_enc,
612         str_enc,
613         x2str_enc,
614         str_enc,
615         int_str_enc,
616         int_str_enc,
617         int_3str_enc,
618         x3str_enc
619 };
620
621 static parent_decoder_t parent_decoder = {
622         int_str_deca,
623         str_deca,
624         x2str_deca,
625         str_deca,
626         int_str_deca,
627         int_str_deca,
628         int_3str_deca,
629         x3str_deca
630 };
631
632 void echld_get_all_codecs( child_encoder_t **e, child_decoder_t **d, echld_parent_encoder_t **pe, parent_decoder_t** pd) {
633         e && (*e = &child_encoder);
634         d && (*d = &child_decoder);
635         pe && (*pe = &parent_encoder);
636         pd && (*pd = &parent_decoder);
637 }
638
639
640
641 /* output encoders, used in the switch */
642
643
644 static char* packet_summary_json(GByteArray* ba _U_) {
645         /* dummy */
646         return g_strdup("{type='packet_summary', packet_summary={}");
647 }
648
649 static char* tree_json(GByteArray* ba _U_) {
650         /* dummy */
651         return g_strdup("{type='tree', tree={}");
652 }
653
654 char* tvb_json(GByteArray* ba  _U_, tvb_t* tvb  _U_, const char* name) {
655         /* dummy */
656         return g_strdup_printf("{type='buffer', buffer={name='%s', range='0-2', data=[0x12,0xff] }",name);
657 }
658
659 static char* error_json(GByteArray* ba) {
660         char* s = (char*)(ba->data + sizeof(int));
661         int i = *((int*)s);
662
663         s = g_strdup_printf("{type='error', error={errnum=%d, message='%s'}}",i,s);
664
665         return s;
666 }
667
668 static char* child_dead_json(GByteArray* ba) {
669         char* s = (char*)(ba->data + sizeof(int));
670         int i = *((int*)s);
671
672         s = g_strdup_printf("{type='child_dead', child_dead={childnum=%d, message='%s'}}",i,s);
673
674         return s;
675 }
676
677 static char* closing_json(GByteArray* ba) {
678         char* s = (char*)(ba->data);
679         s = g_strdup_printf("{type='closing', closing={reason='%s'}}",s);
680
681         return s;
682 }
683
684
685
686 static char* note_added_json(GByteArray* ba) {
687         char* s = (char*)(ba->data);
688         s = g_strdup_printf("{ type='note_added', note_added={msg='%s'}}",s);
689
690         return s;
691 }
692
693 static char* packet_list_json(GByteArray* ba _U_) {
694         return g_strdup("{}");
695 }
696
697 static char* file_saved_json(GByteArray* ba) {
698         char* s = (char*)(ba->data);
699
700         s = g_strdup_printf("{ type='file_saved', file_saved={msg='%s'}}",s);
701
702         return s;
703 }
704
705
706
707 static char* param_set_json(GByteArray* ba) {
708         char* s1 = (char*)(ba->data);
709         char* s2 = ((char*)(ba->data)) + strlen(s1);
710
711         s1 = g_strdup_printf("{type='param_set', param_set={param='%s' value='%s'}}",s1,s2);
712
713
714         return s1;
715 }
716
717 static char* set_param_json(GByteArray* ba) {
718         char* s1 = (char*)(ba->data);
719         char* s2 = ((char*)(ba->data)) + strlen(s1);
720
721         s1 = g_strdup_printf("{type='set_param', set_param={param='%s' value='%s'}}",s1,s2);
722
723
724         return s1;
725 }
726
727 static char* get_param_json(GByteArray* ba) {
728         char* s1 = (char*)(ba->data);
729
730         s1 = g_strdup_printf("{type='get_param', get_param={param='%s'}}",s1);
731
732
733         return s1;
734 }
735
736 static char* file_opened_json(GByteArray* ba _U_) {
737         return g_strdup("");
738 }
739
740 static char* open_file_json(GByteArray* ba _U_) {
741         return g_strdup("");
742 }
743
744 static char* open_interface_json(GByteArray* ba _U_) {
745         return g_strdup("");
746 }
747
748
749 static char* interface_opened_json(GByteArray* ba _U_) {
750         return g_strdup("");
751 }
752
753 static char* notify_json(GByteArray* ba _U_) {
754         return g_strdup("");
755 }
756
757 static char* get_tree_json(GByteArray* ba _U_) {
758         return g_strdup("");
759 }
760
761 static char* get_sum_json(GByteArray* ba _U_) {
762         return g_strdup("");
763 }
764
765 static char* get_buffer_json(GByteArray* ba _U_) {
766         return g_strdup("");
767 }
768
769 static char* buffer_json(GByteArray* ba _U_) {
770         return g_strdup("");
771 }
772
773 static char* add_note_json(GByteArray* ba _U_) {
774         return g_strdup("");
775 }
776
777 static char* apply_filter_json(GByteArray* ba _U_) {
778         return g_strdup("");
779 }
780
781 static char* save_file_json(GByteArray* ba _U_) {
782         return g_strdup("");
783 }
784
785
786 /* this to be used only at the parent */
787 static char* decode_json(echld_msg_type_t type, enc_msg_t* m) {
788         GByteArray* ba = (GByteArray*)m;
789
790         switch(type) {
791                 case ECHLD_ERROR: return error_json(ba);
792                 case ECHLD_TIMED_OUT: return g_strdup("{type='timed_out'}");
793                 case ECHLD_NEW_CHILD: return g_strdup("{type='new_child'}");
794                 case ECHLD_HELLO: return g_strdup("{type='helo'}");
795                 case ECHLD_CHILD_DEAD: return child_dead_json(ba);
796                 case ECHLD_CLOSE_CHILD: return g_strdup("{type='close_child'}");
797                 case ECHLD_CLOSING: return closing_json(ba);
798                 case ECHLD_SET_PARAM: return set_param_json(ba);
799                 case ECHLD_GET_PARAM: return get_param_json(ba);
800                 case ECHLD_PARAM: return param_set_json(ba);
801                 case ECHLD_PING: return g_strdup("{type='ping'}");
802                 case ECHLD_PONG: return g_strdup("{type='pong'}");
803                 case ECHLD_OPEN_FILE: return open_file_json(ba);
804                 case ECHLD_FILE_OPENED: return file_opened_json(ba);
805                 case ECHLD_OPEN_INTERFACE: return open_interface_json(ba);
806                 case ECHLD_INTERFACE_OPENED: return interface_opened_json(ba);
807                 case ECHLD_START_CAPTURE: return g_strdup("{type='start_capture'}");
808                 case ECHLD_CAPTURE_STARTED: return g_strdup("{type='capture_started'}");
809                 case ECHLD_NOTIFY: return notify_json(ba);
810                 case ECHLD_GET_SUM: return get_sum_json(ba);
811                 case ECHLD_PACKET_SUM: return packet_summary_json(ba);
812                 case ECHLD_GET_TREE: return get_tree_json(ba);
813                 case ECHLD_TREE: return tree_json(ba);
814                 case ECHLD_GET_BUFFER: return get_buffer_json(ba);
815                 case ECHLD_BUFFER: return buffer_json(ba);
816                 case ECHLD_EOF: return g_strdup("{type='eof'}");
817                 case ECHLD_STOP_CAPTURE: return g_strdup("{type='stop_capture'}");
818                 case ECHLD_CAPTURE_STOPPED: return g_strdup("{type='capture_stopped'}");
819                 case ECHLD_ADD_NOTE: return add_note_json(ba);
820                 case ECHLD_NOTE_ADDED: return note_added_json(ba);
821                 case ECHLD_APPLY_FILTER: return apply_filter_json(ba);
822                 case ECHLD_PACKET_LIST: return packet_list_json(ba);
823                 case ECHLD_SAVE_FILE: return save_file_json(ba);
824                 case ECHLD_FILE_SAVED: return file_saved_json(ba);
825                 case EC_ACTUAL_ERROR: return g_strdup("{type='actual_error'}");
826                 default: break;
827         }
828
829         return NULL;
830 }
831 char* echld_decode(echld_msg_type_t t, enc_msg_t* m ) {
832         return decode_json(t,m);
833 }
834
835
836
837 extern void dummy_switch(echld_msg_type_t type) {
838         switch(type) {
839                 case ECHLD_ERROR: break; //
840                 case ECHLD_TIMED_OUT: break;
841                 case ECHLD_NEW_CHILD: break;
842                 case ECHLD_HELLO: break;
843                 case ECHLD_CHILD_DEAD: break; //S msg
844                 case ECHLD_CLOSE_CHILD: break;
845                 case ECHLD_CLOSING: break; //
846                 case ECHLD_SET_PARAM: break;
847                 case ECHLD_GET_PARAM: break;
848                 case ECHLD_PARAM: break; //SS param,val
849                 case ECHLD_PING: break;
850                 case ECHLD_PONG: break; //
851                 case ECHLD_OPEN_FILE: break;
852                 case ECHLD_FILE_OPENED: break; //
853                 case ECHLD_OPEN_INTERFACE: break;
854                 case ECHLD_INTERFACE_OPENED: break; //
855                 case ECHLD_START_CAPTURE: break;
856                 case ECHLD_CAPTURE_STARTED: break; //
857                 case ECHLD_NOTIFY: break; //S notification (pre-encoded)
858                 case ECHLD_GET_SUM: break;
859                 case ECHLD_PACKET_SUM: break; //S (pre-encoded)
860                 case ECHLD_GET_TREE: break;
861                 case ECHLD_TREE: break; //IS framenum,tree (pre-encoded)
862                 case ECHLD_GET_BUFFER: break;
863                 case ECHLD_BUFFER: break; //SSIS name,range,totlen,data
864                 case ECHLD_EOF: break; //
865                 case ECHLD_STOP_CAPTURE: break;
866                 case ECHLD_CAPTURE_STOPPED: break; //
867                 case ECHLD_ADD_NOTE: break;
868                 case ECHLD_NOTE_ADDED: break; //IS
869                 case ECHLD_APPLY_FILTER: break;
870                 case ECHLD_PACKET_LIST: break; //SS name,range
871                 case ECHLD_SAVE_FILE: break;
872                 case ECHLD_FILE_SAVED: break;
873                 case EC_ACTUAL_ERROR: break;
874         }
875
876         switch(type) {
877                 case ECHLD_NEW_CHILD: break;
878                 case ECHLD_CLOSE_CHILD: break;
879                 case ECHLD_SET_PARAM: break; // set_param(p,v)
880                 case ECHLD_GET_PARAM: break; // get_param(p)
881                 case ECHLD_PING: break;
882                 case ECHLD_OPEN_FILE: break; // open_file(f,mode)
883                 case ECHLD_OPEN_INTERFACE: break; // open_interface(if,param)
884                 case ECHLD_START_CAPTURE: break;
885                 case ECHLD_GET_SUM: break; // get_sum(rng)
886                 case ECHLD_GET_TREE: break; // get_tree(rng)
887                 case ECHLD_GET_BUFFER: break; // get_buffer(rng)
888                 case ECHLD_STOP_CAPTURE: break;
889                 case ECHLD_ADD_NOTE: break; // add_note(framenum,note)
890                 case ECHLD_APPLY_FILTER: break; // apply_filter(df)
891                 case ECHLD_SAVE_FILE: break; // save_file(f,mode)
892
893
894                 case ECHLD_ERROR: break; // error(err,reason)
895                 case ECHLD_TIMED_OUT: break;
896                 case ECHLD_HELLO: break;
897                 case ECHLD_CHILD_DEAD: break; // child_dead(msg)
898                 case ECHLD_CLOSING: break;
899                 case ECHLD_PARAM: break;
900                 case ECHLD_PONG: break;
901                 case ECHLD_FILE_OPENED: break;
902                 case ECHLD_INTERFACE_OPENED: break;
903                 case ECHLD_CAPTURE_STARTED: break;
904                 case ECHLD_NOTIFY: break; // notify(pre-encoded)
905                 case ECHLD_PACKET_SUM: break; // packet_sum(pre-encoded)
906                 case ECHLD_TREE: break; //tree(framenum, tree(pre-encoded) )
907                 case ECHLD_BUFFER: break; // buffer (name,range,totlen,data)
908                 case ECHLD_EOF: break;
909                 case ECHLD_CAPTURE_STOPPED: break;
910                 case ECHLD_NOTE_ADDED: break;
911                 case ECHLD_PACKET_LIST: break; // packet_list(name,filter,range);
912                 case ECHLD_FILE_SAVED: break;
913
914                 case EC_ACTUAL_ERROR: break;
915         }
916 }
917
918 static void* unused = int_deca;
919
920 extern void unused_things(void) {
921         unused = NULL;
922 }