diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2013-06-22 20:26:13 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2013-06-22 20:26:13 +0000 |
commit | f25a68221c5c4c15bfffd7e10b36791abf56f6ab (patch) | |
tree | c9666ab9f7d18860b41fe8ef75c07cb50eb0e7d3 /echld | |
parent | 87eb22f4648fd5283d2c91c2046c0aa90b7b469b (diff) | |
download | wireshark-f25a68221c5c4c15bfffd7e10b36791abf56f6ab.tar.gz wireshark-f25a68221c5c4c15bfffd7e10b36791abf56f6ab.tar.bz2 wireshark-f25a68221c5c4c15bfffd7e10b36791abf56f6ab.zip |
Not yet running but almost there with the dummy
svn path=/trunk/; revision=50114
Diffstat (limited to 'echld')
-rw-r--r-- | echld/Makefile.am | 86 | ||||
-rw-r--r-- | echld/Makefile.common | 42 | ||||
-rw-r--r-- | echld/echld-int.h | 37 | ||||
-rw-r--r-- | echld/echld-test.c | 53 | ||||
-rw-r--r-- | echld/echld-util.c | 74 | ||||
-rw-r--r-- | echld/echld-util.h | 44 | ||||
-rw-r--r-- | echld/echld.h | 35 | ||||
-rw-r--r-- | echld/echld_child.c | 79 | ||||
-rw-r--r-- | echld/echld_common.c | 193 | ||||
-rw-r--r-- | echld/echld_dispatcher.c | 254 | ||||
-rw-r--r-- | echld/echld_parent.c | 119 |
11 files changed, 636 insertions, 380 deletions
diff --git a/echld/Makefile.am b/echld/Makefile.am new file mode 100644 index 0000000000..e40ee5718d --- /dev/null +++ b/echld/Makefile.am @@ -0,0 +1,86 @@ +# Makefile.am +# +# $Id: Makefile.am 48716 2013-04-03 07:38:44Z guy $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +ACLOCAL_AMFLAGS = `../aclocal-flags` + +# Optional objects that I know how to build. These will be +# linked into libechld. +echld_optional_objects = + +include ../Makefile.am.inc + +include Makefile.common + +AM_CFLAGS =-DWS_BUILD_DLL + +if HAVE_WARNINGS_AS_ERRORS +AM_CFLAGS += -Werror +endif + +lib_LTLIBRARIES = libechld.la +# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +libechld_la_LDFLAGS = -version-info 0:0:0 @LDFLAGS_SHAREDLIB@ + +AM_CPPFLAGS = -I$(srcdir)/.. + +libechld_la_SOURCES = \ + $(LIBECHLD_SRC) \ + $(LIBECHLD_INCLUDES) + +EXTRA_libechld_la_SOURCES= + +libechld_la_DEPENDENCIES= + +libechld_la_LIBADD = \ + @GLIB_LIBS@ + +EXTRA_DIST = \ + CMakeLists.txt \ + Makefile.common \ + Makefile.nmake + +CLEANFILES = \ + libechld.a \ + libechld.la \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in + +# ABI compliance checker can be obtained from +# http://ispras.linux-foundation.org/index.php/ABI_compliance_checker +# Checked using version 1.21.12 +#dumpabi-libechld: all abi-descriptor.xml +# rm -rf abi-check-headers abi_dumps .libs/*.abi.tar.gz +# mkdir abi-check-headers +# cp ../config.h ../ws_symbol_export.h *.h abi-check-headers/ +# abi-compliance-checker -l libechld -v1 `readlink .libs/libechld.so | sed 's/.*\.so\.//'` \ +# -relpath $(abs_srcdir) -dump-abi abi-descriptor.xml || \ +# cat logs/libechld/[0-9]*/log.txt +# cp -f abi_dumps/libechld/libechld_* .libs/ +# cd .libs && ln -sf libechld_*.abi.tar.gz libechld.abi.tar.gz +# +#checkapi: +# $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput \ +# $(PERL) ../tools/checkAPIs.pl -g termoutput -build \ +# $(LIBWSUTIL_SRC) +# file_util.c unicode-utils.c diff --git a/echld/Makefile.common b/echld/Makefile.common new file mode 100644 index 0000000000..f8004280e3 --- /dev/null +++ b/echld/Makefile.common @@ -0,0 +1,42 @@ +# Makefile.common +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 47104 2013-01-15 21:54:41Z guy $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# C source files that are part of the libwsutil source; this includes only +# .c files, not YACC or Lex or... files (as Makefile.nmake maps this list +# into a list of object files by replacing ".c" with ".obj") or files +# generated from YACC or Lex files (as Automake doesn't want them in +# _SOURCES variables). +LIBECHLD_SRC = \ + echld-util.c \ + echld_dispatcher.c \ + echld_child.c \ + echld_parent.c \ + echld_common.c + +# Header files that are not generated from other files +LIBECHLD_INCLUDES = \ + echld-int.h \ + echld-util.h \ + echld.h diff --git a/echld/echld-int.h b/echld/echld-int.h index 245b15d435..6bd2122fb5 100644 --- a/echld/echld-int.h +++ b/echld/echld-int.h @@ -26,17 +26,37 @@ #ifndef __ECHLD_HDR_INT_ #define __ECHLD_HDR_INT_ +#include "../config.h" + +#ifdef HAVE_FCNTL_H #include <fcntl.h> -#include <sys/types.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#include <sys/time.h> #include <sys/uio.h> + +#ifdef HAVE_UNISTD_H #include <unistd.h> -#include <glib.h> -#include <glib/gprintf.h> +#endif + #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <errno.h> +#include <signal.h> + #include <arpa/inet.h> + + +#include <glib.h> +#include <glib/gprintf.h> + + + #include "capture_ifinfo.h" @@ -47,7 +67,6 @@ typedef struct _column_info column_info; typedef struct _proto_node proto_tree; typedef struct tvbuff tvb_t; - struct _hdr { guint32 type_len; guint16 chld_id; @@ -85,7 +104,7 @@ typedef enum _cst { /* these manage the de-framing machine in the receiver side */ typedef struct _echld_reader { guint8* rp; /* the read pointer*/ - guint len; /* the used size = (.wp - .rp) */ + size_t len; /* the used size = (.wp - .rp) */ guint8* wp; /* the write pointer */ int fd; /* the filedesc is serving */ @@ -107,13 +126,13 @@ void echld_init_reader(echld_reader_t* r, int fd, size_t initial); void echld_reset_reader(echld_reader_t* r, int fd, size_t initial); typedef struct _param { - char* name; + const char* name; char* (*get)(char** err ); echld_bool_t (*set)(char* val , char** err); } param_t; /* the call_back used by read_frame() */ -typedef int (*read_cb_t)(guint8*, size_t, echld_chld_id_t, echld_msg_type_t, echld_reqh_id_t, void*); +typedef long (*read_cb_t)(guint8*, size_t, echld_chld_id_t, echld_msg_type_t, echld_reqh_id_t, void*); typedef struct _child_in { @@ -160,8 +179,8 @@ void echld_get_all_codecs(child_encoder_t**, child_decoder_t**, echld_parent_enc void echld_init_reader(echld_reader_t* r, int fd, size_t initial); void free_reader(echld_reader_t* r); -int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data); -int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data); +long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data); +long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data); void echld_child_initialize(int pipe_from_parent, int pipe_to_parent, int reqh_id); diff --git a/echld/echld-test.c b/echld/echld-test.c new file mode 100644 index 0000000000..b65d83b5f9 --- /dev/null +++ b/echld/echld-test.c @@ -0,0 +1,53 @@ +/* echld-test.c + * basic test framework for echld + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "echld.h" +#include <signal.h> +#include <stdio.h> + + +void reaper(int sig) { + +}; + + +int main(int argc, char** argv) { + int pid; + + echld_initialize(ECHLD_ENCODING_JSON); + + + switch((pid = fork())) { + case -1: + return 222; + case 0: + exit(echld_loop()); + case 1: + echld_ping(0,) + signal(reaper) + waitpid(); + } +}; diff --git a/echld/echld-util.c b/echld/echld-util.c new file mode 100644 index 0000000000..bc29ac3b6b --- /dev/null +++ b/echld/echld-util.c @@ -0,0 +1,74 @@ +/* echld-util.c + * utility for echld + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../config.h" + +#include "echld-int.h" +#include "echld-util.h" + +struct _ping { + struct timeval tv; + echld_ping_cb_t cb; + void* cb_data; +}; + +static long timevaldiff(struct timeval *starttime, struct timeval *finishtime) { + long msec; + msec=(finishtime->tv_sec-starttime->tv_sec)*1000; + msec+=(finishtime->tv_usec-starttime->tv_usec)/1000; + return msec; +} + +static gboolean pong(echld_msg_type_t type, GByteArray* ba _U_, void* data) { + struct _ping* p = (struct _ping*)data; + struct timeval t; + long ret = -1; + gettimeofday(&t,NULL); + + switch (type) { + case ECHLD_PONG: + ret = timevaldiff(&(p->tv),&t); + default: + ret = -1; + } + + if (p->cb) p->cb(ret, p->cb_data); + + return TRUE; +} + + +echld_state_t echld_ping(int chld_id, echld_ping_cb_t pcb, void* cb_data) { + struct _ping* p = g_new0(struct _ping,1); + + p->cb = pcb; + p->cb_data = cb_data; + gettimeofday(&(p->tv),NULL); + + return echld_reqh(chld_id, 0, ECHLD_PING, NULL, pong, p); +} + + diff --git a/echld/echld-util.h b/echld/echld-util.h new file mode 100644 index 0000000000..3afebe60f2 --- /dev/null +++ b/echld/echld-util.h @@ -0,0 +1,44 @@ +/* echld-util.h + * utility for echld + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +typedef void (*echld_ping_cb_t)(long usec, void* data); +echld_state_t echld_ping(int child_id, echld_ping_cb_t pcb, void* cb_data); + +typedef void (*echld_list_interface_cb_t)(char* intf_name, char* params, void* cb_data); +echld_state_t echld_list_interfaces(int child_id, echld_list_interface_cb_t, void* cb_data); + +typedef void (*echild_get_packet_summary_cb_t)(char* summary, void* data); +echld_state_t echld_open_file(int child_id, const char* filename,echild_get_packet_summary_cb_t,void*); + + +echld_state_t echld_open_interface(int child_id, const char* intf_name, const char* params); +echld_state_t echld_start_capture(int child_id, echild_get_packet_summary_cb_t); +echld_state_t echld_stop_capture(int child_id); + +typedef void (*echild_get_packets_cb)(char* tree_text,void* data); +typedef void (*echild_get_buffer_cb)(char* buffer_text, void* data); +echld_state_t echld_get_packets_range(int child_id, const char* range, echild_get_packets_cb, echild_get_buffer_cb, void* data); + diff --git a/echld/echld.h b/echld/echld.h index 60b97d6f2e..b35f2b58ac 100644 --- a/echld/echld.h +++ b/echld/echld.h @@ -72,7 +72,7 @@ typedef int echld_bool_t; typedef struct timeval tv_t; /* will initialize epan registering protocols and taps */ -echld_state_t echld_initialize(echld_encoding_t); +void echld_initialize(echld_encoding_t); /* cleans up (?) echld and kills the server process(es) */ echld_state_t echld_terminate(void); @@ -105,7 +105,7 @@ typedef echld_bool_t (*echld_iter_cb_t)(echld_chld_id_t, void* child_data, void* void echld_foreach_child(echld_iter_cb_t cb, void* cb_data); /* enc_msg_t is an obscure object for an encoded message */ -typedef struct GByteArray enc_msg_t; +typedef struct _GByteArray enc_msg_t; /* @@ -145,7 +145,7 @@ typedef struct _parent_out { enc_msg_t* (*save_file)(const char* filename, const char* params); } echld_parent_encoder_t; -echld_parent_encoder_t* echld_get_encoder(); +echld_parent_encoder_t* echld_get_encoder(void); /* * decoder @@ -225,29 +225,6 @@ echld_state_t echld_msgh_set_type(echld_chld_id_t, int msgh_id, echld_msg_type_t echld_state_t echld_msgh_set_all(echld_chld_id_t, int msgh_id, echld_msg_type_t, echld_msg_cb_t, void*); -/* - * "Simple" API - * these calls require you looping on echld_select() or calling echld_wait() until you get your answer. - * see bellow - */ - -typedef void (*echld_ping_cb_t)(int usec, void* data); -echld_state_t echld_ping(int child_id, echld_ping_cb_t cb, void* cb_data); - -typedef void (*echld_list_interface_cb_t)(char* intf_name, char* params, void* cb_data); -echld_state_t echld_list_interfaces(int child_id, echld_list_interface_cb_t, void* cb_data); - -typedef void (*echild_get_packet_summary_cb_t)(char* summary, void* data); -echld_state_t echld_open_file(int child_id, const char* filename,echild_get_packet_summary_cb_t,void*); - - -echld_state_t echld_open_interface(int child_id, const char* intf_name, const char* params); -echld_state_t echld_start_capture(int child_id, echild_get_packet_summary_cb_t); -echld_state_t echld_stop_capture(int child_id); - -typedef void (*echild_get_packets_cb)(char* tree_text,void* data); -typedef void (*echild_get_buffer_cb)(char* buffer_text, void* data); -echld_state_t echld_get_packets_range(int child_id, const char* range, echild_get_packets_cb, echild_get_buffer_cb, void* data); /* @@ -319,15 +296,13 @@ enum _echld_msg_type_t { /* cwd RW: the current working directory */ /* list_files WO: a file listing of the current dir */ /* interfaces RO: the interface listing */ - /* dfilter RW: initial display filter* + /* dfilter RW: initial display filter*/ + /* dfilter_chk WO: check a display filter */ /* ... */ ECHLD_PING = '}', /* out: ping the child */ ECHLD_PONG = '{', /* out: ping's response, error or TO otherwise */ - ECHLD_CHK_FILTER = 'K', /* out: verify if a (display) filter works */ - ECHLD_FILTER_CKD = 'k', /* in: yes this filter works, error or TO? otherwise */ - ECHLD_OPEN_FILE = 'O', /* out: open a file */ ECHLD_FILE_OPENED = 'o', /* in: the file has being open, error otherwise */ diff --git a/echld/echld_child.c b/echld/echld_child.c index e5f165ec21..121284af8b 100644 --- a/echld/echld_child.c +++ b/echld/echld_child.c @@ -62,7 +62,7 @@ static echld_child_t child; #ifdef DEBUG_CHILD static int dbg_level = 0; -void child_debug(int level, char* fmt, ...) { +void child_debug(int level, const char* fmt, ...) { va_list ap; char* str; @@ -105,7 +105,6 @@ void echld_child_initialize(int pipe_from_parent, int pipe_to_parent, int reqh_i void child_err(int e, unsigned reqh_id, const char* fmt, ...) { size_t len= 1024; - guint8* b[len]; gchar err_str[len]; va_list ap; static GByteArray* ba; @@ -116,7 +115,7 @@ void child_err(int e, unsigned reqh_id, const char* fmt, ...) { CHILD_DBG((0,"error='%s'",err_str)); - ba = (void*)child.enc->error(e, err_str); + ba = child.enc->error(e, err_str); echld_write_frame(child.fds.pipe_to_parent, ba, child.chld_id, ECHLD_ERROR, reqh_id, NULL); g_byte_array_free(ba,TRUE); } @@ -199,31 +198,23 @@ static char* intflist2json(GList* if_list) { return s; } -static void child_start_interface_listing() {} +static void child_start_interface_listing(void) { -static gboolean child_open_file(int chld_id, int reqh_id, char* filename, guint8* buff, int buff_len) { - char* reason = "Unimplemented"; // this ain't a good reason to fail! +} + +static gboolean child_open_file(int chld_id _U_, int reqh_id _U_, const char* filename, guint8* buff, int buff_len) { + const char* reason = "Unimplemented"; // this ain't a good reason to fail! g_snprintf(buff,buff_len,"Cannot open file=%s reason=%s",filename,reason); return FALSE; } -static gboolean child_open_interface(int chld_id, int reqh_id, const char* intf_name, const char* params, guint8* err_buf, int errbuff_len) { - char* reason = "Unimplemented"; // this ain't a good reason to fail! +static gboolean child_open_interface(int chld_id _U_, int reqh_id _U_, const char* intf_name, const char* params _U_, guint8* err_buf, int errbuff_len) { + const char* reason = "Unimplemented"; // this ain't a good reason to fail! g_snprintf(err_buf,errbuff_len,"Cannot open interface=%s reason=%s",intf_name,reason); return FALSE; } -// static void child_list_files() { -// char* file_info = "{glob='*.cap', file_list={'dummy.cap'={type='pcap-ng', size=20300, npackets=502}}}"; -// // ls -// // foreach file in cur dir -// GByteArray* ba = (void*)child.enc->file_info(file_info); -// CHILD_RESP(ba,ECHLD_FILE_INFO); -// g_byte_array_free(ba,TRUE); -// } - - static char* param_get_cwd(char** err ) { char* pwd = getcwd(NULL, 128); @@ -251,9 +242,10 @@ static char* param_get_cookie(char** err ) { return g_strdup(cookie); *err = g_strdup("cookie not set"); + return NULL; } -static echld_bool_t param_set_cookie(char* val , char** err ) { +static echld_bool_t param_set_cookie(char* val , char** err _U_) { if (cookie) g_free(cookie); @@ -262,13 +254,13 @@ static echld_bool_t param_set_cookie(char* val , char** err ) { } #ifdef DEBUG_CHILD -static char* param_get_dbg_level(char** err ) { +static char* param_get_dbg_level(char** err _U_) { return g_strdup_printf("%d",dbg_level); } static echld_bool_t param_set_dbg_level(char* val , char** err ) { char* p; - int lvl = strtol(val, &p, 10); + int lvl = (int)strtol(val, &p, 10); if (p<=val) { *err = g_strdup("not an integer"); @@ -302,15 +294,8 @@ static param_t* get_paramset(char* name) { } -static gboolean child_set_filter(char* dflt, GString* err) { return FALSE; } -static gboolean child_start_capture(GString* msg, GString* err) { return FALSE; } -static gboolean child_stop_capture(GString* msg, GString* err) { return FALSE; } -static gboolean child_get_packets(GString* msg, GString* err) { return FALSE; } -static gboolean child_apply_filter(char* dflt, GString* err) { return FALSE; } -static gboolean child_add_note(int packet_num, char* note, GString* err) { return FALSE; } - -static int child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) { +static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data _U_) { GByteArray* ba = NULL; child.chld_id = chld_id; @@ -368,15 +353,14 @@ static int child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_m break; } - ba = (void*)child.enc->param(param,value); + ba = child.enc->param(param,value); CHILD_RESP(ba,ECHLD_PARAM); g_byte_array_free(ba,TRUE); CHILD_DBG((1,"Set Param: param='%s' value='%s'",param,value)); break; } else { - child_err(ECHLD_CANNOT_SET_PARAM,reqh_id,"reason='decoder error'"); - break; + goto misencoded; } } case ECHLD_GET_PARAM: { @@ -403,14 +387,13 @@ static int child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_m break; } - ba = (void*)child.enc->param(param,val); + ba = child.enc->param(param,val); CHILD_RESP(ba,ECHLD_PARAM); g_byte_array_free(ba,TRUE); CHILD_DBG((2,"Get Param: param='%s' value='%s'",param,val)); break; } else { - child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"reason='decoder error'"); - break; + goto misencoded; } } case ECHLD_CLOSE_CHILD: @@ -423,14 +406,23 @@ static int child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_m break; case ECHLD_OPEN_INTERFACE: case ECHLD_OPEN_FILE: + if (child.state != IDLE) goto wrong_state; + goto not_implemented; case ECHLD_START_CAPTURE: + if (child.state != READY) goto wrong_state; + goto not_implemented; case ECHLD_STOP_CAPTURE: + if (child.state != IDLE) goto wrong_state; + goto not_implemented; case ECHLD_GET_SUM: case ECHLD_GET_TREE: case ECHLD_GET_BUFFER: + if (child.state != READING && child.state != CAPTURING ) goto wrong_state; + goto not_implemented; case ECHLD_ADD_NOTE: case ECHLD_APPLY_FILTER: case ECHLD_SAVE_FILE: + if (child.state != DONE ) goto wrong_state; goto not_implemented; default: child_err(ECHLD_ERR_WRONG_MSG,reqh_id,"chld_id=%d msg_type='%c'",chld_id,type); @@ -454,19 +446,19 @@ static int child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_m } -static void child_dumpcap_read() { +static void child_dumpcap_read(void) { // this folk manages the reading of dumpcap's pipe // it has to read interface descriptions when doing so // and managing capture during capture CHILD_DBG((2,"child_dumpcap_read")); } -static void child_read_file() { +static void child_read_file(void) { // this folk manages the reading of the file after open file has opened it - CHILD_DBG((2,"child_read_file")); + CHILD_DBG((2,"child_read_file")); } -int echld_child_loop() { +int echld_child_loop(void) { int parent_fd = child.fds.pipe_to_parent; #ifdef DEBUG_CHILD @@ -480,8 +472,7 @@ int echld_child_loop() { fd_set wfds; fd_set efds; struct timeval timeout; - struct dispatcher_child* c; - int nfds; + int nfds = 0; FD_ZERO(&rfds); @@ -492,10 +483,12 @@ int echld_child_loop() { if (child.fds.pipe_from_dumpcap > 0) { FD_SET(child.fds.pipe_from_dumpcap,&rfds); + nfds++; } if (child.fds.file_being_read > 0) { FD_SET(child.fds.file_being_read,&rfds); + nfds++; } CHILD_DBG((4,"child_loop: before select() step=%d",step++)); @@ -517,11 +510,11 @@ int echld_child_loop() { if (FD_ISSET(parent_fd, &rfds)) { - int st = echld_read_frame(&(child.parent), child_receive, &child); + long st = echld_read_frame(&(child.parent), child_receive, &child); if (st < 0) { CHILD_DBG((0,"Read Frame Failed step=%d",step++)); - return st; + return (int)st; } } diff --git a/echld/echld_common.c b/echld/echld_common.c index 33101e263b..74846baf9c 100644 --- a/echld/echld_common.c +++ b/echld/echld_common.c @@ -37,7 +37,7 @@ typedef void (*reader_realloc_t)(echld_reader_t*, size_t); static void child_realloc_buff(echld_reader_t* r, size_t needed) { size_t a = r->actual_len; size_t s = r->len; - int rp_off = r->rp - r->data; + long rp_off = r->rp - r->data; if ( a < (s + needed) ) { guint8* data = r->data; @@ -46,7 +46,7 @@ static void child_realloc_buff(echld_reader_t* r, size_t needed) { a *= 2; } while( a < (s + needed) ); - data = g_realloc(data,a); + data = (guint8*)g_realloc(data,a); r->actual_len = a; r->len = s; @@ -74,7 +74,7 @@ void echld_init_reader(echld_reader_t* r, int fd, size_t initial) { if (r->data == NULL) { r->actual_len = initial; - r->data = g_malloc0(initial); + r->data = (guint8*)g_malloc0(initial); r->wp = r->data; r->rp = NULL; r->len = 0; @@ -87,7 +87,7 @@ void echld_reset_reader(echld_reader_t* r, int fd, size_t initial) { if (r->data == NULL) { r->actual_len = initial; - r->data = g_malloc0(initial); + r->data =(guint8*) g_malloc0(initial); r->wp = r->data; r->rp = NULL; r->len = 0; @@ -102,9 +102,9 @@ void free_reader(echld_reader_t* r) { free(r->data); } -static int reader_readv(echld_reader_t* r, size_t len) { +static long reader_readv(echld_reader_t* r, size_t len) { struct iovec iov; - int nread; + long nread; if ( (r->actual_len - r->len) < len ) reader_realloc_buff(r, len); @@ -112,7 +112,9 @@ static int reader_readv(echld_reader_t* r, size_t len) { iov.iov_base = r->wp; iov.iov_len = len; - nread = readv(0, &iov, len); + nread = readv(0, + &iov, + (guint)len); if (nread >= 0) { r->wp += nread; @@ -123,15 +125,15 @@ static int reader_readv(echld_reader_t* r, size_t len) { }; -int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { +long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { // it will use shared memory instead of inband communication do { hdr_t* h = (hdr_t*)r->rp; - int nread; + long nread; size_t fr_len; size_t missing; - int off; + long off; if ( r->len < ECHLD_HDR_LEN) { /* read the header */ @@ -147,7 +149,7 @@ int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { cb( &(r->rp[sizeof(hdr_t)]), HDR_LEN(h), h->h.chld_id, HDR_TYPE(h), h->h.reqh_id, cb_data); - if ( r->len >= off ) { + if ( ((long)r->len) >= off ) { /* shift the consumed frame */ r->len -= off; memcpy(r->rp ,r->rp + off ,r->len); @@ -165,9 +167,7 @@ int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { if (nread < 0) { goto kaput; /*XXX*/ - } else /* if (nread == 0) { - break; - } else */ if (nread < missing) { + } else if (nread < (long)missing) { goto again; } else { goto incomplete_frame; @@ -182,7 +182,7 @@ int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { if (nread < 0) { goto kaput; /*XXX*/ - } else if (nread <= missing) { + } else if (nread <= (long)missing) { goto again; } @@ -196,12 +196,12 @@ int echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data) { -int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data) { +long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data) { static guint8* write_buf = NULL; - static size_t wb_len = 4096; + static long wb_len = 4096; hdr_t* h; struct iovec iov; - int fr_len = ba->len+ECHLD_HDR_LEN; + long fr_len = ba->len+ECHLD_HDR_LEN; data = data; // @@ -209,7 +209,7 @@ int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t if (! write_buf) { // lock if needed - write_buf = g_malloc0(wb_len); + write_buf = (guint8*)g_malloc0(wb_len); // unlock if needed } @@ -219,11 +219,11 @@ int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t } while (fr_len > wb_len); // lock if needed - write_buf = g_realloc(write_buf,wb_len); + write_buf = (guint8*)g_realloc(write_buf,wb_len); // unlock if needed } - h = (void*)write_buf; + h = (hdr_t*)write_buf; h->h.type_len = (type<<24) | (((guint32)ba->len) & 0x00ffffff) ; h->h.chld_id = chld_id; h->h.reqh_id = reqh_id; @@ -233,7 +233,7 @@ int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t iov.iov_base = write_buf; iov.iov_len = fr_len; - return (int) writev(fd, &iov, fr_len); + return (long) writev(fd, &iov, (unsigned)fr_len); } @@ -248,7 +248,7 @@ int echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t static enc_msg_t* str_enc(const char* s) { GByteArray* ba = g_byte_array_new(); - g_byte_array_append(ba,s,strlen(s)+1); + g_byte_array_append(ba,s,(guint)(strlen(s)+1)); return (enc_msg_t*)ba; } @@ -260,16 +260,14 @@ static gboolean str_dec(guint8* b, size_t bs, char** text) { return TRUE; } -static gboolean str_deca(enc_msg_t* e, char** text) { - GByteArray* ba = (void*)e; +static gboolean str_deca(enc_msg_t* ba, char** text) { return str_dec(ba->data,ba->len,text); - } static enc_msg_t* int_str_enc(int i, const char* s) { GByteArray* ba = g_byte_array_new(); - g_array_append(ba,&i,sizeof(int)); - g_array_append(ba,s,strlen(s)+1); + g_byte_array_append(ba,(guint8*)&i,sizeof(int)); + g_byte_array_append(ba,s,(guint)(strlen(s)+1)); return (enc_msg_t*)ba; } @@ -286,14 +284,13 @@ static gboolean int_str_dec(guint8* b, size_t bs, int* ip, char** text) { return TRUE; } -static gboolean int_str_deca(enc_msg_t* e, int* ip, char** text) { - GByteArray* ba = (void*)e; +static gboolean int_str_deca(enc_msg_t* ba, int* ip, char** text) { return int_str_dec(ba->data,ba->len,ip,text); } static enc_msg_t* int_enc(int i) { GByteArray* ba = g_byte_array_new(); - g_array_append(ba,&i,sizeof(int)); + g_byte_array_append(ba,(guint8*)&i,sizeof(int)); return (enc_msg_t*)ba; } @@ -303,15 +300,14 @@ static gboolean int_dec(guint8* b, size_t bs, int* ip) { return TRUE; } -static gboolean int_deca(enc_msg_t* e, int* ip) { - GByteArray* ba = (void*)e; +static gboolean int_deca(enc_msg_t* ba, int* ip) { return int_dec(ba->data,ba->len,ip); } static enc_msg_t* x2str_enc(const char* s1, const char* s2) { GByteArray* ba = g_byte_array_new(); - g_array_append(ba,s1,strlen(s1)+1); - g_array_append(ba,s2,strlen(s2)+1); + g_byte_array_append(ba,s1,(guint)(strlen(s1)+1)); + g_byte_array_append(ba,s2,(guint)(strlen(s2)+1)); return (enc_msg_t*)ba; } @@ -326,8 +322,7 @@ static gboolean x2str_dec(guint8* b, size_t blen, char** str1, char** str2) { return TRUE; } -static gboolean x2str_deca(enc_msg_t* e, char** str1, char** str2) { - GByteArray* ba = (void*)e; +static gboolean x2str_deca(enc_msg_t* ba, char** str1, char** str2) { return x2str_dec(ba->data,ba->len,str1,str2); } @@ -350,16 +345,15 @@ static gboolean int_3str_dec (guint8* b, size_t len, int* i, char** s1, char** s static enc_msg_t* int_3str_enc(int i, const char* s1, const char* s2, const char* s3) { GByteArray* ba = g_byte_array_new(); - g_array_append(ba,&i,sizeof(int)); - g_array_append(ba,s1,strlen(s1)+1); - g_array_append(ba,s2,strlen(s2)+1); - g_array_append(ba,s3,strlen(s3)+1); + g_byte_array_append(ba,(guint8*)&i,sizeof(int)); + g_byte_array_append(ba,s1,(guint)(strlen(s1)+1)); + g_byte_array_append(ba,s2,(guint)(strlen(s2)+1)); + g_byte_array_append(ba,s3,(guint)(strlen(s3)+1)); return (enc_msg_t*)ba; } static gboolean int_3str_deca (enc_msg_t* e, int* i, char** s1, char** s2, char** s3) { - GByteArray* ba = (void*)e; - return int_3str_dec(ba->data,ba->len,i,s1,s2,s3); + return int_3str_dec(e->data,e->len,i,s1,s2,s3); } static gboolean x3str_dec (guint8* b, size_t len, char** s1, char** s2, char** s3) { @@ -377,16 +371,15 @@ static gboolean x3str_dec (guint8* b, size_t len, char** s1, char** s2, char** s } static gboolean x3str_deca (enc_msg_t* e, char** s1, char** s2, char** s3) { - GByteArray* ba = (void*)e; - return x3str_dec(ba->data,ba->len,s1,s2,s3); + return x3str_dec(e->data,e->len,s1,s2,s3); } static enc_msg_t* x3str_enc(const char* s1, const char* s2, const char* s3) { GByteArray* ba = g_byte_array_new(); - g_array_append(ba,s1,strlen(s1)+1); - g_array_append(ba,s2,strlen(s2)+1); - g_array_append(ba,s3,strlen(s3)+1); + g_byte_array_append(ba,s1,(guint)(strlen(s1)+1)); + g_byte_array_append(ba,s2,(guint)(strlen(s2)+1)); + g_byte_array_append(ba,s3,(guint)(strlen(s3)+1)); return (enc_msg_t*)ba; } @@ -404,7 +397,7 @@ static echld_parent_encoder_t parent_encoder = { x2str_enc }; -echld_parent_encoder_t* echld_get_encoder() { +echld_parent_encoder_t* echld_get_encoder(void) { return &parent_encoder; } @@ -413,9 +406,6 @@ static child_decoder_t child_decoder = { x2str_dec, str_dec, int_dec, - - - str_dec, x2str_dec, str_dec, @@ -459,17 +449,17 @@ void echld_get_all_codecs( child_encoder_t **e, child_decoder_t **d, echld_paren /* output encoders, used in the switch */ -static char* packet_summary_json(GByteArray* ba) { +static char* packet_summary_json(GByteArray* ba _U_) { /* dummy */ return g_strdup("{type='packet_summary', packet_summary={}"); } -static char* tree_json(GByteArray* ba) { +static char* tree_json(GByteArray* ba _U_) { /* dummy */ return g_strdup("{type='tree', tree={}"); } -static char* tvb_json(GByteArray* ba, tvb_t* tvb, const char* name) { +char* tvb_json(GByteArray* ba _U_, tvb_t* tvb _U_, const char* name) { /* dummy */ return g_strdup_printf("{type='buffer', buffer={name='%s', range='0-2', data=[0x12,0xff] }",name); } @@ -499,21 +489,6 @@ static char* closing_json(GByteArray* ba) { return s; } -static char* cwd_json(GByteArray* ba) { - char* s = (char*)(ba->data); - s = g_strdup_printf("{type='cwd', cwd={dir='%s'}}",s); - - return s; -} - -static char* file_info_json(GByteArray* ba) { - char* s1 = (char*)(ba->data); - char* s2 = ((char*)(ba->data)) + strlen(s1); - - s1 = g_strdup_printf("{type='file', file={filename='%s' info='%s'}}",s1,s2); - - return s1; -} static char* note_added_json(GByteArray* ba) { @@ -523,7 +498,7 @@ static char* note_added_json(GByteArray* ba) { return s; } -static char* packet_list_json(GByteArray* ba) { +static char* packet_list_json(GByteArray* ba _U_) { return g_strdup("{}"); } @@ -566,100 +541,52 @@ static char* get_param_json(GByteArray* ba) { return s1; } -static char* list_files_json(GByteArray* ba) { - char* s1 = (char*)(ba->data); - - s1 = g_strdup_printf("{type='list_files', list_files={glob='%s'}}",s1); - - - return s1; -} - - -static char* chk_filter_json(GByteArray* ba) { - char* s1 = (char*)(ba->data); - - s1 = g_strdup_printf("{type='chk_filter', chk_filter={filter='%s'}}",s1); - - return s1; -} - -static char* filter_ckd_json(GByteArray* ba) { - char* s1 = (char*)(ba->data + sizeof(int)); - int i = *((int*)ba->data); - - s1 = g_strdup_printf("{type='filter_ckd', filter_ckd={filter='%s',ok=%s}}",ba->data,i?"true":"false"); - - return s1; -} - -static char* set_filter_json(GByteArray* ba) { - char* s1 = (char*)(ba->data); - - s1 = g_strdup_printf("{type='chk_filter', chk_filter={filter='%s'}}",s1); - - return s1; -} - -static char* filter_set_json(GByteArray* ba) { - char* s1 = (char*)(ba->data); - - s1 = g_strdup_printf("{type='filter_set', filter_set={filter='%s'}}",s1); - - return s1; -} - - -static char* file_opened_json(GByteArray* ba) { - return g_strdup(""); -} - -static char* open_file_json(GByteArray* ba) { +static char* file_opened_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* intf_info_json(GByteArray* ba) { +static char* open_file_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* open_interface_json(GByteArray* ba) { +static char* open_interface_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* interface_opened_json(GByteArray* ba) { +static char* interface_opened_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* notify_json(GByteArray* ba) { +static char* notify_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* get_tree_json(GByteArray* ba) { +static char* get_tree_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* get_sum_json(GByteArray* ba) { +static char* get_sum_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* get_buffer_json(GByteArray* ba) { +static char* get_buffer_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* buffer_json(GByteArray* ba) { +static char* buffer_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* add_note_json(GByteArray* ba) { +static char* add_note_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* apply_filter_json(GByteArray* ba) { +static char* apply_filter_json(GByteArray* ba _U_) { return g_strdup(""); } -static char* save_file_json(GByteArray* ba) { +static char* save_file_json(GByteArray* ba _U_) { return g_strdup(""); } @@ -675,7 +602,7 @@ static char* decode_json(echld_msg_type_t type, enc_msg_t* m) { case ECHLD_HELLO: return g_strdup("{type='helo'}"); case ECHLD_CHILD_DEAD: return child_dead_json(ba); case ECHLD_CLOSE_CHILD: return g_strdup("{type='close_child'}"); - case ECHLD_CLOSING: return g_strdup("{type='closing'}"); + case ECHLD_CLOSING: return closing_json(ba); case ECHLD_SET_PARAM: return set_param_json(ba); case ECHLD_GET_PARAM: return get_param_json(ba); case ECHLD_PARAM: return param_set_json(ba); @@ -702,7 +629,7 @@ static char* decode_json(echld_msg_type_t type, enc_msg_t* m) { case ECHLD_APPLY_FILTER: return apply_filter_json(ba); case ECHLD_PACKET_LIST: return packet_list_json(ba); case ECHLD_SAVE_FILE: return save_file_json(ba); - case ECHLD_FILE_SAVED: return g_strdup("{type='file_saved'}"); + case ECHLD_FILE_SAVED: return file_saved_json(ba); case EC_ACTUAL_ERROR: return g_strdup("{type='actual_error'}"); default: break; } diff --git a/echld/echld_dispatcher.c b/echld/echld_dispatcher.c index 42edbdd3f9..53dbbda9d7 100644 --- a/echld/echld_dispatcher.c +++ b/echld/echld_dispatcher.c @@ -31,7 +31,7 @@ **/ struct dispatcher_child { - unsigned chld_id; + echld_chld_id_t chld_id; child_state_t state; echld_reader_t reader; int write_fd; @@ -67,7 +67,7 @@ struct dispatcher* dispatcher; #ifdef DEBUG_DISPATCHER static int dbg_level = 0; -void dispatcher_debug(int level, char* fmt, ...) { +void dispatcher_debug(int level, const char* fmt, ...) { va_list ap; char* str; @@ -81,13 +81,13 @@ void dispatcher_debug(int level, char* fmt, ...) { g_free(str); } -static char* param_get_dbg_level(char** err ) { +static char* param_get_dbg_level(char** err _U_) { return g_strdup_printf("%d",dbg_level); } static echld_bool_t param_set_dbg_level(char* val , char** err ) { char* p; - int lvl = strtol(val, &p, 10); + int lvl = (int)strtol(val, &p, 10); if (p<=val) { *err = g_strdup("not an integer"); @@ -106,36 +106,129 @@ static echld_bool_t param_set_dbg_level(char* val , char** err ) { #define DISP_DBG(attrs) #endif +static void dispatcher_err(int errnum, const char* fmt, ...) { + size_t len= 1024; + gchar err_str[len]; + va_list ap; + static GByteArray* ba; -/* parameters */ + va_start(ap, fmt); + g_vsnprintf(err_str,len,fmt,ap); + va_end(ap); -int wait_chldn = 0; + DISP_DBG((0,"error=\"%s\"",err_str)); -static char* param_get_wait_chldn(char** err ) { - return g_strdup_printf("%d",wait_chldn); + ba = dispatcher->enc.to_parent->error(errnum, err_str); + DISP_RESP(ba,ECHLD_ERROR); + g_byte_array_free(ba,TRUE); } -static echld_bool_t param_set_wait_chldn(char* val , char** err ) { - char* p; - int lvl = strtol(val, &p, 10); +/* parameters */ - if (p<=val) { - *err = g_strdup("not an integer"); - return FALSE; - } else if (lvl < 0 || lvl > 10) { - *err = g_strdup_printf("invalid level=%d (min=0 max=5)",lvl); - return FALSE; +/* interface listing */ + +static char* intflist2json(GList* if_list) { + /* blatantly stolen from print_machine_readable_interfaces in dumpcap.c */ +#define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */ + + int i; + GList *if_entry; + if_info_t *if_info; + GSList *addr; + if_addr_t *if_addr; + char addr_str[ADDRSTRLEN]; + GString *str = g_string_new("={ "); + char* s; + + i = 1; /* Interface id number */ + for (if_entry = g_list_first(if_list); if_entry != NULL; + if_entry = g_list_next(if_entry)) { + if_info = (if_info_t *)if_entry->data; + g_string_append_printf(str,"%d={ intf='%s',", i++, if_info->name); + + /* + * Print the contents of the if_entry struct in a parseable format. + * Each if_entry element is tab-separated. Addresses are comma- + * separated. + */ + /* XXX - Make sure our description doesn't contain a tab */ + if (if_info->vendor_description != NULL) + g_string_append_printf(str," vnd_desc='%s',", if_info->vendor_description); + + /* XXX - Make sure our friendly name doesn't contain a tab */ + if (if_info->friendly_name != NULL) + g_string_append_printf(str," name='%s', addrs=[ ", if_info->friendly_name); + + for (addr = g_slist_nth(if_info->addrs, 0); addr != NULL; + addr = g_slist_next(addr)) { + + if_addr = (if_addr_t *)addr->data; + switch(if_addr->ifat_type) { + case IF_AT_IPv4: + if (inet_ntop(AF_INET, &if_addr->addr.ip4_addr, addr_str, + ADDRSTRLEN)) { + g_string_append_printf(str,"%s", addr_str); + } else { + g_string_append(str,"<unknown IPv4>"); + } + break; + case IF_AT_IPv6: + if (inet_ntop(AF_INET6, &if_addr->addr.ip6_addr, + addr_str, ADDRSTRLEN)) { + g_string_append_printf(str,"%s", addr_str); + } else { + g_string_append(str,"<unknown IPv6>"); + } + break; + default: + g_string_append_printf(str,"<type unknown %u>", if_addr->ifat_type); + } + } + + g_string_append(str," ]"); /* addrs */ + + + if (if_info->loopback) + g_string_append(str,", loopback=1"); + else + g_string_append(str,", loopback=0"); + + g_string_append(str,"}, "); + } + + g_string_truncate(str,str->len - 2); /* the comma and space */ + g_string_append(str,"}"); + + s=str->str; + g_string_free(str,FALSE); + return s; +} + +static char* param_get_interfaces(char** err) { + int err_no = 0; + GList* if_list; + char* s; + *err = NULL; + if_list = capture_interface_list(&err_no, err); + + if (*err) { + return NULL; } - wait_chldn = lvl; - return TRUE; + s = intflist2json(if_list); + + free_interface_list(if_list); + + return s; } + + static param_t disp_params[] = { #ifdef DEBUG_DISPATCHER {"dbg_level", param_get_dbg_level, param_set_dbg_level}, # endif - {"wait_chldn",param_get_wait_chldn,param_set_wait_chldn}, + {"interfaces",param_get_interfaces,NULL}, {NULL,NULL,NULL} }; static param_t* get_paramset(char* name) { @@ -146,24 +239,6 @@ static param_t* get_paramset(char* name) { return NULL; } -void dispatcher_err(int err, const char* fmt, ...) { - size_t len= 1024; - guint8* b[len]; - char err_str[len]; - GByteArray* em; - va_list ap; - - - va_start(ap, fmt); - g_vsnprintf(err_str,len,fmt,ap); - va_end(ap); - - fprintf(stderr, "%s[%d]: error=%d '%s'\n", "dispatcher", dispatcher->pid, err, err_str); - - em = (void*)dispatcher->enc.to_parent->error(err, err_str); - echld_write_frame(dispatcher->parent_out, em, 0, ECHLD_ERROR, dispatcher->reqh_id, NULL); - g_ptr_array_free((void*)em,TRUE); -} static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, guint16 chld_id) { int i; @@ -171,7 +246,7 @@ static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, guint int max_children = d->max_children; for(i = 0; i < max_children; i++) { - struct dispatcher_child* c = &(c[i]); + struct dispatcher_child* c = &(cc[i]); if (c->chld_id == chld_id) return c; } @@ -187,12 +262,12 @@ static void dispatcher_clear_child(struct dispatcher_child* c) { c->closing = 0; } -static void preinit_epan() { +static void preinit_epan(void) { /* Here we do initialization of parts of epan that will be the same for every child we fork */ } -static void dispatcher_clear() { +static void dispatcher_clear(void) { /* remove unnecessary stuff for the working child */ } @@ -202,47 +277,43 @@ void dispatcher_reaper(int sig) { struct dispatcher_child* cc = dispatcher->children; int max_children = dispatcher->max_children; int pid = waitpid(-1, &status, WNOHANG); - size_t len= 1024; - guint8* b[len]; GByteArray* em; + if (sig != SIGCHLD) { + DISP_DBG((1,"Reaper got wrong signal=%d",sig)); + return; + } + + DISP_DBG((2,"Child dead pid=%d",pid)); for(i = 0; i < max_children; i++) { struct dispatcher_child* c = &(cc[i]); if ( c->pid == pid ) { if (c->closing || dispatcher->closing) { - em = (void*)dispatcher->enc.to_parent->child_dead("OK"); + em = dispatcher->enc.to_parent->child_dead("OK"); } else { - /* here we do collect crash data !!! */ - /* - WIFEXITED(status) - True if the process terminated normally by a call to _exit(2) or exit(3). - - WIFSIGNALED(status) - True if the process terminated due to receipt of a signal. - - WIFSTOPPED(status) - True if the process has not terminated, but has stopped and can be restarted. This macro can be true only if the wait call speci- - fied the WUNTRACED option or if the child process is being traced (see ptrace(2)). - - Depending on the values of those macros, the following macros produce the remaining status information about the child process: - - WEXITSTATUS(status) - If WIFEXITED(status) is true, evaluates to the low-order 8 bits of the argument passed to _exit(2) or exit(3) by the child. - - WTERMSIG(status) - If WIFSIGNALED(status) is true, evaluates to the number of the signal that caused the termination of the process. - - WCOREDUMP(status) - If WIFSIGNALED(status) is true, evaluates as true if the termination of the process was accompanied by the creation of a core file - containing an image of the process when the signal was received. - - WSTOPSIG(status) - If WIFSTOPPED(status) is true, evaluates to the number of the signal that caused the process to stop. + char* s = NULL; + + if (WIFEXITED(status)) { + s = g_strdup_printf( + "Unexpected dead: reason='exited' pid=%d status=%d", + pid, WEXITSTATUS(status)); + } else if ( WIFSIGNALED(status) ) { + s = g_strdup_printf( + "Unexpected dead: reason='signaled' pid=%d termsig=%d coredump=%s", + pid, WTERMSIG(status), WCOREDUMP(status) ? "yes":"no"); + + /*if (WCOREDUMP(status)) { system("analyze_coredump.sh pid=%d") } */ + + } else if (WIFSTOPPED(status)) { + s = g_strdup_printf( + "Unexpected dead: reason='stopped' pid=%d stopsig=%d", + pid, WSTOPSIG(status)); + } -*/ - em = (void*)dispatcher->enc.to_parent->child_dead("Unexpected, probably crashed"); - dispatcher_err(ECHLD_ERR_CRASHED_CHILD, "Unexpected dead: pid=%d chld_id=%d", pid, c->chld_id); + em = dispatcher->enc.to_parent->child_dead(s); + dispatcher_err(ECHLD_ERR_CRASHED_CHILD, s); + if (s) g_free(s); } echld_write_frame(dispatcher->parent_out, em, c->chld_id, ECHLD_CHILD_DEAD, 0, NULL); @@ -257,7 +328,7 @@ void dispatcher_reaper(int sig) { -static void dispatcher_destroy() { +static void dispatcher_destroy(void) { int i; int max_children = dispatcher->max_children; struct dispatcher_child* cc = dispatcher->children; @@ -275,19 +346,21 @@ static void dispatcher_destroy() { } } - exit(6666); + exit(0); } /* stuff coming from child going to parent */ -static int dispatch_to_parent(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) { - struct dispatcher_child* c = data; - dispatcher->reqh_id = reqh_id; +static long dispatch_to_parent(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) { /* TODO: timeouts, clear them */ /* TODO: keep stats */ + GByteArray in_ba; + struct dispatcher_child* c = (struct dispatcher_child*)data; + dispatcher->reqh_id = reqh_id; + in_ba.data = b; - in_ba.len = len; + in_ba.len = (guint)len; if (chld_id != c->chld_id) { goto misbehabing; @@ -373,7 +446,7 @@ void dispatch_new_child(struct dispatcher* dd) { int i; int fdt_len = getdtablesize(); - dispatcher_clear(dd); + dispatcher_clear(); for(i=0;i<fdt_len;i++) { if ( i != pipe_from_parent @@ -419,13 +492,14 @@ void dispatch_new_child(struct dispatcher* dd) { /* process signals sent from parent */ -static int dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) { - struct dispatcher* disp = data; - disp->reqh_id = reqh_id; +static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) { + struct dispatcher* disp = (struct dispatcher*)data; GByteArray in_ba; + disp->reqh_id = reqh_id; + in_ba.data = b; - in_ba.len = len; + in_ba.len = (guint)len; if (chld_id == 0) { /* these are messages to the dispatcher itself */ switch(type) { @@ -462,7 +536,7 @@ static int dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ech return 0; } - ba = (void*)disp->enc.to_parent->param(param,value); + ba = disp->enc.to_parent->param(param,value); DISP_RESP(ba,ECHLD_PARAM); g_byte_array_free(ba,TRUE); DISP_DBG((1,"Set Param: param='%s' value='%s'",param,value)); @@ -498,7 +572,7 @@ static int dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ech return 0; } - ba = (void*)disp->enc.to_parent->param(param,val); + ba = disp->enc.to_parent->param(param,val); DISP_RESP(ba,ECHLD_PARAM); g_byte_array_free(ba,TRUE); DISP_DBG((2,"Get Param: param='%s' value='%s'",param,val)); @@ -562,7 +636,7 @@ static int dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ech } -int dispatcher_loop() { +int dispatcher_loop(void) { int parent_out = dispatcher->parent_out; int parent_in = dispatcher->parent_in.fd; @@ -598,7 +672,7 @@ int dispatcher_loop() { } if (FD_ISSET(parent_in, &rfds)) { - int st = echld_read_frame(&(dispatcher->parent_in), dispatch_to_child, dispatcher); + long st = echld_read_frame(&(dispatcher->parent_in), dispatch_to_child, dispatcher); if (st < 0) { /* XXX */ @@ -614,7 +688,7 @@ int dispatcher_loop() { } if (FD_ISSET(c->reader.fd,&rfds)) { - int st = echld_read_frame(&(c->reader), dispatch_to_parent, c); + long st = echld_read_frame(&(c->reader), dispatch_to_parent, c); if (st < 0) { /* XXX cleanup child and report */ @@ -643,7 +717,7 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds) { echld_init_reader(&(d.parent_in),in_pipe_fds[0],4096); d.parent_out = out_pipe_fds[1]; - d.children = g_malloc0(ECHLD_MAX_CHILDREN * sizeof(struct dispatcher_child)); + d.children = g_new0(struct dispatcher_child,ECHLD_MAX_CHILDREN); d.max_children = ECHLD_MAX_CHILDREN; d.nchildren = 0; d.reqh_id = -1; diff --git a/echld/echld_parent.c b/echld/echld_parent.c index b94590444f..be2cb99d92 100644 --- a/echld/echld_parent.c +++ b/echld/echld_parent.c @@ -76,7 +76,7 @@ struct _echld_parent { static int dbg_level = 0; -static void parent_dgb(int level, const char* fmt, ...) { +static void parent_dbg(int level, const char* fmt, ...) { va_list ap; char str[1024]; @@ -88,13 +88,15 @@ static void parent_dgb(int level, const char* fmt, ...) { fprintf(stderr,"ParentDebug: level=%d msg='%s'\n",level,str); } + #define PARENT_DBG(attrs) parent_dbg attrs + #else #define PARENT_DBG(attrs) #endif void echld_set_parent_dbg_level(int lvl) { - PARENT_DBG((0,"Debug Level Set: %d",dbg_level = lvl)); + PARENT_DBG((0,"Debug Level Set: %d",(dbg_level = lvl))); } static void parent_fatal(int exit_code, const char* fmt, ...) { @@ -114,7 +116,7 @@ static void parent_fatal(int exit_code, const char* fmt, ...) { exit(exit_code); } -static echld_state_t echld_cleanup(void) { +static void echld_cleanup(void) { int i; char b[4]; GByteArray ba; @@ -139,14 +141,14 @@ static echld_state_t echld_cleanup(void) { } -static int parent_child_cleanup(echld_t* c) { +static void parent_child_cleanup(echld_t* c) { PARENT_DBG((2,"cleanup chld_id=%d",c->chld_id)); c->chld_id = -1; c->data = NULL; c->state = FREE; - g_array_truncate(c->handlers); - g_array_truncate(c->reqs); + g_array_set_size(c->handlers,0); + g_array_set_size(c->reqs,0); } @@ -178,7 +180,7 @@ void parent_reaper(int sig) { } /* will initialize epan registering protocols and taps */ -echld_state_t echld_initialize(echld_encoding_t enc) { +void echld_initialize(echld_encoding_t enc) { int from_disp[2]; int to_disp[2]; @@ -203,7 +205,7 @@ echld_state_t echld_initialize(echld_encoding_t enc) { echld_cleanup(); - dispatcher(to_disp,from_disp); + echld_dispatcher_start(to_disp,from_disp); PARENT_FATAL((1115,"This shoudln't happen")); } @@ -215,11 +217,11 @@ echld_state_t echld_initialize(echld_encoding_t enc) { PARENT_DBG((3,"Dispatcher forked")); echld_get_all_codecs(NULL, NULL, &parent.enc, &parent.dec); - parent.children = g_malloc0(ECHLD_MAX_CHILDREN*sizeof(echld_t)); + parent.children = g_new0(echld_t,ECHLD_MAX_CHILDREN); parent.snd = g_byte_array_new(); parent.dispatcher_fd = to_disp[0]; - init_reader(&(parent.reader),from_disp[1]); + echld_init_reader(&(parent.reader),from_disp[1],4096); for (i=0;i<ECHLD_MAX_CHILDREN;i++) { parent.children[i].chld_id = -1; @@ -279,7 +281,7 @@ static echld_state_t reqh_snd(echld_t* c, echld_msg_type_t t, GByteArray* ba, ec req.reqh_id = reqh_ids++; req.cb = resp_cb; req.cb_data = cb_data; - gettimeofday(&(req.tv)); + gettimeofday(&(req.tv),NULL); g_array_append_val(c->reqs,req); @@ -300,7 +302,8 @@ echld_reqh_id_t echld_reqh( enc_msg_t* ba, echld_msg_cb_t resp_cb, void* cb_data) { - return reqh_snd(get_child(child_id),t,(void*)ba,resp_cb,cb_data); + usecs_timeout=usecs_timeout; + return reqh_snd(get_child(child_id),t,ba,resp_cb,cb_data); } /* get callback data for a live request */ @@ -377,31 +380,35 @@ gboolean echld_reqh_detach(int child_id, int reqh_id) { if (idx < 0) return FALSE; g_array_remove_index(c->reqs,idx); + + return TRUE; } static echld_bool_t parent_dead_child(echld_msg_type_t type, enc_msg_t* ba, void* data) { - echld_t* c = data; - char* str; + echld_t* c = (echld_t*)data; + char* s; if (type != ECHLD_CHILD_DEAD) { + PARENT_DBG((1, "Must Be ECHLD_CHILD_DEAD")); return 1; } - if ( parent.dec->child_dead((void*)ba,&str) ) { - g_string_prepend_printf(str,"Dead Child[%d]: %s",c->chld_id,str); - g_free(str); + if ( parent.dec->child_dead(ba,&s) ) { + PARENT_DBG((1,"Dead Child[%d]: %s",c->chld_id,s)); + g_free(s); } parent_child_cleanup(c); return 0; } -static echld_bool_t parent_get_hello(echld_msg_type_t type, enc_msg_t* ba, void* data) { - echld_t* c = data; +static echld_bool_t parent_get_hello(echld_msg_type_t type, enc_msg_t* ba _U_, void* data) { + echld_t* c = (echld_t*)data; switch (type) { case ECHLD_HELLO: + PARENT_DBG((1,"Child[%d]: =>IDLE",c->chld_id)); c->state = IDLE; return TRUE; case ECHLD_ERROR: @@ -432,7 +439,9 @@ int echld_new(void* child_data) { c->state = CREATING; c->handlers = g_array_new(TRUE,TRUE,sizeof(hdlr_t)); - g_byte_array_truncate(parent.snd,0); + g_byte_array_set_size(parent.snd,0); + + PARENT_DBG((1,"Child[%d]: =>CREATING",c->chld_id)); msgh_attach(c,ECHLD_CHILD_DEAD, parent_dead_child , c); reqh_snd(c, ECHLD_NEW_CHILD, parent.snd, parent_get_hello, c); @@ -474,8 +483,7 @@ static int msgh_idx(echld_t* c, int msgh_id) { /* start a message handler */ static int msgh_attach(echld_t* c, echld_msg_type_t t, echld_msg_cb_t resp_cb, void* cb_data) { hdlr_t h; - int hdlr_idx; - static int msgh_id; + static int msgh_id = 1; h.id = msgh_id++; h.type = t; @@ -486,7 +494,7 @@ static int msgh_attach(echld_t* c, echld_msg_type_t t, echld_msg_cb_t resp_cb, v return 0; } -static int echld_msgh_attach(int child_id, echld_msg_type_t t, echld_msg_cb_t resp_cb, void* cb_data) { +int echld_msgh(int child_id, echld_msg_type_t t, echld_msg_cb_t resp_cb, void* cb_data) { echld_t* c = get_child(child_id); if (c) return msgh_attach(c,t,resp_cb,cb_data); @@ -562,9 +570,9 @@ static echld_state_t msgh_get_all(echld_t* c, int msgh_id, echld_msg_type_t* t, h = &(((hdlr_t*)(c->handlers->data))[idx]); - t && (*t = h->type); - cb && (*cb = h->cb); - data && (*data = h->cb_data); + if (t) *t = h->type; + if (cb) *cb = h->cb; + if (data) *data = h->cb_data; return 0; } @@ -656,7 +664,6 @@ void echld_foreach_child(echld_iter_cb_t cb, void* cb_data) { static reqh_t* get_req(echld_t* c, int reqh_id) { int idx = reqh_id_idx(c,reqh_id); - reqh_t* r; if(idx < 0) return NULL; return ((reqh_t*)(c->reqs->data))+idx; @@ -673,10 +680,11 @@ static hdlr_t* get_next_hdlr_for_type(echld_t* c, echld_msg_type_t t, int* cooki return NULL; } -int parent_read_frame(GByteArray* ba, guint16 chld_id, echld_msg_type_t t, guint16 reqh_id, void* data) { +static long parent_read_frame(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t t, echld_reqh_id_t reqh_id, void* data _U_) { echld_t* c = get_child(chld_id); + GByteArray* ba = g_byte_array_new(); - if (ba == NULL) g_byte_array_new(); + g_byte_array_append(ba,b, (guint)len); if (c) { reqh_t* r = get_req(c, reqh_id); @@ -685,18 +693,18 @@ int parent_read_frame(GByteArray* ba, guint16 chld_id, echld_msg_type_t t, guint gboolean go_ahead = TRUE; if (r) { /* got that reqh_id */ - go_ahead = r->cb ? r->cb(t,(void*)ba,r->cb_data) : TRUE; + go_ahead = r->cb ? r->cb(t,ba,r->cb_data) : TRUE; } while(go_ahead && ( h = get_next_hdlr_for_type(c,t,&i))) { - go_ahead = h->cb(t,(void*)ba,r->cb_data); + go_ahead = h->cb(t,ba,r->cb_data); } } else { /* no such child??? */ } - ba && g_byte_array_free(ba,TRUE); - + g_byte_array_free(ba,TRUE); + return 1; } int echld_fdset(fd_set* rfds, fd_set* efds) { @@ -711,12 +719,12 @@ int echld_fd_read(fd_set* rfds, fd_set* efds) { if (FD_ISSET(parent.reader.fd,efds) || FD_ISSET(parent.dispatcher_fd,efds) ) { /* Handle errored dispatcher */ r_nfds--; - return; + return -1; } if (FD_ISSET(parent.reader.fd,rfds)) { r_nfds++; - read_frame(&(parent.reader),parent_read_frame,&(parent)); + echld_read_frame(&(parent.reader),parent_read_frame,&(parent)); } return r_nfds; @@ -748,52 +756,13 @@ echld_state_t echld_wait(struct timeval* timeout) { } -/* Ping the child */ -struct _ping { - struct timeval tv; - echld_t* child; - echld_ping_cb_t cb; - void* cb_data; -}; - -static long timevaldiff(struct timeval *starttime, struct timeval *finishtime) { - long msec; - msec=(finishtime->tv_sec-starttime->tv_sec)*1000; - msec+=(finishtime->tv_usec-starttime->tv_usec)/1000; - return msec; -} - -static gboolean pong(echld_msg_type_t type, GByteArray* ba, void* data) { - struct _ping* p = data; - struct timeval t; - gettimeofday(&t); - - if (p->cb) p->cb(timevaldiff(&(p->tv),&t), p->cb_data); - - return FALSE; -} - -echld_state_t echld_ping(int child_id, echld_ping_cb_t pcb, void* cb_data) { - echld_t* c; - struct _ping* p; - GByteArray* ba; - if (!(( c = get_child(child_id) )) ) { - return -1; - } +/* Ping the child */ - p = g_malloc0(sizeof(struct _ping)); - ba = g_byte_array_new(); - p->child = c; - p->cb = pcb; - p->cb_data = cb_data; - gettimeofday(&(p->tv)); - return echld_req(c->chld_id, ECHLD_PING, ba, pong, p); -} |