summaryrefslogtreecommitdiff
path: root/dumpcap.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-06-08 11:54:26 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-06-08 11:54:26 +0000
commit6a1f6be63b9b50bbcf0f0dfa243b4c8988e20c30 (patch)
tree7beb4ef379518d51e37d187034a77b5668c2a634 /dumpcap.c
parentae43364681b4df6e38eb0f29d5191afd3fc8d414 (diff)
downloadwireshark-6a1f6be63b9b50bbcf0f0dfa243b4c8988e20c30.tar.gz
From Alexey Neyman Forward ported by Michael Mann:
Allow captures over TCP connections. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2788 svn path=/trunk/; revision=43153
Diffstat (limited to 'dumpcap.c')
-rw-r--r--dumpcap.c420
1 files changed, 273 insertions, 147 deletions
diff --git a/dumpcap.c b/dumpcap.c
index 2db55e6f7c..bbdca84f6c 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -230,13 +230,13 @@ typedef struct _pcap_options {
gboolean ts_nsec; /* TRUE if we're using nanosecond precision. */
/* capture pipe (unix only "input file") */
gboolean from_cap_pipe; /* TRUE if we are capturing data from a capture pipe */
+ gboolean from_cap_socket; /* TRUE if we're capturing from socket */
struct pcap_hdr cap_pipe_hdr; /* Pcap header when capturing from a pipe */
struct pcaprec_modified_hdr cap_pipe_rechdr; /* Pcap record header when capturing from a pipe */
#ifdef _WIN32
HANDLE cap_pipe_h; /* The handle of the capture pipe */
-#else
- int cap_pipe_fd; /* the file descriptor of the capture pipe */
#endif
+ int cap_pipe_fd; /* the file descriptor of the capture pipe */
gboolean cap_pipe_modified; /* TRUE if data in the pipe uses modified pcap headers */
gboolean cap_pipe_byte_swapped; /* TRUE if data in the pipe is byte swapped */
#if defined(_WIN32)
@@ -1649,6 +1649,23 @@ cap_pipe_adjust_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcapr
}
}
+/* Wrapper: distinguish between recv/read if we're reading on Windows,
+ * or just read().
+ */
+static int
+cap_pipe_read(int pipe_fd, char *buf, size_t sz, gboolean from_socket _U_)
+{
+#ifdef _WIN32
+ if (from_socket) {
+ return recv(pipe_fd, buf, sz, 0);
+ } else {
+ return -1;
+ }
+#else
+ return ws_read(pipe_fd, buf, sz);
+#endif
+}
+
#if defined(_WIN32)
/*
* Thread function that reads from a pipe and pushes the data
@@ -1663,10 +1680,10 @@ cap_pipe_adjust_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcapr
* the queues themselves (yet).
*
* We might want to move some of the cap_pipe_dispatch logic here so that
- * we can let cap_pipe_read run independently, queuing up multiple reads
+ * we can let cap_thread_read run independently, queuing up multiple reads
* for the main thread (and possibly get rid of cap_pipe_read_mtx).
*/
-static void *cap_pipe_read(void *arg)
+static void *cap_thread_read(void *arg)
{
pcap_options *pcap_opts;
int bytes_read;
@@ -1683,48 +1700,57 @@ static void *cap_pipe_read(void *arg)
g_mutex_lock(pcap_opts->cap_pipe_read_mtx);
bytes_read = 0;
while (bytes_read < (int) pcap_opts->cap_pipe_bytes_to_read) {
+ if ((pcap_opts->from_cap_socket)
+#ifndef _WIN32
+ || 1
+#endif
+ )
+ {
+ b = cap_pipe_read(pcap_opts->cap_pipe_fd, pcap_opts->cap_pipe_buf+bytes_read,
+ pcap_opts->cap_pipe_bytes_to_read - bytes_read, pcap_opts->from_cap_socket);
+ if (b <= 0) {
+ if (b == 0) {
+ pcap_opts->cap_pipe_err = PIPEOF;
+ bytes_read = 0;
+ break;
+ } else {
+ pcap_opts->cap_pipe_err = PIPERR;
+ bytes_read = -1;
+ break;
+ }
+ } else {
+ bytes_read += b;
+ }
+ }
#ifdef _WIN32
- /* If we try to use read() on a named pipe on Windows with partial
- * data it appears to return EOF.
- */
- res = ReadFile(pcap_opts->cap_pipe_h, pcap_opts->cap_pipe_buf+bytes_read,
- pcap_opts->cap_pipe_bytes_to_read - bytes_read,
- &b, NULL);
-
- bytes_read += b;
- if (!res) {
- last_err = GetLastError();
- if (last_err == ERROR_MORE_DATA) {
- continue;
- } else if (last_err == ERROR_HANDLE_EOF || last_err == ERROR_BROKEN_PIPE || last_err == ERROR_PIPE_NOT_CONNECTED) {
- pcap_opts->cap_pipe_err = PIPEOF;
- bytes_read = 0;
- break;
- }
- pcap_opts->cap_pipe_err = PIPERR;
- bytes_read = -1;
- break;
- } else if (b == 0 && pcap_opts->cap_pipe_bytes_to_read > 0) {
- pcap_opts->cap_pipe_err = PIPEOF;
- bytes_read = 0;
- break;
- }
-#else /* _WIN32 */
- b = read(pcap_opts->cap_pipe_fd, pcap_opts->cap_pipe_buf+bytes_read,
- pcap_opts->cap_pipe_bytes_to_read - bytes_read);
- if (b <= 0) {
- if (b == 0) {
- pcap_opts->cap_pipe_err = PIPEOF;
- bytes_read = 0;
- break;
- } else {
- pcap_opts->cap_pipe_err = PIPERR;
- bytes_read = -1;
- break;
- }
- } else {
- bytes_read += b;
- }
+ else
+ {
+ /* If we try to use read() on a named pipe on Windows with partial
+ * data it appears to return EOF.
+ */
+ res = ReadFile(pcap_opts->cap_pipe_h, pcap_opts->cap_pipe_buf+bytes_read,
+ pcap_opts->cap_pipe_bytes_to_read - bytes_read,
+ &b, NULL);
+
+ bytes_read += b;
+ if (!res) {
+ last_err = GetLastError();
+ if (last_err == ERROR_MORE_DATA) {
+ continue;
+ } else if (last_err == ERROR_HANDLE_EOF || last_err == ERROR_BROKEN_PIPE || last_err == ERROR_PIPE_NOT_CONNECTED) {
+ pcap_opts->cap_pipe_err = PIPEOF;
+ bytes_read = 0;
+ break;
+ }
+ pcap_opts->cap_pipe_err = PIPERR;
+ bytes_read = -1;
+ break;
+ } else if (b == 0 && pcap_opts->cap_pipe_bytes_to_read > 0) {
+ pcap_opts->cap_pipe_err = PIPEOF;
+ bytes_read = 0;
+ break;
+ }
+ }
#endif /*_WIN32 */
}
pcap_opts->cap_pipe_bytes_read = bytes_read;
@@ -1737,7 +1763,6 @@ static void *cap_pipe_read(void *arg)
}
#endif
-#if !defined(_WIN32) || defined(MUST_DO_SELECT)
/* Provide select() functionality for a single file descriptor
* on UNIX/POSIX. Windows uses cap_pipe_read via a thread.
*
@@ -1757,8 +1782,86 @@ cap_pipe_select(int pipe_fd)
return select(pipe_fd+1, &rfds, NULL, NULL, &timeout);
}
+
+#define DEF_TCP_PORT 19000
+
+static int
+cap_open_socket(char *pipename, pcap_options *pcap_opts, char *errmsg, int errmsgl)
+{
+ char *sockname = pipename + 4;
+ struct sockaddr_in sa;
+ char buf[16];
+ char *p;
+ unsigned long port;
+ size_t len;
+ int fd;
+
+ memset(&sa, 0, sizeof(sa));
+
+ p = strchr(sockname, ':');
+ if (p == NULL) {
+ len = strlen(sockname);
+ port = DEF_TCP_PORT;
+ }
+ else {
+ len = p - sockname;
+ port = strtoul(p + 1, &p, 10);
+ if (*p || port > 65535) {
+ goto fail_invalid;
+ }
+ }
+
+ if (len > 15) {
+ goto fail_invalid;
+ }
+
+ strncpy(buf, sockname, len);
+ buf[len] = '\0';
+ if (!inet_pton(AF_INET, buf, &sa.sin_addr)) {
+ goto fail_invalid;
+ }
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons((u_short)port);
+
+ if (((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
+ (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)) {
+ g_snprintf(errmsg, errmsgl,
+ "The capture session could not be initiated due to\n"
+#ifdef _WIN32
+ "the socket error: %d", WSAGetLastError());
+#else
+ "the socket error: %s", strerror(errno));
#endif
+ pcap_opts->cap_pipe_err = PIPERR;
+ return -1;
+ }
+ pcap_opts->from_cap_socket = TRUE;
+ return fd;
+
+fail_invalid:
+ g_snprintf(errmsg, errmsgl,
+ "The capture session could not be initiated because\n"
+ "\"%s\" is not a valid socket specification", pipename);
+ pcap_opts->cap_pipe_err = PIPERR;
+ return -1;
+}
+
+/* Wrapper: distinguish between closesocket on Windows; use ws_close
+ * otherwise.
+ */
+static void
+cap_pipe_close(int pipe_fd, gboolean from_socket _U_)
+{
+#ifdef _WIN32
+ if (from_socket) {
+ closesocket(pipe_fd);
+ }
+#else
+ ws_close(pipe_fd);
+#endif
+}
/* Mimic pcap_open_live() for pipe captures
@@ -1776,23 +1879,16 @@ cap_pipe_open_live(char *pipename,
#ifndef _WIN32
ws_statb64 pipe_stat;
struct sockaddr_un sa;
- int b;
- int fd;
#else /* _WIN32 */
-#if 1
char *pncopy, *pos;
wchar_t *err_str;
#endif
-#endif
-#ifndef _WIN32
- int sel_ret;
+ int b, fd, sel_ret;
unsigned int bytes_read;
-#endif
guint32 magic = 0;
-#ifndef _WIN32
pcap_opts->cap_pipe_fd = -1;
-#else
+#ifdef _WIN32
pcap_opts->cap_pipe_h = INVALID_HANDLE_VALUE;
#endif
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_open_live: %s", pipename);
@@ -1807,6 +1903,10 @@ cap_pipe_open_live(char *pipename,
#else /* _WIN32 */
pcap_opts->cap_pipe_h = GetStdHandle(STD_INPUT_HANDLE);
#endif /* _WIN32 */
+ } else if (!strncmp(pipename, "TCP@", 4)) {
+ if ((fd = cap_open_socket(pipename, pcap_opts, errmsg, errmsgl)) < 0) {
+ return;
+ }
} else {
#ifndef _WIN32
if (ws_stat64(pipename, &pipe_stat) < 0) {
@@ -1955,46 +2055,53 @@ cap_pipe_open_live(char *pipename,
pcap_opts->from_cap_pipe = TRUE;
+ if ((pcap_opts->from_cap_socket)
#ifndef _WIN32
- /* read the pcap header */
- bytes_read = 0;
- while (bytes_read < sizeof magic) {
- sel_ret = cap_pipe_select(fd);
- if (sel_ret < 0) {
- g_snprintf(errmsg, errmsgl,
- "Unexpected error from select: %s", g_strerror(errno));
- goto error;
- } else if (sel_ret > 0) {
- b = read(fd, ((char *)&magic)+bytes_read, sizeof magic-bytes_read);
- if (b <= 0) {
- if (b == 0)
- g_snprintf(errmsg, errmsgl, "End of file on pipe magic during open");
- else
- g_snprintf(errmsg, errmsgl, "Error on pipe magic during open: %s",
- g_strerror(errno));
- goto error;
- }
- bytes_read += b;
- }
- }
-#else
- g_thread_create(&cap_pipe_read, pcap_opts, FALSE, NULL);
-
- pcap_opts->cap_pipe_buf = (char *) &magic;
- pcap_opts->cap_pipe_bytes_read = 0;
- pcap_opts->cap_pipe_bytes_to_read = sizeof(magic);
- /* We don't have to worry about cap_pipe_read_mtx here */
- g_async_queue_push(pcap_opts->cap_pipe_pending_q, pcap_opts->cap_pipe_buf);
- g_async_queue_pop(pcap_opts->cap_pipe_done_q);
- if (pcap_opts->cap_pipe_bytes_read <= 0) {
- if (pcap_opts->cap_pipe_bytes_read == 0)
- g_snprintf(errmsg, errmsgl, "End of file on pipe magic during open");
- else
- g_snprintf(errmsg, errmsgl, "Error on pipe magic during open: %s",
- g_strerror(errno));
- goto error;
+ || 1
+#endif
+ )
+ {
+ /* read the pcap header */
+ bytes_read = 0;
+ while (bytes_read < sizeof magic) {
+ sel_ret = cap_pipe_select(fd);
+ if (sel_ret < 0) {
+ g_snprintf(errmsg, errmsgl,
+ "Unexpected error from select: %s", g_strerror(errno));
+ goto error;
+ } else if (sel_ret > 0) {
+ b = cap_pipe_read(fd, ((char *)&magic)+bytes_read, sizeof magic-bytes_read, pcap_opts->from_cap_socket);
+ if (b <= 0) {
+ if (b == 0)
+ g_snprintf(errmsg, errmsgl, "End of file on pipe magic during open");
+ else
+ g_snprintf(errmsg, errmsgl, "Error on pipe magic during open: %s",
+ g_strerror(errno));
+ goto error;
+ }
+ bytes_read += b;
+ }
+ }
+ }
+#ifdef _WIN32
+ else {
+ g_thread_create(&cap_thread_read, pcap_opts, FALSE, NULL);
+
+ pcap_opts->cap_pipe_buf = (char *) &magic;
+ pcap_opts->cap_pipe_bytes_read = 0;
+ pcap_opts->cap_pipe_bytes_to_read = sizeof(magic);
+ /* We don't have to worry about cap_pipe_read_mtx here */
+ g_async_queue_push(pcap_opts->cap_pipe_pending_q, pcap_opts->cap_pipe_buf);
+ g_async_queue_pop(pcap_opts->cap_pipe_done_q);
+ if (pcap_opts->cap_pipe_bytes_read <= 0) {
+ if (pcap_opts->cap_pipe_bytes_read == 0)
+ g_snprintf(errmsg, errmsgl, "End of file on pipe magic during open");
+ else
+ g_snprintf(errmsg, errmsgl, "Error on pipe magic during open: %s",
+ g_strerror(errno));
+ goto error;
+ }
}
-
#endif
switch (magic) {
@@ -2034,42 +2141,50 @@ cap_pipe_open_live(char *pipename,
goto error;
}
+ if ((pcap_opts->from_cap_socket)
#ifndef _WIN32
- /* Read the rest of the header */
- bytes_read = 0;
- while (bytes_read < sizeof(struct pcap_hdr)) {
- sel_ret = cap_pipe_select(fd);
- if (sel_ret < 0) {
- g_snprintf(errmsg, errmsgl,
- "Unexpected error from select: %s", g_strerror(errno));
- goto error;
- } else if (sel_ret > 0) {
- b = read(fd, ((char *)hdr)+bytes_read,
- sizeof(struct pcap_hdr) - bytes_read);
- if (b <= 0) {
- if (b == 0)
- g_snprintf(errmsg, errmsgl, "End of file on pipe header during open");
- else
- g_snprintf(errmsg, errmsgl, "Error on pipe header during open: %s",
- g_strerror(errno));
- goto error;
- }
- bytes_read += b;
- }
+ || 1
+#endif
+ )
+ {
+ /* Read the rest of the header */
+ bytes_read = 0;
+ while (bytes_read < sizeof(struct pcap_hdr)) {
+ sel_ret = cap_pipe_select(fd);
+ if (sel_ret < 0) {
+ g_snprintf(errmsg, errmsgl,
+ "Unexpected error from select: %s", g_strerror(errno));
+ goto error;
+ } else if (sel_ret > 0) {
+ b = cap_pipe_read(fd, ((char *)hdr)+bytes_read,
+ sizeof(struct pcap_hdr) - bytes_read, pcap_opts->from_cap_socket);
+ if (b <= 0) {
+ if (b == 0)
+ g_snprintf(errmsg, errmsgl, "End of file on pipe header during open");
+ else
+ g_snprintf(errmsg, errmsgl, "Error on pipe header during open: %s",
+ g_strerror(errno));
+ goto error;
+ }
+ bytes_read += b;
+ }
+ }
}
-#else
- pcap_opts->cap_pipe_buf = (char *) hdr;
- pcap_opts->cap_pipe_bytes_read = 0;
- pcap_opts->cap_pipe_bytes_to_read = sizeof(struct pcap_hdr);
- g_async_queue_push(pcap_opts->cap_pipe_pending_q, pcap_opts->cap_pipe_buf);
- g_async_queue_pop(pcap_opts->cap_pipe_done_q);
- if (pcap_opts->cap_pipe_bytes_read <= 0) {
- if (pcap_opts->cap_pipe_bytes_read == 0)
- g_snprintf(errmsg, errmsgl, "End of file on pipe header during open");
- else
- g_snprintf(errmsg, errmsgl, "Error on pipe header header during open: %s",
- g_strerror(errno));
- goto error;
+#ifdef _WIN32
+ else {
+ pcap_opts->cap_pipe_buf = (char *) hdr;
+ pcap_opts->cap_pipe_bytes_read = 0;
+ pcap_opts->cap_pipe_bytes_to_read = sizeof(struct pcap_hdr);
+ g_async_queue_push(pcap_opts->cap_pipe_pending_q, pcap_opts->cap_pipe_buf);
+ g_async_queue_pop(pcap_opts->cap_pipe_done_q);
+ if (pcap_opts->cap_pipe_bytes_read <= 0) {
+ if (pcap_opts->cap_pipe_bytes_read == 0)
+ g_snprintf(errmsg, errmsgl, "End of file on pipe header during open");
+ else
+ g_snprintf(errmsg, errmsgl, "Error on pipe header header during open: %s",
+ g_strerror(errno));
+ goto error;
+ }
}
#endif
@@ -2089,18 +2204,14 @@ cap_pipe_open_live(char *pipename,
pcap_opts->cap_pipe_state = STATE_EXPECT_REC_HDR;
pcap_opts->cap_pipe_err = PIPOK;
-#ifndef _WIN32
pcap_opts->cap_pipe_fd = fd;
-#endif
return;
error:
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_open_live: error %s", errmsg);
pcap_opts->cap_pipe_err = PIPERR;
-#ifndef _WIN32
- ws_close(fd);
+ cap_pipe_close(fd, pcap_opts->from_cap_socket);
pcap_opts->cap_pipe_fd = -1;
-#endif
return;
}
@@ -2119,12 +2230,9 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
GTimeVal wait_time;
#endif
gpointer q_status;
-#else
- int b;
-#endif
-#ifdef _WIN32
wchar_t *err_str;
#endif
+ int b;
#ifdef LOG_CAPTURE_VERBOSE
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_dispatch");
@@ -2151,9 +2259,14 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
/* Fall through */
case STATE_READ_REC_HDR:
+ if ((pcap_opts->from_cap_socket)
#ifndef _WIN32
- b = read(pcap_opts->cap_pipe_fd, ((char *)&pcap_opts->cap_pipe_rechdr)+pcap_opts->cap_pipe_bytes_read,
- pcap_opts->cap_pipe_bytes_to_read - pcap_opts->cap_pipe_bytes_read);
+ || 1
+#endif
+ )
+ {
+ b = cap_pipe_read(pcap_opts->cap_pipe_fd, ((char *)&pcap_opts->cap_pipe_rechdr)+pcap_opts->cap_pipe_bytes_read,
+ pcap_opts->cap_pipe_bytes_to_read - pcap_opts->cap_pipe_bytes_read, pcap_opts->from_cap_socket);
if (b <= 0) {
if (b == 0)
result = PD_PIPE_EOF;
@@ -2162,7 +2275,10 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
break;
}
pcap_opts->cap_pipe_bytes_read += b;
-#else
+ }
+#ifdef _WIN32
+ else
+ {
#if GLIB_CHECK_VERSION(2,31,18)
q_status = g_async_queue_timeout_pop(pcap_opts->cap_pipe_done_q, PIPE_READ_TIMEOUT);
#else
@@ -2180,6 +2296,7 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
if (!q_status) {
return 0;
}
+ }
#endif
if ((pcap_opts->cap_pipe_bytes_read) < pcap_opts->cap_pipe_bytes_to_read)
return 0;
@@ -2204,9 +2321,14 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
/* Fall through */
case STATE_READ_DATA:
+ if ((pcap_opts->from_cap_socket)
#ifndef _WIN32
- b = read(pcap_opts->cap_pipe_fd, data+pcap_opts->cap_pipe_bytes_read,
- pcap_opts->cap_pipe_bytes_to_read - pcap_opts->cap_pipe_bytes_read);
+ || 1
+#endif
+ )
+ {
+ b = cap_pipe_read(pcap_opts->cap_pipe_fd, data+pcap_opts->cap_pipe_bytes_read,
+ pcap_opts->cap_pipe_bytes_to_read - pcap_opts->cap_pipe_bytes_read, pcap_opts->from_cap_socket);
if (b <= 0) {
if (b == 0)
result = PD_PIPE_EOF;
@@ -2215,7 +2337,11 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
break;
}
pcap_opts->cap_pipe_bytes_read += b;
-#else
+ }
+#ifdef _WIN32
+ else
+ {
+
#if GLIB_CHECK_VERSION(2,31,18)
q_status = g_async_queue_timeout_pop(pcap_opts->cap_pipe_done_q, PIPE_READ_TIMEOUT);
#else
@@ -2233,6 +2359,7 @@ cap_pipe_dispatch(loop_data *ld, pcap_options *pcap_opts, guchar *data, char *er
if (!q_status) {
return 0;
}
+ }
#endif
if ((pcap_opts->cap_pipe_bytes_read) < pcap_opts->cap_pipe_bytes_to_read)
return 0;
@@ -2402,13 +2529,13 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
pcap_opts->linktype = -1;
pcap_opts->ts_nsec = FALSE;
pcap_opts->from_cap_pipe = FALSE;
+ pcap_opts->from_cap_socket = FALSE;
memset(&pcap_opts->cap_pipe_hdr, 0, sizeof(struct pcap_hdr));
memset(&pcap_opts->cap_pipe_rechdr, 0, sizeof(struct pcaprec_modified_hdr));
#ifdef _WIN32
pcap_opts->cap_pipe_h = INVALID_HANDLE_VALUE;
-#else
- pcap_opts->cap_pipe_fd = -1;
#endif
+ pcap_opts->cap_pipe_fd = -1;
pcap_opts->cap_pipe_modified = FALSE;
pcap_opts->cap_pipe_byte_swapped = FALSE;
#ifdef _WIN32
@@ -2566,13 +2693,12 @@ static void capture_loop_close_input(loop_data *ld)
for (i = 0; i < ld->pcaps->len; i++) {
pcap_opts = g_array_index(ld->pcaps, pcap_options *, i);
/* if open, close the capture pipe "input file" */
-#ifndef _WIN32
if (pcap_opts->cap_pipe_fd >= 0) {
g_assert(pcap_opts->from_cap_pipe);
- ws_close(pcap_opts->cap_pipe_fd);
+ cap_pipe_close(pcap_opts->cap_pipe_fd, pcap_opts->from_cap_socket);
pcap_opts->cap_pipe_fd = -1;
}
-#else
+#ifdef _WIN32
if (pcap_opts->cap_pipe_h != INVALID_HANDLE_VALUE) {
CloseHandle(pcap_opts->cap_pipe_h);
pcap_opts->cap_pipe_h = INVALID_HANDLE_VALUE;