kerberos dissect KERBEROS_AD_GSS_API_ETYPE_NEGOTIATION content
[metze/wireshark/wip.git] / dumpcap.c
index 0dd2d5d0227278965a8f0b2e36f4ccc61ee1dc48..1991e9d0a2b7ad7a1f2502f192bf78cc8c171317 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -1982,6 +1982,7 @@ pcapng_read_shb(capture_src *pcap_src,
                            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
@@ -2012,7 +2013,7 @@ pcapng_read_shb(capture_src *pcap_src,
 
     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;
@@ -2391,8 +2392,10 @@ pcapng_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int err
             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
@@ -2440,9 +2443,12 @@ pcapng_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int err
             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
@@ -2458,8 +2464,6 @@ pcapng_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int err
             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 {
 
@@ -2474,12 +2478,11 @@ pcapng_pipe_dispatch(loop_data *ld, capture_src *pcap_src, char *errmsg, int err
             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;
 
@@ -2743,13 +2746,24 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
         } 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,
@@ -3081,11 +3095,9 @@ static int
 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) {
@@ -3093,27 +3105,36 @@ capture_loop_dispatch(loop_data *ld,
 #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
     {
@@ -4482,8 +4503,8 @@ get_dumpcap_runtime_info(GString *str)
 }
 
 /* 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;
@@ -4544,7 +4565,6 @@ main(int argc, char *argv[])
     g_string_free(runtime_info_str, TRUE);
 
 #ifdef _WIN32
-    arg_list_utf_16to8(argc, argv);
     create_app_running_mutex();
 
     /*
@@ -5251,6 +5271,22 @@ main(int argc, char *argv[])
     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,