"%s: EUID: %d Capabilities: %s", pfx,
geteuid(), cap_to_text(caps, NULL));
cap_free(caps);
+}
#else
print_caps(const char *pfx _U_) {
-#endif
}
+#endif
static void
relinquish_all_capabilities(void)
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
"Console: Control signal");
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
- "Console: Control signal, CtrlType: %u", dwCtrlType);
+ "Console: Control signal, CtrlType: %lu", dwCtrlType);
/* Keep capture running if we're a service and a user logs off */
if (capture_child || (dwCtrlType != CTRL_LOGOFF_EVENT)) {
#else /* _WIN32 */
size_t bytes_read;
#endif /* _WIN32 */
- ssize_t b;
pcap_src = (capture_src *)arg;
while (pcap_src->cap_pipe_err == PIPOK) {
#endif
)
{
+ ssize_t b;
b = cap_pipe_read(pcap_src->cap_pipe_fd, pcap_src->cap_pipe_buf+bytes_read,
pcap_src->cap_pipe_bytes_to_read - bytes_read, pcap_src->from_cap_socket);
if (b <= 0) {
/* If we try to use read() on a named pipe on Windows with partial
* data it appears to return EOF.
*/
+ DWORD b;
res = ReadFile(pcap_src->cap_pipe_h, pcap_src->cap_pipe_buf+bytes_read,
pcap_src->cap_pipe_bytes_to_read - bytes_read,
&b, NULL);
g_snprintf(errmsg, errmsgl,
"The capture session could not be initiated due to the socket error: \n"
#ifdef _WIN32
- " %d: %S", lastError, errorText ? (char *)errorText : "Unknown");
+ " %d: %s", lastError, errorText ? (char *)errorText : "Unknown");
if (errorText)
LocalFree(errorText);
#else
#endif /* _WIN32 */
ssize_t b;
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_read_data_bytes read %lu of %lu",
+ pcap_src->cap_pipe_bytes_read, pcap_src->cap_pipe_bytes_to_read);
+#endif
sz = pcap_src->cap_pipe_bytes_to_read - pcap_src->cap_pipe_bytes_read;
while (bytes_read < sz) {
if (fd == -1) {
sz-bytes_read, pcap_src->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_snprintf(errmsg, errmsgl, "End of file on pipe during cap_pipe_read.");
+ else {
+#ifdef _WIN32
+ LPTSTR errorText = NULL;
+ int lastError = WSAGetLastError();
+ errno = lastError;
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&errorText, 0, NULL);
+ g_snprintf(errmsg, errmsgl, "Error on pipe data during cap_pipe_read: "
+ " %d: %s", lastError, errorText ? (char *)errorText : "Unknown");
+ if (errorText)
+ LocalFree(errorText);
+#else
+ g_snprintf(errmsg, errmsgl, "Error on pipe data during cap_pipe_read: %s.",
g_strerror(errno));
+#endif
+ }
return -1;
}
bytes_read += b;
}
}
pcap_src->cap_pipe_bytes_read += bytes_read;
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_read_data_bytes read %lu of %lu",
+ pcap_src->cap_pipe_bytes_read, pcap_src->cap_pipe_bytes_to_read);
+#endif
return 0;
}
NULL, GetLastError(), 0, (LPTSTR) &err_str, 0, NULL);
g_snprintf(errmsg, errmsgl,
"The capture session on \"%s\" could not be started "
- "due to error on pipe open: %s (error %d).",
+ "due to error on pipe open: %s (error %lu).",
pipename, utf_16to8(err_str), GetLastError());
LocalFree(err_str);
pcap_src->cap_pipe_err = PIPERR;
NULL, GetLastError(), 0, (LPTSTR) &err_str, 0, NULL);
g_snprintf(errmsg, errmsgl,
"The capture session on \"%s\" timed out during "
- "pipe open: %s (error %d).",
+ "pipe open: %s (error %lu).",
pipename, utf_16to8(err_str), GetLastError());
LocalFree(err_str);
pcap_src->cap_pipe_err = PIPERR;
* large enough for most regular network packets. We increase it,
* up to the maximum size we allow, as necessary.
*/
- pcap_src->cap_pipe_databuf = (guchar*)g_malloc(2048);
+ pcap_src->cap_pipe_databuf = (char*)g_malloc(2048);
pcap_src->cap_pipe_databuf_size = 2048;
#ifdef _WIN32
g_strerror(errno));
return -1;
}
+ /* Continuing with STATE_EXPECT_DATA requires reading into cap_pipe_databuf at offset cap_pipe_bytes_read */
pcap_src->cap_pipe_bytes_read = sizeof(struct pcapng_block_header_s) + sizeof(struct pcapng_section_header_block_s);
}
#endif
switch (shb->magic)
{
case PCAPNG_MAGIC:
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng SHB MAGIC");
pcap_src->cap_pipe_byte_swapped = FALSE;
break;
case PCAPNG_SWAPPED_MAGIC:
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng SHB SWAPPED MAGIC");
pcap_src->cap_pipe_byte_swapped = TRUE;
break;
default:
pcap_src->cap_pipe_max_pkt_size = WTAP_MAX_PACKET_SIZE_STANDARD;
- /* Setup state to capture the rest of the section header block */
+ /* Setup state to capture any options following the section header block */
pcap_src->cap_pipe_state = STATE_EXPECT_DATA;
return 0;
guint32 type = BLOCK_TYPE_SHB;
struct pcapng_block_header_s *bh = &pcap_src->cap_pipe_info.pcapng.bh;
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng_pipe_open_live: fd %d", fd);
#ifdef _WIN32
if (pcap_src->from_cap_socket)
#endif
new_bufsize |= new_bufsize >> 8;
new_bufsize |= new_bufsize >> 16;
new_bufsize++;
- pcap_src->cap_pipe_databuf = (guchar*)g_realloc(pcap_src->cap_pipe_databuf, new_bufsize);
+ pcap_src->cap_pipe_databuf = (char*)g_realloc(pcap_src->cap_pipe_databuf, new_bufsize);
pcap_src->cap_pipe_databuf_size = new_bufsize;
}
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPTSTR) &err_str, 0, NULL);
g_snprintf(errmsg, errmsgl,
- "Error reading from pipe: %s (error %d)",
+ "Error reading from pipe: %s (error %lu)",
utf_16to8(err_str), GetLastError());
LocalFree(err_str);
#else
switch (pcap_src->cap_pipe_state) {
case STATE_EXPECT_REC_HDR:
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng_pipe_dispatch STATE_EXPECT_REC_HDR");
+#endif
#ifdef _WIN32
if (g_mutex_trylock(pcap_src->cap_pipe_read_mtx)) {
#endif
pcap_src->cap_pipe_bytes_read = 0;
#ifdef _WIN32
- pcap_src->cap_pipe_buf = pcap_src->cap_pipe_databuf;
- g_async_queue_push(pcap_src->cap_pipe_pending_q, pcap_src->cap_pipe_buf);
+ if (!pcap_src->from_cap_socket) {
+ pcap_src->cap_pipe_buf = pcap_src->cap_pipe_databuf;
+ g_async_queue_push(pcap_src->cap_pipe_pending_q, pcap_src->cap_pipe_buf);
+ }
g_mutex_unlock(pcap_src->cap_pipe_read_mtx);
}
#endif
/* Fall through */
case STATE_READ_REC_HDR:
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng_pipe_dispatch STATE_READ_REC_HDR");
+#endif
#ifdef _WIN32
- if (pcap_src->from_cap_socket)
+ if (pcap_src->from_cap_socket) {
#endif
- {
if (cap_pipe_read_data_bytes(pcap_src, errmsg, errmsgl)) {
return -1;
}
- }
#ifdef _WIN32
- else {
+ } else {
q_status = g_async_queue_timeout_pop(pcap_src->cap_pipe_done_q, PIPE_READ_TIMEOUT);
if (pcap_src->cap_pipe_err == PIPEOF) {
result = PD_PIPE_EOF;
break;
case STATE_EXPECT_DATA:
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng_pipe_dispatch STATE_EXPECT_DATA");
+#endif
#ifdef _WIN32
if (g_mutex_trylock(pcap_src->cap_pipe_read_mtx)) {
#endif
pcap_src->cap_pipe_state = STATE_READ_DATA;
pcap_src->cap_pipe_bytes_to_read = bh->block_total_length;
-
#ifdef _WIN32
- pcap_src->cap_pipe_bytes_to_read -= pcap_src->cap_pipe_bytes_read;
- pcap_src->cap_pipe_buf = pcap_src->cap_pipe_databuf + pcap_src->cap_pipe_bytes_read;
- g_async_queue_push(pcap_src->cap_pipe_pending_q, pcap_src->cap_pipe_buf);
+ if (!pcap_src->from_cap_socket) {
+ pcap_src->cap_pipe_bytes_to_read -= pcap_src->cap_pipe_bytes_read;
+ pcap_src->cap_pipe_buf = pcap_src->cap_pipe_databuf + pcap_src->cap_pipe_bytes_read;
+ pcap_src->cap_pipe_bytes_read = 0;
+ g_async_queue_push(pcap_src->cap_pipe_pending_q, pcap_src->cap_pipe_buf);
+ }
g_mutex_unlock(pcap_src->cap_pipe_read_mtx);
}
#endif
/* Fall through */
case STATE_READ_DATA:
+#ifdef LOG_CAPTURE_VERBOSE
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "pcapng_pipe_dispatch STATE_READ_DATA");
+#endif
#ifdef _WIN32
- if (pcap_src->from_cap_socket)
+ if (pcap_src->from_cap_socket) {
#endif
- {
if (cap_pipe_read_data_bytes(pcap_src, errmsg, errmsgl)) {
return -1;
}
- if (pcap_src->cap_pipe_bytes_read < pcap_src->cap_pipe_bytes_to_read)
- return 0;
- }
#ifdef _WIN32
- else {
+ } else {
q_status = g_async_queue_timeout_pop(pcap_src->cap_pipe_done_q, PIPE_READ_TIMEOUT);
if (pcap_src->cap_pipe_err == PIPEOF) {
if (!q_status) {
return 0;
}
- if (pcap_src->cap_pipe_bytes_read < pcap_src->cap_pipe_bytes_to_read) {
- return 0;
- }
- pcap_src->cap_pipe_bytes_read = bh->block_total_length;
}
#endif /* _WIN32 */
+ if (pcap_src->cap_pipe_bytes_read < pcap_src->cap_pipe_bytes_to_read) {
+ return 0;
+ }
result = PD_DATA_READ;
break;
case PD_DATA_READ:
if (!pcapng_block_save(pcap_src)) {
+ g_snprintf(errmsg, errmsgl, "pcapng_pipe_dispatch block save failed");
return -1;
}
if (use_threads) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, (LPTSTR) &err_str, 0, NULL);
g_snprintf(errmsg, errmsgl,
- "Error reading from pipe: %s (error %d)",
+ "Error reading from pipe: %s (error %lu)",
utf_16to8(err_str), GetLastError());
LocalFree(err_str);
#else
} else {
/* We couldn't open "iface" as a network device. */
/* Try to open it as a pipe */
+ gboolean pipe_err = FALSE;
cap_pipe_open_live(interface_opts->name, pcap_src, &pcap_src->cap_pipe_info.pcap.hdr, errmsg, (int) errmsg_len);
-#ifndef _WIN32
- if (pcap_src->cap_pipe_fd == -1) {
-#else
- if (pcap_src->cap_pipe_h == INVALID_HANDLE_VALUE) {
+#ifdef _WIN32
+ if (pcap_src->from_cap_socket) {
#endif
+ if (pcap_src->cap_pipe_fd == -1) {
+ pipe_err = TRUE;
+ }
+#ifdef _WIN32
+ } else {
+ if (pcap_src->cap_pipe_h == INVALID_HANDLE_VALUE) {
+ pipe_err = TRUE;
+ }
+ }
+#endif
+
+ if (pipe_err) {
if (pcap_src->cap_pipe_err == PIPNEXIST) {
/*
* We tried opening as an interface, and that failed,
capture_loop_dispatch(loop_data *ld,
char *errmsg, int errmsg_len, capture_src *pcap_src)
{
- int inpkts;
+ int inpkts = 0;
gint packet_count_before;
-#ifndef _WIN32
int sel_ret;
-#endif
packet_count_before = ld->packet_count;
if (pcap_src->from_cap_pipe) {
#ifdef LOG_CAPTURE_VERBOSE
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from capture pipe");
#endif
-#ifndef _WIN32
- sel_ret = cap_pipe_select(pcap_src->cap_pipe_fd);
- if (sel_ret <= 0) {
- if (sel_ret < 0 && errno != EINTR) {
- g_snprintf(errmsg, errmsg_len,
- "Unexpected error from select: %s", g_strerror(errno));
- report_capture_error(errmsg, please_report);
- ld->go = FALSE;
+#ifdef _WIN32
+ if (pcap_src->from_cap_socket) {
+#endif
+ sel_ret = cap_pipe_select(pcap_src->cap_pipe_fd);
+ if (sel_ret <= 0) {
+ if (sel_ret < 0 && errno != EINTR) {
+ g_snprintf(errmsg, errmsg_len,
+ "Unexpected error from select: %s", g_strerror(errno));
+ report_capture_error(errmsg, please_report);
+ ld->go = FALSE;
+ }
}
+#ifdef _WIN32
} else {
+ /* Windows does not have select() for pipes. */
+ /* Proceed with _dispatch() which waits for cap_pipe_done_q
+ * notification from cap_thread_read() when ReadFile() on
+ * the pipe has read enough bytes. */
+ sel_ret = 1;
+ }
+#endif
+ if (sel_ret > 0) {
/*
* "select()" says we can read from the pipe without blocking
*/
-#endif
inpkts = pcap_src->cap_pipe_dispatch(ld, pcap_src, errmsg, errmsg_len);
if (inpkts < 0) {
ld->go = FALSE;
}
-#ifndef _WIN32
}
-#endif
}
else
{
#ifdef _WIN32
cur_time = GetTickCount(); /* Note: wraps to 0 if sys runs for 49.7 days */
- if ((cur_time - upd_time) > DUMPCAP_UPD_TIME) { /* wrap just causes an extra update */
+ if ((cur_time - upd_time) > DUMPCAP_UPD_TIME) /* wrap just causes an extra update */
#else
gettimeofday(&cur_time, NULL);
if (((guint64)cur_time.tv_sec * 1000000 + cur_time.tv_usec) >
- ((guint64)upd_time.tv_sec * 1000000 + upd_time.tv_usec + DUMPCAP_UPD_TIME*1000)) {
+ ((guint64)upd_time.tv_sec * 1000000 + upd_time.tv_usec + DUMPCAP_UPD_TIME*1000))
#endif
+ {
upd_time = cur_time;
global_ld.go = FALSE;
global_ld.err = err;
pcap_src->dropped++;
- } else if (bh->block_type == BLOCK_TYPE_EPB || bh->block_type == BLOCK_TYPE_SPB) {
+ } else if (bh->block_type == BLOCK_TYPE_EPB || bh->block_type == BLOCK_TYPE_SPB || bh->block_type == BLOCK_TYPE_SYSTEMD_JOURNAL) {
/* count packet only if we actually have an EPB or SPB */
#if defined(DEBUG_DUMPCAP) || defined(DEBUG_CHILD_DUMPCAP)
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
"Wrote a packet of length %d captured on interface %u.",
- phdr->caplen, pcap_src->interface_id);
+ bh->block_total_length, pcap_src->interface_id);
#endif
global_ld.packet_count++;
pcap_src->received++;
int err;
guint ts_mul = pcap_src->ts_nsec ? 1000000000 : 1000000;
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_write_packet_cb");
+
/* We may be called multiple times from pcap_dispatch(); if we've set
the "stop capturing" flag, ignore this packet, as we're not
supposed to be saving any more packets. */
}
/* And now our feature presentation... [ fade to music ] */
-int
-main(int argc, char *argv[])
+static int
+real_main(int argc, char *argv[])
{
GString *comp_info_str;
GString *runtime_info_str;
g_string_free(runtime_info_str, TRUE);
#ifdef _WIN32
- arg_list_utf_16to8(argc, argv);
create_app_running_mutex();
/*
return 0; /* never here, make compiler happy */
}
+#ifdef _WIN32
+int
+wmain(int argc, wchar_t *wc_argv[])
+{
+ char **argv;
+
+ argv = arg_list_utf_16to8(argc, wc_argv);
+ return real_main(argc, argv);
+}
+#else
+int
+main(int argc, char *argv[])
+{
+ return real_main(argc, argv);
+}
+#endif
static void
console_log_handler(const char *log_domain, GLogLevelFlags log_level,
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO,
"Signal pipe: Stop capture: %s", sig_pipe_name);
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
- "Signal pipe: %s (%p) result: %u avail: %u", sig_pipe_name,
+ "Signal pipe: %s (%p) result: %u avail: %lu", sig_pipe_name,
sig_pipe_handle, result, avail);
return FALSE;
} else {