static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
char **err_msg);
+static void (*fetch_dumpcap_pid)(int) = NULL;
+
+
void
capture_session_init(capture_session *cap_session, void *cf)
{
_exit(1);
}
+ if (fetch_dumpcap_pid && cap_session->fork_child > 0)
+ fetch_dumpcap_pid(cap_session->fork_child);
+
sync_pipe_read_fd = sync_pipe[PIPE_READ];
#endif
_exit(1);
}
+ if (fetch_dumpcap_pid && *fork_child > 0)
+ fetch_dumpcap_pid(*fork_child);
+
*data_read_fd = data_pipe[PIPE_READ];
*message_read_fd = sync_pipe[PIPE_READ];
#endif
fork_child_status);
ret = -1;
}
- } else {
+ } else if (errno != ECHILD) {
*msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
ret = -1;
+ } else {
+ /* errno == ECHILD ; echld might have already reaped the child */
+ ret = fetch_dumpcap_pid ? 0 : -1;
}
#endif
}
}
+void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
+ fetch_dumpcap_pid = cb;
+}
+
#endif /* HAVE_LIBPCAP */
extern void
capture_input_closed(capture_session *cap_session, gchar *msg);
+/* set a callback to be called after fork with the pid of the forked child */
+extern void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid));
+
#endif /* capture_sync.h */
AM_CFLAGS += -Werror
endif
-AM_CPPFLAGS = -I$(srcdir)/..
+AM_CPPFLAGS = -I$(srcdir)/.. -I$(srcdir)/../wiretap
libechld_la_SOURCES = \
$(LIBECHLD_SRC) \
- $(LIBECHLD_INCLUDES)
+ $(LIBECHLD_INCLUDES) \
+ $(LIBECHLD_MORE_SRC)
+
libechld_la_DEPENDENCIES=
../epan/libwireshark.la \
+ ../wiretap/libwiretap.la \
../wsutil/libwsutil.la
libechld_la_LIBADD = \
../epan/libwireshark.la \
../wsutil/libwsutil.la \
+ ../wiretap/libwiretap.la \
@GLIB_LIBS@
EXTRA_DIST = \
echld-int.h \
echld-util.h \
echld.h
+
+LIBECHLD_MORE_SRC = \
+ ../capture_opts.c \
+ ../capture_stop_conditions.c \
+ ../cfutils.c \
+ ../clopts_common.c \
+ ../sync_pipe_write.c \
+ ../capture-pcap-util.c \
+ ../capture-pcap-util.h \
+ ../capture-pcap-util-int.h \
+ ../conditions.c \
+ ../pcapio.c \
+ ../ringbuffer.c \
+ ../capture_sync.c \
+ ../version_info.c \
+ ../capture_ifinfo.c \
+ ../ws80211_utils.c
+
+OTHER = \
+ ../dumpcap.c
+
+
--- /dev/null
+## Makefile for building wireshark.exe with Microsoft C and nmake
+## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
+#
+# $Id: Makefile.nmake 47938 2013-02-28 14:09:46Z rbalint $
+
+include ..\config.nmake
+include <win32.mak>
+include ..\Makefile.nmake.inc
+
+############### no need to modify below this line #########
+
+include Makefile.common
+
+CFLAGS=$(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \
+ /I. /I.. $(GLIB_CFLAGS) \
+ /I$(PCAP_DIR)\include -DWS_BUILD_DLL
+
+.c.obj::
+ $(CC) $(CFLAGS) -Fd.\ -c $<
+
+# no fork() on windows this needs some thoughts...
static int dbg_level = DEBUG_BASE;
static FILE* dbg_fp;
+static const char* dbg_prefix;
static void common_dbg(int level, const char* fmt, ...) {
va_list ap;
va_end(ap);
if (dbg_fp) {
- fprintf(dbg_fp,"Common: level=%d msg='%s'\n",level,str);
+ fprintf(dbg_fp,"%s: level=%d msg='%s'\n",dbg_prefix,level,str);
fflush(dbg_fp);
}
}
+extern void echld_common_set_dbg(int level, FILE* fp, const char* prefix) {
+ dbg_prefix = prefix;
+ dbg_level = level;
+ dbg_fp = fp;
+}
#define DBG(attrs) ( common_dbg attrs )
#else
#define DBG(attrs)
#endif
-extern void echld_common_set_dbg(int level, FILE* fp) {
- dbg_level = level;
- dbg_fp = fp;
-}
/**
static echld_parent_encoder_t parent_encoder = {
int_str_enc,
+ str_enc,
x2str_enc,
int_enc,
str_enc,
parent_decoder_t* from_child;
} dec;
+ int dumpcap_pid;
gboolean closing;
};
static int debug_lvl = DEBUG_DISPATCHER;
static FILE* debug_fp = NULL;
-#define DCOM echld_common_set_dbg(debug_lvl,debug_fp)
-#define DFL fflush(debug_fp)
+#define DCOM() echld_common_set_dbg(debug_lvl,debug_fp,"Disp")
int dispatcher_debug(int level, const char* fmt, ...) {
va_list ap;
}
debug_lvl = lvl;
- DCOM;
+ DCOM();
return TRUE;
}
static long dbg_r = 0;
#define DISP_DBG(attrs) ( dispatcher_debug attrs )
-#define DISP_DBG_INIT() do { debug_fp = stderr; DCOM; } while(0)
-#define DISP_DBG_START(fname) do { debug_fp = fopen(fname,"a"); DCOM; DISP_DBG((0,"Log Started")); } while(0)
+#define DISP_DBG_INIT() do { debug_fp = stderr; DCOM(); } while(0)
+#define DISP_DBG_START(fname) do { debug_fp = fopen(fname,"a"); DCOM(); DISP_DBG((0,"Log Started")); } while(0)
#define DISP_WRITE(FD,BA,CH,T,RH) ( dbg_r = echld_write_frame(FD,BA,CH,T,RH,NULL), DISP_DBG((1,"SND fd=%d ch=%d ty='%c' rh=%d msg='%s'",FD,CH,T,RH, (dbg_r>0?"ok":strerror(errno)))), dbg_r )
#else
#define DISP_DBG(attrs)
GList* if_list;
char* s;
*err = NULL;
- if_list = capture_interface_list(&err_no, err);
+
+ if_list = capture_interface_list(&err_no, err, NULL);
if (*err) {
return NULL;
c->closing = 0;
}
-static void preinit_epan(void) {
- DISP_DBG((2,"preinit_epan"));
+static void set_dumpcap_pid(int pid) {
+ dispatcher->dumpcap_pid = pid;
+}
+
+static void preinit_epan(char* argv0, int (*main)(int, char **)) {
+ char* init_progfile_dir_error = init_progfile_dir(argv0, main);
+
+
+ if (init_progfile_dir_error) {
+ DISP_FATAL((CANNOT_PREINIT_EPAN,"Failed epan_preinit: msg='%s'",init_progfile_dir_error));
+ }
+
+ capture_sync_set_fetch_dumpcap_pid_cb(set_dumpcap_pid);
+
/* Here we do initialization of parts of epan that will be the same for every child we fork */
+
+ DISP_DBG((2,"epan preinit"));
+
}
int max_children = dispatcher->max_children;
int pid = waitpid(-1, &status, WNOHANG);
GByteArray* em;
+ int reqh_id_save = dispatcher->reqh_id;
+
+ dispatcher->reqh_id = 0;
if (sig != SIGCHLD) {
DISP_DBG((1,"Reaper got wrong signal=%d",sig));
+ dispatcher->reqh_id = reqh_id_save;
return;
}
DISP_WRITE(dispatcher->parent_out, em, c->chld_id, ECHLD_CHILD_DEAD, 0);
dispatcher_clear_child(c);
g_byte_array_free(em,TRUE);
+ dispatcher->reqh_id = reqh_id_save;
return;
}
}
+ if (pid == dispatcher->dumpcap_pid) {
+ dispatcher->dumpcap_pid = 0;
+ dispatcher->reqh_id = reqh_id_save;
+ return;
+ }
+
dispatcher_err(ECHLD_ERR_UNKNOWN_PID, "Unkown child pid: %d", pid);
+ dispatcher->reqh_id = reqh_id_save;
+
}
if (chld_id == 0) { /* these are messages to the dispatcher itself */
- DISP_DBG((2,"Message to Dispatcher"));
+ DISP_DBG((2,"Parent => Dispatcher"));
switch(type) {
case ECHLD_CLOSE_CHILD:
dispatcher_destroy();
} else {
struct dispatcher_child* c;
- DISP_DBG((2,"Message to Child"));
+ DISP_DBG((2,"Parent => Child"));
if (! (c = dispatcher_get_child(dispatcher, chld_id)) ) {
dispatcher_err(ECHLD_ERR_NO_SUCH_CHILD, "wrong chld_id %d", chld_id);
}
-void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds) {
+void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, int (*main)(int, char **)) {
static struct dispatcher d;
#ifdef DEBUG_DISPATCHER
int dbg_fd;
d.nchildren = 0;
d.reqh_id = -1;
d.pid = getpid();
+ d.dumpcap_pid = 0;
close(out_pipe_fds[0]);
close(in_pipe_fds[1]);
DISP_DBG((2,"Dispatcher Configured pid=%d parent_in=%d parent_out=%d",d.pid,in_pipe_fds[0],d.parent_out));
- preinit_epan();
+ preinit_epan(argv0,main);
exit(dispatcher_loop());
}
-extern void echld_dispatcher_unused(void) {
- DISP_FATAL((1,"UNUSED"));
-}
+#include "capture_opts.h"
+#include "capture_session.h"
#include "capture_ifinfo.h"
+#include "capture_sync.h"
+#include "../epan/filesystem.h"
#include "echld.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* XXX these shouldn't be needed */
typedef struct _column_info column_info;
typedef struct _proto_node proto_tree;
#define READER_FD_ISSET(R,fdset_p) READER_FD_ISSET(R.fd,&(fdset_p))
#define READER_FD_CLEAR(R,fdset_p) READER_FD_CLEAR(R.fd,&(fdset_p))
-extern void echld_common_set_dbg(int level, FILE* fp);
+extern void echld_common_set_dbg(int level, FILE* fp, const char* prefix);
extern void echld_init_reader(echld_reader_t* r, int fd, size_t initial);
extern void echld_reset_reader(echld_reader_t* r, int fd, size_t initial);
echld_bool_t (*set_param) (guint8*, size_t, char** param, char** value);
echld_bool_t (*get_param) (guint8*, size_t, char** param);
echld_bool_t (*close_child) (guint8*, size_t, int* mode);
-
-
echld_bool_t (*open_file) (guint8*, size_t, char** filename);
echld_bool_t (*open_interface) (guint8*, size_t, char** intf_name, char** params);
echld_bool_t (*get_sum) (guint8*, size_t, char** range);
extern int echld_child_loop(void);
/* never returns*/
-extern void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds);
+extern void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, int (*main)(int, char **));
extern void dummy_switch(echld_msg_type_t type);
#define SHOULD_HAVE_EXITED_BEFORE 129
#define DISPATCHER_PIPE_FAILED 130
#define TERMINATED 140
+#define CANNOT_PREINIT_EPAN 141
+#ifndef DEBUG_BASE
+#define echld_common_set_dbg(a,b,c)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#endif
}
+struct _get_param {
+ const char* name;
+ echld_param_cb_t cb;
+ void* cb_data;
+ echld_bool_t (*dec)(enc_msg_t*, char**, char**);
+ echld_bool_t (*dec_err)(enc_msg_t*, int* , char**);
+ const char** err_msg;
+};
+
+#define CHNULL ((char*)NULL)
+
+static gboolean got_param(echld_msg_type_t type, GByteArray* ba _U_, void* data) {
+ struct _get_param* g = (struct _get_param*)data;
+ char* err_msg;
+
+ switch (type) {
+ case ECHLD_PARAM:
+ if (g->cb) {
+ char* param;
+ char* value;
+ g->dec(ba,¶m,&value);
+ g->cb(param,value,NULL,g->cb_data);
+
+ }
+ break;
+ case ECHLD_ERROR: {
+ int errnum;
+ g->dec_err(ba,&errnum,&err_msg);
+ g->cb(NULL,NULL,err_msg,g->cb_data);
+ break;
+ }
+ default:
+ err_msg = g_strdup_printf("other type='%c'",type);
+ g->cb(NULL,NULL,err_msg,g->cb_data);
+ g_free(err_msg);
+ break;
+ }
+
+ g_free(g);
+ return TRUE;
+}
+
+extern echld_state_t echld_get_param(int chld_id, const char* param, echld_param_cb_t acb, void* cb_data) {
+ struct _get_param* g = g_new0(struct _get_param,1);
+ echld_parent_encoder_t* enc;
+ parent_decoder_t* dec;
+ enc_msg_t* em;
+
+ echld_get_all_codecs(NULL, NULL, &enc, &dec);
+
+ em = enc->get_param(param);
+
+ g->name = param;
+ g->cb = acb;
+ g->cb_data = cb_data;
+ g->dec = dec->param;
+ g->dec_err = dec->error;
+
+ return echld_reqh(chld_id, ECHLD_GET_PARAM, 0, em, got_param, g);
+}
+
+extern echld_state_t echld_set_param(int chld_id, const char* param, const char* value, echld_param_cb_t acb, void* cb_data) {
+ struct _get_param* g = g_new0(struct _get_param,1);
+ echld_parent_encoder_t* enc;
+ parent_decoder_t* dec;
+ enc_msg_t* em;
+
+ echld_get_all_codecs(NULL, NULL, &enc, &dec);
+
+ em = enc->set_param(param,value);
+
+ g->name = param;
+ g->cb = acb;
+ g->cb_data = cb_data;
+ g->dec = dec->param;
+ g->dec_err = dec->error;
+
+ return echld_reqh(chld_id, ECHLD_SET_PARAM, 0, em, got_param, g);
+}
+
#ifndef __ECHLD_UTIL
#define __ECHLD_UTIL
+#ifdef __cplusplus
+extern "C" {
+#endif
typedef void (*echld_ping_cb_t)(long usec, void* data);
WS_DLL_PUBLIC 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);
-WS_DLL_PUBLIC echld_state_t echld_list_interfaces(int child_id, echld_list_interface_cb_t, void* cb_data);
+typedef void (*echld_param_cb_t)(const char* param, const char* value, const char* error, void* data);
+WS_DLL_PUBLIC echld_state_t echld_get_param(int chld_id, const char* param, echld_param_cb_t cb, void* cb_data);
+WS_DLL_PUBLIC echld_state_t echld_set_param(int chld_id, const char* param, const char* value, echld_param_cb_t acb, void* cb_data);
typedef void (*echild_get_packet_summary_cb_t)(char* summary, void* data);
WS_DLL_PUBLIC echld_state_t echld_open_file(int child_id, const char* filename,echild_get_packet_summary_cb_t,void*);
typedef void (*echild_get_buffer_cb)(char* buffer_text, void* data);
WS_DLL_PUBLIC echld_state_t echld_get_packets_range(int child_id, const char* range, echild_get_packets_cb, echild_get_buffer_cb, void* data);
+#ifdef __cplusplus
+};
+#endif
+
#endif
#ifndef __ECHLD_H
#define __ECHLD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "ws_symbol_export.h"
#define ECHLD_VERSION "0.0"
typedef struct timeval tv_t;
/* will initialize epan registering protocols and taps */
-WS_DLL_PUBLIC void echld_initialize(echld_encoding_t);
+WS_DLL_PUBLIC void echld_initialize(echld_encoding_t, char* argv0, int (*main)(int, char **));
/* cleans up (?) echld and kills the server process(es) */
WS_DLL_PUBLIC echld_state_t echld_terminate(void);
typedef struct _parent_out {
enc_msg_t* (*error)(int err, const char* text);
+ enc_msg_t* (*get_param)(const char* param);
enc_msg_t* (*set_param)(const char* param, const char* value);
enc_msg_t* (*close_child)(int mode);
enc_msg_t* (*open_file)(const char* filename);
ECHLD_ERR_OTHER
};
+#ifdef __cplusplus
+};
+#endif
#endif
extern void echld_set_parent_dbg_level(int lvl) {
(dbg_level = lvl);
if (lvl > 6) {
- echld_common_set_dbg(lvl,stderr);
+ echld_common_set_dbg(lvl,stderr,"parent");
}
PARENT_DBG((0,"Debug Level Set: %d",lvl));
}
}
/* will initialize epan registering protocols and taps */
-void echld_initialize(echld_encoding_t enc) {
+void echld_initialize(echld_encoding_t enc, char* argv0, int (*main)(int, char **)) {
int from_disp[2];
int to_disp[2];
#endif
/* child code */
echld_cleanup();
- echld_dispatcher_start(to_disp,from_disp);
+ echld_dispatcher_start(to_disp,from_disp,argv0,main);
PARENT_FATAL((SHOULD_HAVE_EXITED_BEFORE,"This shoudln't happen"));
} else {
/* parent code */
reader_realloc_buf = parent_realloc_buff;
#endif
- echld_common_set_dbg(9,stderr);
+ echld_common_set_dbg(9,stderr,"parent");
PARENT_DBG((3,"Dispatcher forked"));
}
}
+void param_cb(const char* param, const char* value, const char* error, void* data _U_) {
+ if (error) {
+ fprintf(stderr, "Param Set Error msg=%s\n", error );
+ return;
+ }
+
+ fprintf(stderr, "Param: param='%s' val='%s'\n", param, value );
+
+}
-int main(int argc, char** argv) {
+
+int main(int argc _U_, char** argv _U_) {
struct timeval tv;
int tot_cycles = 0;
- int max_cycles = 30;
- int npings;
+ int max_cycles = 20;
+ int npings = 2;
tv.tv_sec = 0;
tv.tv_usec = 250000;
echld_set_parent_dbg_level(5);
- switch(argc) {
- case 1:
- npings = 3;
- break;
- case 2:
- npings = (int)atoi(argv[1]);
- break;
- default:
- fprintf(stderr, "usage: %s [num pings, default=10]\n",argv[0]);
- return 1;
- }
+ echld_initialize(ECHLD_ENCODING_JSON,argv[0],main);
- max_cycles = npings*4;
+ do {
+ if ( (tot_cycles > 2) && npings > 0 && npings-- ) echld_ping(0,ping_cb,NULL);
- echld_initialize(ECHLD_ENCODING_JSON);
+ if ( tot_cycles == 10) echld_set_param(0,"dbg_level","5",param_cb,NULL);
+ if ( tot_cycles == 12) echld_get_param(0,"interfaces",param_cb,NULL);
- do {
- if ( (tot_cycles > npings) && npings && npings-- ) echld_ping(0,ping_cb,NULL);
tot_cycles++;
echld_wait(&tv);
} while( (pings < npings) || (tot_cycles < max_cycles));
}
+void main_window_update(void) {}