summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2013-06-22 20:26:13 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2013-06-22 20:26:13 +0000
commitf25a68221c5c4c15bfffd7e10b36791abf56f6ab (patch)
treec9666ab9f7d18860b41fe8ef75c07cb50eb0e7d3
parent87eb22f4648fd5283d2c91c2046c0aa90b7b469b (diff)
downloadwireshark-f25a68221c5c4c15bfffd7e10b36791abf56f6ab.tar.gz
Not yet running but almost there with the dummy
svn path=/trunk/; revision=50114
-rw-r--r--echld/Makefile.am86
-rw-r--r--echld/Makefile.common42
-rw-r--r--echld/echld-int.h37
-rw-r--r--echld/echld-test.c53
-rw-r--r--echld/echld-util.c74
-rw-r--r--echld/echld-util.h44
-rw-r--r--echld/echld.h35
-rw-r--r--echld/echld_child.c79
-rw-r--r--echld/echld_common.c193
-rw-r--r--echld/echld_dispatcher.c254
-rw-r--r--echld/echld_parent.c119
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);
-}