aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2019-09-11 16:46:00 +0200
committerAnders Broman <a.broman58@gmail.com>2019-09-23 04:38:00 +0000
commite52f33f66c979ac493fa738005815bb01d5304a8 (patch)
tree32a87b0b934f176cd139f6131336713fe505c42a
parentbd439c909045de71f3ab6907ff3f2e74682e7f3a (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.c14
-rw-r--r--dumpcap.c94
-rw-r--r--extcap.c2
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);*/
diff --git a/dumpcap.c b/dumpcap.c
index fa20b402b8..367a71ff8f 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -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 */
diff --git a/extcap.c b/extcap.c
index 623ba18945..0fbfac3d9b 100644
--- a/extcap.c
+++ b/extcap.c
@@ -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);
}