Wireshark-dev: [Wireshark-dev] [Patch] Re: capture from a fifo

From: Richard van der Hoff <richardv@xxxxxxxxxxxxx>
Date: Wed, 26 Jul 2006 14:22:57 +0100
Richard van der Hoff wrote:
[tshark from a fifo] Ulf - I notice you made the relevant change here (r16787) - is there any reason why tshark shouldn't use capture_loop_dispatch to do its processing, rather than attempting to use cap_pipe_dispatch or pcap_dispatch directly?

well, there didn't seem to be, so I've made a patch which does exactly this, and which fixes the problem.

I've even gone so far as to add a unit test for it :).

Please could this be applied?

--
Richard van der Hoff <richardv@xxxxxxxxxxxxx>
Telephony Gateways Project Manager
Tel: +44 (0) 845 666 7778
http://www.mxtelecom.com
Index: capture_loop.c
===================================================================
--- capture_loop.c	(revision 9793)
+++ capture_loop.c	(working copy)
@@ -323,7 +323,7 @@
 
 /* We read one record from the pipe, take care of byte order in the record
  * header, write the record to the capture file, and update capture statistics. */
-int
+static int
 cap_pipe_dispatch(loop_data *ld, guchar *data, char *errmsg, int errmsgl)
 {
   struct pcap_pkthdr phdr;
@@ -800,7 +800,7 @@
 }
 
 /* dispatch incoming packets (pcap or capture pipe) */
-static int
+int
 capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
 		      char *errmsg, int errmsg_len) {
   int       inpkts;
@@ -1465,10 +1465,10 @@
 void capture_loop_stop(void)
 {
 #ifdef HAVE_PCAP_BREAKLOOP
-  pcap_breakloop(ld.pcap_h);
-#else
+  if(ld.pcap_h != NULL)
+    pcap_breakloop(ld.pcap_h);
+#endif
   ld.go = FALSE;
-#endif
 }
  
 
Index: capture_loop.h
===================================================================
--- capture_loop.h	(revision 9793)
+++ capture_loop.h	(working copy)
@@ -159,12 +159,12 @@
 extern initfilter_status_t
 capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, const gchar * iface, gchar * cfilter);
 
-#ifdef HAVE_LIBPCAP
-#ifndef _WIN32
-extern int 
-cap_pipe_dispatch(loop_data *, guchar *, char *, int);
-#endif /* _WIN32 */
-#endif
+/** read a single record from the capture input, and dispatch it
+    returns the number of packets processed.
+*/
+extern int
+capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
+		      char *errmsg, int errmsg_len);
 
 extern gboolean 
 capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
Index: tshark.c
===================================================================
--- tshark.c	(revision 9793)
+++ tshark.c	(working copy)
@@ -1700,12 +1700,7 @@
          each packet. */
       pcap_cnt = 1;
     }
-#ifndef _WIN32
-    if (ld.from_cap_pipe) {
-      inpkts = cap_pipe_dispatch(&ld, pcap_data, errmsg, sizeof errmsg);
-    } else
-#endif
-      inpkts = pcap_dispatch(ld.pcap_h, pcap_cnt, ld.packet_cb, (u_char *) &ld);
+    inpkts=capture_loop_dispatch(pcap_data, &ld, errmsg, sizeof errmsg);
     if (inpkts < 0) {
       /* Error from "pcap_dispatch()", or error or "no more packets" from
          "cap_pipe_dispatch(). */
Index: test/suite-capture.sh
===================================================================
--- test/suite-capture.sh	(revision 9793)
+++ test/suite-capture.sh	(working copy)
@@ -93,6 +93,38 @@
 	fi
 }
 
+# capture packets via a fifo
+capture_step_fifo() {
+	mkfifo 'fifo'
+        (cat $CAPFILE; sleep 1; tail -c +25 $CAPFILE) > fifo &
+	$DUT -i fifo -w ./testout.pcap -a duration:$TRAFFIC_CAPTURE_DURATION > ./testout.txt 2>&1
+	RETURNVALUE=$?
+        rm 'fifo'
+	if [ ! $RETURNVALUE -eq $EXIT_OK ]; then
+		test_step_failed "exit status of $DUT: $RETURNVALUE"
+		return
+	fi
+
+	# we should have an output file now
+	if [ ! -f "./testout.pcap" ]; then
+		test_step_failed "No output file!"
+		return
+	fi
+	
+	# ok, we got a capture file, does it contain exactly 8 packets?
+	$CAPINFOS ./testout.pcap > ./testout.txt
+	grep -i 'Number of packets: 8' ./testout.txt > /dev/null
+	if [ $? -eq 0 ]; then
+		test_step_ok
+	else
+		echo
+		cat ./testout.txt
+		test_step_failed "No or not enough traffic captured."
+	fi
+}    
+
+
+
 # capture exactly 2 times 10 packets (multiple files)
 capture_step_2multi_10packets() {
 	$DUT -i $TRAFFIC_CAPTURE_IFACE -w ./testout.pcap -c 10  -a duration:$TRAFFIC_CAPTURE_DURATION > ./testout.txt 2>&1
@@ -202,6 +234,7 @@
 	test_step_add "Capture 10 packets using stdout: -w -" capture_step_10packets_stdout
 	test_step_add "Capture read filter (${TRAFFIC_CAPTURE_DURATION}s)" capture_step_read_filter
 	test_step_add "Capture snapshot length 68 bytes (${TRAFFIC_CAPTURE_DURATION}s)" capture_step_snapshot
+	test_step_add "Capture via fifo" capture_step_fifo
 }
 
 dumpcap_capture_suite() {