diff options
author | Tomasz Moń <desowin@gmail.com> | 2019-09-11 16:46:00 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-09-23 04:38:00 +0000 |
commit | e52f33f66c979ac493fa738005815bb01d5304a8 (patch) | |
tree | 32a87b0b934f176cd139f6131336713fe505c42a | |
parent | bd439c909045de71f3ab6907ff3f2e74682e7f3a (diff) |
extcap: Multiple extcap instance support on Windows
Wireshark does create named pipes and waits for the child process to
connect. The named pipe server handle is inheritable and thus available
in child dumpcap process. Pass the handle identifier instead of named
pipe name so dumpcap can use it.
Bug: 13653
Change-Id: Id2c019f67a63f1ea3d98b9da2153d6de5078cd01
Reviewed-on: https://code.wireshark.org/review/34503
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | capchild/capture_sync.c | 14 | ||||
-rw-r--r-- | dumpcap.c | 94 | ||||
-rw-r--r-- | extcap.c | 2 |
3 files changed, 60 insertions, 50 deletions
diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c index c46871d229..d2ed2ee75a 100644 --- a/capchild/capture_sync.c +++ b/capchild/capture_sync.c @@ -324,7 +324,15 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf argv = sync_pipe_add_arg(argv, &argc, "-i"); if (interface_opts->extcap_fifo != NULL) + { +#ifdef _WIN32 + char *pipe = g_strdup_printf("%s%" G_GUINTPTR_FORMAT, EXTCAP_PIPE_PREFIX, interface_opts->extcap_pipe_h); + argv = sync_pipe_add_arg(argv, &argc, pipe); + g_free(pipe); +#else argv = sync_pipe_add_arg(argv, &argc, interface_opts->extcap_fifo); +#endif + } else argv = sync_pipe_add_arg(argv, &argc, interface_opts->name); @@ -500,11 +508,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf #else si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; /* this hides the console window */ - if(interface_opts->extcap_pipe_h != INVALID_HANDLE_VALUE) - si.hStdInput = interface_opts->extcap_pipe_h; - else - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = sync_pipe_write; /*si.hStdError = (HANDLE) _get_osfhandle(2);*/ @@ -1561,7 +1561,7 @@ cap_pipe_open_live(char *pipename, struct sockaddr_un sa; #else /* _WIN32 */ char *pncopy, *pos; - char* extcap_pipe_name; + guintptr extcap_pipe_handle; #endif gboolean extcap_pipe = FALSE; ssize_t b; @@ -1682,57 +1682,63 @@ cap_pipe_open_live(char *pipename, } #else /* _WIN32 */ -#define PIPE_STR "\\pipe\\" - /* Under Windows, named pipes _must_ have the form - * "\\<server>\pipe\<pipename>". <server> may be "." for localhost. - */ - pncopy = g_strdup(pipename); - if ( (pos=strstr(pncopy, "\\\\")) == pncopy) { - pos = strchr(pncopy + 3, '\\'); - if (pos && g_ascii_strncasecmp(pos, PIPE_STR, strlen(PIPE_STR)) != 0) - pos = NULL; + if (sscanf(pipename, EXTCAP_PIPE_PREFIX "%" G_GUINTPTR_FORMAT, &extcap_pipe_handle) == 1) + { + /* The client is already connected to extcap pipe. + * We have inherited the handle from parent process. + */ + extcap_pipe = TRUE; + pcap_src->cap_pipe_h = (HANDLE)extcap_pipe_handle; } + else + { +#define PIPE_STR "\\pipe\\" + /* Under Windows, named pipes _must_ have the form + * "\\<server>\pipe\<pipename>". <server> may be "." for localhost. + */ + pncopy = g_strdup(pipename); + if ((pos = strstr(pncopy, "\\\\")) == pncopy) { + pos = strchr(pncopy + 3, '\\'); + if (pos && g_ascii_strncasecmp(pos, PIPE_STR, strlen(PIPE_STR)) != 0) + pos = NULL; + } - g_free(pncopy); + g_free(pncopy); - if (!pos) { - g_snprintf(errmsg, (gulong)errmsgl, - "The capture session could not be initiated because\n" - "\"%s\" is neither an interface nor a pipe.", pipename); - pcap_src->cap_pipe_err = PIPNEXIST; - return; - } - extcap_pipe_name = g_strconcat("\\\\.\\pipe\\", EXTCAP_PIPE_PREFIX, NULL); - extcap_pipe = strstr(pipename, extcap_pipe_name) ? TRUE : FALSE; - g_free(extcap_pipe_name); + if (!pos) { + g_snprintf(errmsg, (gulong)errmsgl, + "The capture session could not be initiated because\n" + "\"%s\" is neither an interface nor a pipe.", pipename); + pcap_src->cap_pipe_err = PIPNEXIST; + return; + } - /* Wait for the pipe to appear */ - while (1) { - if(extcap_pipe) - pcap_src->cap_pipe_h = GetStdHandle(STD_INPUT_HANDLE); - else + + /* Wait for the pipe to appear */ + while (1) { pcap_src->cap_pipe_h = CreateFile(utf_8to16(pipename), GENERIC_READ, 0, NULL, - OPEN_EXISTING, 0, NULL); + OPEN_EXISTING, 0, NULL); - if (pcap_src->cap_pipe_h != INVALID_HANDLE_VALUE) - break; + if (pcap_src->cap_pipe_h != INVALID_HANDLE_VALUE) + break; - if (GetLastError() != ERROR_PIPE_BUSY) { - g_snprintf(errmsg, (gulong)errmsgl, - "The capture session on \"%s\" could not be started " - "due to error on pipe open: %s.", - pipename, win32strerror(GetLastError())); - pcap_src->cap_pipe_err = PIPERR; - return; - } + if (GetLastError() != ERROR_PIPE_BUSY) { + g_snprintf(errmsg, (gulong)errmsgl, + "The capture session on \"%s\" could not be started " + "due to error on pipe open: %s.", + pipename, win32strerror(GetLastError())); + pcap_src->cap_pipe_err = PIPERR; + return; + } - if (!WaitNamedPipe(utf_8to16(pipename), 30 * 1000)) { - g_snprintf(errmsg, (gulong)errmsgl, - "The capture session on \"%s\" timed out during " - "pipe open: %s.", - pipename, win32strerror(GetLastError())); - pcap_src->cap_pipe_err = PIPERR; - return; + if (!WaitNamedPipe(utf_8to16(pipename), 30 * 1000)) { + g_snprintf(errmsg, (gulong)errmsgl, + "The capture session on \"%s\" timed out during " + "pipe open: %s.", + pipename, win32strerror(GetLastError())); + pcap_src->cap_pipe_err = PIPERR; + return; + } } } #endif /* _WIN32 */ @@ -1511,7 +1511,7 @@ static gboolean extcap_create_pipe(const gchar *ifname, gchar **fifo, HANDLE *ha } else { - g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "\nWireshark Created pipe =>(%s)", pipename); + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "\nWireshark Created pipe =>(%s) handle (%" G_GUINTPTR_FORMAT ")", pipename, *handle_out); *fifo = g_strdup(pipename); } |